How to repeat UVs per face on a plane that can be accessed in fragment shader?

tl;dr How can I add UV’s to a ShaderMaterial that repeat per face?

I’ve been banging my head around this all day and I know it must be something really simple (stupid) but I just can’t see it :frowning_face:

I made a custom buffer geometry that is just a flat plane (code taken roughly from the built-in PlaneGeometry) but modified it so it is flat on the Z-axis. I also add some custom attributes to allow a texture per face (through a sampler2DArray). This all works wonderfully (see screenshot):

I know which corners should be faded through an attribute. The technique I’m trying to mimick is described here: opengl - How can I render a textured quad so that I fade different corners? - Stack Overflow

The problem I have is that my UV-coordinates stretch around the entire plane, instead of going from 0 to 1 per face (or index?). The textures render perfectly, but I need to figure out where the face starts and ends based on UV coordinates.

I have 2 sets of UV’s on my plane.

uvs.push(ix, 1 - iz);
uvs2.push(ix * gridX, 1 - (iz * gridZ));

This is uvs rendered as a texture (this is the one that is used to render the diffuse textures - this works (although the UV looks strange - the edge colors are at the very top):

This is uvs2 rendered as a texture:

So what I’m after is uvs2 repeated 100x100 times so that I can access the current position by simply grabbing a fract of the UV. (e.g.: float x = fract(vUv.x); // 0-1)

To clarify:

If I do this:

gl_FragColor = vec4(color.rgb, color.a * (1.0 - vUv2.x));

I expect the result to be that each tile on the plane fades out from left to right. Instead the entire plane is fading.

Hi!
If you want it to be tiled 10x10, then do something like that: https://jsfiddle.net/prisoner849/sct6ekw5/

vec2 uv2 = fract(vUv * 10.);
diffuseColor.a = 1. - (uv2.x * uv2.y);
1 Like

Oh my god… See, it was something silly :joy:

Thank you very much!! :smiley:

You’re welcome :handshake: :beers:

If you want different tiling, say 5 x 6, then simply do
vec2 uv2 = fract(vUv * vec2(5., 6.));

1 Like