If I recall correctly, fragcoord
is the position of the fragment/pixel in world space, so that is probably what you will need if you want the texture to tile in world space instead of local space.
Though if you do not mind that the UV maps are modified, you can work around the issue by shifting the UV by the world position of the vertex. I had to reference the Triplanar Godot shader, but with the vertex modifications it should look like this:
shader_type spatial;
render_mode world_vertex_coords;
vec4 hash4(vec2 p){
return fract ( sin(vec4( 1.0+dot(p,vec2(37.0,17.0)), 2.0+dot(p,vec2(11.0,47.0)), 3.0+dot(p,vec2(41.0,29.0)), 4.0+dot(p,vec2(23.0,31.0)) ) ) *103.0);
}
vec4 textureNoTile (sampler2D samp, vec2 uv)
{
vec2 iuv = floor(uv);
vec2 fuv = fract(uv);
vec4 ofa = hash4( iuv + vec2(0,0) );
vec4 ofb = hash4( iuv + vec2(0,0) );
vec4 ofc = hash4( iuv + vec2(0,0) );
vec4 ofd = hash4( iuv + vec2(0,0) );
vec2 ddx = dFdx(uv);
vec2 ddy = dFdy(uv);
ofa.zw = sign(ofa.zw -0.5 );
ofb.zw = sign(ofb.zw -0.5 );
ofc.zw = sign(ofc.zw -0.5 );
ofd.zw = sign(ofd.zw -0.5 );
vec2 uva = uv*ofa.zw + ofa.xy, ddxa = ddx*ofa.zw, ddya = ddy*ofa.zw;
vec2 uvb = uv*ofb.zw + ofb.xy, ddxb = ddx*ofb.zw, ddyb = ddy*ofb.zw;
vec2 uvc = uv*ofc.zw + ofc.xy, ddxc = ddx*ofc.zw, ddyc = ddy*ofc.zw;
vec2 uvd = uv*ofd.zw + ofd.xy, ddxd = ddx*ofd.zw, ddyd = ddy*ofd.zw;
vec2 b = smoothstep (0.25, 0.75, fuv);
return mix(mix (textureGrad(samp, uva, ddxa, ddya), textureGrad(samp, uvb, ddxb, ddyb), b.x), mix(textureGrad( samp, uvc, ddxc, ddyc ), textureGrad( samp, uvd, ddxd, ddyd ), b.x), b.y);
}
uniform sampler2D grass_tex;
uniform vec4 col_mult: hint_color;
void vertex()
{
UV += (VERTEX).xy * NORMAL.z;
UV += (VERTEX).xz * NORMAL.y;
UV += (VERTEX).zy * vec2(-1.0, 1.0) * NORMAL.x;
}
void fragment() {
vec4 texture_modified = textureNoTile(grass_tex, vec2(UV.x *3.0, UV.y * 3.0));
//vec3 col = col_mult.rgb * texture_modified.rgb;
ALBEDO = texture_modified.rgb;
}
The tiling doesn't seem to totally work with the cube I was using for testing though.