Home Game Development c++ – Help with calculating tangent/binormal in Vulkan fragment shader using GLSL

c++ – Help with calculating tangent/binormal in Vulkan fragment shader using GLSL

0
c++ – Help with calculating tangent/binormal in Vulkan fragment shader using GLSL

[ad_1]

I need help understanding what am I doing wrong with transformation/calculation of tangents and binormals using GLSL. I’m using Willems’ PBR demo shaders as a reference: https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/pbr.vert
https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/pbr_khr.frag

I start by programmatically generating a sphere with normals and texture coordinates as seen in this image:
enter image description here

The “light” is directly to the left (-10, 0, 0) and both texture coordinates and normals seem to be proper as per smooth gradient and appropriately wrapped texture

However the moment I try to add binormal and tangent into the equation using the “getNormals” code from fragment shader above – it all gets messed up, lit from improper direction, not evenly and blocky:
enter image description here

I tried to RenderDoc that PBR demo and the only big difference I see thus far is that he uses right handed system (Z is going backwards) whereas I’m using left-handed system (Z is forward) through GLM – but I’m not sure if that’s what ruins calculations?

Do note that I’m using identity matrices so the only transformation that sphere encounters is projection*view as vertex main output and identity as “world position” (worldPos) output because there are no world-level transformations happening to vertices themselves.

I then feed this worldPos together with texCoord and normal into getNormals() using the following code:

vec3 Q1 = dFdx(worldPos);
vec3 Q2 = dFdy(worldPos);
vec2 st1 = dFdx(texCoord);
vec2 st2 = dFdy(texCoord);

vec3 N = normalize(normal);
vec3 T = normalize(Q1 * st2.t - Q2 * st1.t);
vec3 B = -normalize(cross(N, T));

mat3 TBN = mat3(T, B, N);

return normalize(TBN * normal); // transform normal

and get that issue. Setting T and B to vec3(0.0) both returns the smooth shading back and the result is equal to just passing normal as return.

does it have anything to do with the coordinate system I’m using?
E.g. X is right, Y is up, Z is forward, U is right, V is down?

any ideas or tips?

[ad_2]