Texture coordinates projection

I have some classic texture coordinates and as a normal behaviour they follow the mesh's transformations.

I am trying to use the same texture coordinates behaviour but without being affected by the mesh rotation transformation. The results would be a sort of texture coordinates projection.

I don't know if my explanations are well explained but how could I achieve such effect.

Thanks a lot.

• Could you explain further the end result. Are you after decal projection? A picture of the expected result would help. Commented Oct 31, 2016 at 10:16
• This is still for eye rendering :) post updated.
– MaT
Commented Oct 31, 2016 at 10:47
• @MaT based on the images i don't think a normal map is enough , you also need a height map. you need to compute the direction vector on the uv space and then offset it based on surface "depth" Commented Oct 31, 2016 at 12:35
• My question seems to be really badly formulated :P The Normal screenshot shows the eyes without any rotation therefore the occlusion map is well applied but as soon as you rotate the eye, the occlusion classical behaviour breaks the effect. That's why I am trying apply the occlusion map not only in object space to avoid the effect of the eye rotation, but I don't see how.
– MaT
Commented Oct 31, 2016 at 12:40

A static occlusion map won't generally work accurately with a dynamic mesh, as you can see. In your case you can separate the occlusion map and instead put it on a static object that wraps around the eye. You can render that object with multiplicative blending and get the effect you want.

GLSL has built-in fragment shader inputs, and one of them is gl_FragCoord. You can get the $x$ and $y$ value from this and use that as the lookup coordinate of the texture map in a sequence of two passes, but that could be a good or bad thing depending on the application (such as caching the result). This would both be rotation invariant while allowing you to scale and move the mesh.

First Pass

Transform the mesh without rotation. Bind a texture to the fragment shader and write the interpolated UV coordinates to it.

Second Pass

Transform the mesh correctly this time. Bind the texture from the last pass and read from it this time. You preserved the old UV coordinates, and now you can use these to look up whatever texture you have before. Obviously, this works best with a mesh that's a sphere (such as an eye).

vec2 texCoords = gl_FragCoord.xy; // do some sort of scaling
vec2 oldTexCoords = texture(samplerOfUVTexture, texCoords); // sample UV


Now you have both the old UV coordinates and the new UV coordinates. You can use the new UV coordinates for you diffuse map and the old UV coordinates for the occlusion map.

• How would that work? gl_FragCoord are the screen UVs. If the mesh occupies part of the screen it's not going to be textured correctly from these. Commented Oct 31, 2016 at 9:07
• @aces Yes I agree, I don't really get how this could work.
– MaT
Commented Oct 31, 2016 at 9:48
• @Syntac_ The picture makes the intent clearer, but it certainly can be textured correctly with this if you save the rendering of the pre-rotated mesh onto a texture and used screenspace coordinates to look it up. See my edit for a more detailed explanation.
– aces
Commented Nov 1, 2016 at 2:58

I think that I got a solution but I would gladly know if there are some optimizations possible.

My UVs and local coordinates values are corresponding. I mean that they are in the same range value. That said, I can use my XY vertices values for sampling the occlusion texture. The main problem is that the local coordinates are dependent to the rotation of my object which doesn't solve anything...

To solve that I am converting my local coordinates into world space using a objectToWorld matrix (inverse of current world matrix).
Then I am converting it back into object space using the inverse TRS matrix but without taking into account the rotation of the object.

It's a bit hacky and I think that I could avoid some steps but this is working.
Any advice is welcome :)