Hello jmonkeys,
I am currently trying to implement parallax mapping in my voxelshader, however I cannot seem to get it working.
since I already have normal maps implemented and working I guess there is no problem with the TBN matrix I got in the shaders, but to sum it up (and since there might still be a bug in there that I just dont notice with the directional light / normal map thing mentioned further down)
when meshing, instead of putting normal, tangent and bitangent into vertexbuffers, I put a single byte indicating which direction this face is facing. like 0 for faces facing direction negative x, 1 for faces facing direction positive x and so on.
first assumption I made is that in the vertex shader when I see this byte is a “0” I can just define the TBN matrix like so:
if (inNormal < 0.5) {
t = vec3(0.0,0.0,1.0);
b = vec3(0.0,1.0,0.0);
n = vec3(-1.0,0.0,0.0);
} else if (inNormal < 1.5 //... same theory for 5 other faces
//could later be replaced with fancy chains of step() calls to get the desired result
}
TBN = transpose(mat3(t, b, n));
to get a matrix that transforms worldspace to tangent space, completly independant on the order of the vertices. so if I had a quad
2--3
| |
0--1
I could define the triangles as 0, 1, 3 and 3, 2, 0 as well as 1, 3, 2 and 2, 0, 1 and the TBN matrix should still work, right?
second assumption is that as long as my model is neither scaled not rotated, direction vectors in worldSpace and modelSpace are the same, is that correct?
that would mean the TBN matrix I create can also transform direction vectors from modelspace to tangent space
so now onto the actual parallax thing:
in the vertex shader, after calculating the TBN matrix I want to calculate viewPos and lightDirection (thats the direction the sun shines into) in tangent space so I multiply them with the TBN matrix I just created
tangentViewPos = TBN * g_CameraPosition;
tangentLightDirection = normalize(TBN * m_SunDirection);
and since I read somewhere that interpolating linearly in tangent space might mess things up I also send the fragments position to the fragment shader but in worldspace:
worldFragPos = vec3(g_WorldMatrix * vec4(inPosition, 1.0));
then in the fragment shader I want to get the fragments position in tangentspace so I can calculate the viewDirection in tangentspace:
vec3 tangentFragPos = TBN * worldFragPos;
vec3 tangentViewDir = normalize(tangentViewPos - tangentFragPos);
vec3 finalTexCoord = parallaxMapping(texCoord, tangentViewDir);
with parallaxMapping defined as:
vec3 parallaxMapping(vec3 texCoords, vec3 viewDir) {
const float height_scale = 0.8;
float height = (1.0 - texture(m_ParallaxArray, texCoords).r) * height_scale;
return vec3(texCoords.xy - (viewDir.xy / viewDir.z * height), texCoords.z);
}
I followed LearnOpenGL - Parallax Mapping so I guess the parallaxMapping(…) function should be working and thats also why I’m doing it all in tangent space, but trying to fix my problem I had a look into lighting.vert, lightig.frag and the instancing.glslib and it seems they are doing it all in viewspace, is there any advantage in one over the other?
And to explain what the above code results in:
the textures definitely move and they also do it somewhat smoothly and move faster when looking from a lower angle (ofc they only move when moving the cam), but for some faces the texture moves with the camera (like when I’m facing a block and I move the cam to the left the texture moves to the left, too) and for other faces the texture moves into the opposite direction, however none of these cases look like working parallax, more like a scrolling background in 2D games
As mentioned, the diffuse light component I get by dotting tangentLightDirection with the normal that I get by multiplying the TBN with the values from a normalMap, looks like its working.
Although I have to say it definitely works when I assume the normal I lookup in the normal map is (0,0,1) and then continue with multiplying it with the TBN and dotting with the tangentLightDirection.
However, when I read the normal from the normalMap and continue with this value (mult with TBN, dot with tangentLightDirection), some faces seem to have the normals inverted in that it looks like the face is lit from the right side while actually the sun is on the left side.
these normalmaps were created with an online tool NormalMap-Online
and when checking the color values in gimp they give me something around 128, 128, 255 for areas that should be flat, so thats what I would expect
Does it make any sence? Can anyone help me out?
Thanks in advance and once more greetings from the shire,
Samwise