1

Been following questions like this one (Calculating normals for a height map) to calculate the normals across a noisy terrain. Because I'm doing a planet, I figured I could multiply by the TBN matrix (using tangent, bitangent and normal from original mesh, before displacement) to calculate this accurately. The results are... wrong. Here is my tessalation evaluation shader code:

vec2 pointCoord = outputVertex.textureCoord;

//Use the original TBN matrix to calculate this properly
float heightL = getNoiseAtPoint(pointCoord + vec2(-delta, 0));
float heightR = getNoiseAtPoint(pointCoord + vec2(delta, 0));
float heightU = getNoiseAtPoint(pointCoord + vec2( 0, delta));
float heightD = getNoiseAtPoint(pointCoord + vec2( 0, -delta));

vec3 tangentNormal = normalize(vec3(heightL - heightR, 2.0f, heightU - heightD));

vec3 T = normalize(interpolate3D(inputVertex[0].tangent, inputVertex[1].tangent, inputVertex[2].tangent));
vec3 B = normalize(interpolate3D(inputVertex[0].bitangent, inputVertex[1].bitangent, inputVertex[2].bitangent));

mat3 TBN = mat3(T, normalize(vecToOrigin),  B);

vec3 worldNormal = normalize( TBN * tangentNormal);

outputVertex.normal = worldNormal;

vec3 debugColour;
debugColour.x = ((2.0 * worldNormal.x) - 1.0);
debugColour.y = ((2.0 * worldNormal.y) - 1.0);
debugColour.z = ((2.0 * worldNormal.z) - 1.0);

outputVertex.debugTexture = debugColour;

I've been struggling with this for a while now, and getting consistently wrong results. Here is what I'm seeing:

Something's up here

And here's the worldNormals visualized as rgb:

enter image description here

Same two pictures, but this time from the perspective of the light. Strikes me there's a lot of blue (z) across the whole sphere...

enter image description here enter image description here

Anyone got any ideas? I'm fairly sure my original tangents and bitangents are correct as if I remove displacement I can do regular normal mapping just fine Thanks

EDIT: correct debug colours being in wrong range, uploaded the corresponding photos etc

EDIT 2 - vertex shader-

void calculateTBN()
{
    vec4 tan = tangent / tangent.w;
    vec3 T = normalize(vec3(transform * tan));

    vec4 bitan = bitangent / bitangent.w;
    vec3 B = normalize(vec3(transform * bitan));


    vec3 N = normalize(vec3(normalMat * vec4(normal, 0.0).xyz));

    TBN = mat3(T, B, N);

    outputVertex.TBN = TBN;

    outputVertex.tangent = T;
    outputVertex.bitangent = B;
}

void main(void) {
    //Calculate transform matrix
    transform = T * R * S;

    //Calculate pos
    pos = vec4(position.x, position.y, position.z, 1.0) + posRelParent;

    //Pass through the texture coords
    outputVertex.textureCoord = textureCoord;

    //Transform matrix dealt with
    pos = transform * pos;

    //Output vertex pos
    outputVertex.vert = pos.xyz;

    //Work out the normal for lighting
    normalMat = transpose(inverse(mat3(transform)));
    outputVertex.normal = normalize(normalMat * normal);

    calculateTBN();

    gl_Position = pos;
}
Figwig
  • 592
  • 1
  • 3
  • 16
  • `outputVertex.normal` is in world space, so the color depends on the point of view. The coordinates of the vector are in range [-1.0, 1.0]. How do you convert the vector to the RGB color channels in range [0.0, 1.0]? Note, if you just assign the vector to the color and if x and y < 0.0, then red and green are 0 and the color depends on the z coordinate wich is assigned to the blue component. – Rabbid76 Sep 16 '19 at 14:54
  • So all the vectors are in viewspace. Skip the transformation – Rabbid76 Sep 16 '19 at 15:45
  • Skip what transform sorry? My TBN matrix vectors are certainly all in viewspace, but the new normal from the calculation will be in tangent space until I multiply it by the TBN matrix, surely? – Figwig Sep 16 '19 at 15:47
  • No, it is in viewspace, because the entire tbn matrix is "in viewspace"! – Rabbid76 Sep 16 '19 at 15:50
  • Prior to being multiplied by the TBN matrix, `worldNormal` is literally generated by a perlin noise image, with up being z and x and y being calculated by the gradients. The perlin noise image doesn't account for the curvature of the sphere. It therefore surely can't be in viewSpace, unless I've grossly misunderstood what that means – Figwig Sep 16 '19 at 15:59
  • `pointCoord` is a texture coord between (0,0) and (1,1) – Figwig Sep 16 '19 at 16:00
  • The matrix depnds on the vectors. If the vectors are different then the matrix is different, too and does somthig diffetent – Rabbid76 Sep 16 '19 at 16:01
  • Okay understood, the TBN matrix is indeed in viewspace. My point was that `worldNormal` remains in tangent space if I "Skip the transform" as you suggested – Figwig Sep 16 '19 at 16:05

0 Answers0