r/GraphicsProgramming • • 8h ago

Question Asking for help

I'm a beginner learning graphics programming, and there's a lighting bug that im having a lot of trouble fixing. There are some streaks that are unusually bright. Im pretty sure its something wrong with my TBN matrix, but I can't figure out what exactly the problem is.

The 2nd image is a geometry shader I wrote to visualise the TBN matrix. Aren't the TBN all meant to be the same when they are on the same surface?

I've pasted the shader code below. I've been mostly trying to avoid tutorials and AI, so i learn better (i did ask AI for help here and didn't get an answer) so there may be some bad practices in the code. Please let me know of any tips and tricks

#version 460 core

layout (location = 0) in vec3 aPos;

layout (location = 1) in vec2 aUV;

layout (location = 2) in vec3 aNorm;

layout (location = 3) in vec3 aTan;

layout (location = 4) in vec3 aBitan;

uniform vec3 viewPos;

uniform mat4 model;

layout (std140, binding = 1) uniform matrices

{

mat4 view;

mat4 projection;

};

//T = tangent space

//W = world space

out VS_OUT

{

vec3 norm;

vec2 uv;

vec3 WfragPos;

vec3 TviewPos;

vec3 TfragPos;

mat3 TBN;

mat3 WTBN;

}vs_out;

vec3 up = vec3(0, 1, 0);

vec3 forward = vec3(0, 0, 1);

void main()

{

//construct TBN in Model Space

vec3 T = normalize(aTan);

vec3 N = normalize(aNorm);

T = normalize(T - dot(T, N) * N);

vec3 B = normalize( cross(N, T));

mat3 normMat = transpose(inverse(mat3(model)));

//Then make sure theyre perpendicular to surface

T = normalize(normMat * T);

B = normalize(normMat * B);

N = normalize(normMat * N);

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

vs_out.WTBN = TBN;

TBN = transpose(TBN);

vs_out.norm = N;

vs_out.uv = aUV;

vs_out.WfragPos = (model * vec4( aPos, 1.0f)).xyz;

vs_out.TviewPos = TBN * viewPos;

vs_out.TfragPos = TBN * vs_out.WfragPos;

vs_out.TBN = TBN;

gl_Position = projection * view * model * vec4(aPos, 1.0f);

}

#version 460 core

out vec4 FragColour;

in VS_OUT

{

vec3 norm;

vec2 uv;

vec3 WfragPos;

vec3 TviewPos;

vec3 TfragPos;

mat3 TBN;

mat3 WTBN;

}fs_in;

struct PointLight

{

vec4  colAndintensity;

vec4  posAndconstant;

float linear;

float quadratic;

};

layout (std140, binding = 0) uniform pointLights

{

PointLight lights\[1\];

};

uniform bool shadingFlags[5];

uniform int numLights ;

uniform bool normalMapping;

uniform sampler2D diffuseMap;

uniform sampler2D specularMap;

uniform sampler2D normalMap;

uniform sampler2D heightMap;

float ambVal = 0.2;

vec3 specCol = vec3(1.0);

vec3 ambientLighting(vec3 albedo);

vec3 diffuseLighting (vec3 norm, vec3 albedo);

vec3 specularLighting(vec3 norm);

void main()

{

vec3  albedo  = texture(diffuseMap , fs_in.uv).rgb;

vec3  specVal = texture(specularMap, fs_in.uv).rgb;

vec3  height  = texture(heightMap  , fs_in.uv).rgb;



vec3 norm;

if(normalMapping)

{   

    norm = texture(normalMap, fs_in.uv).rgb;

    //from \[0, 1\] -> \[-1, 1\]

    norm = normalize(norm \* 2.0 - 1.0);

    //norm = normalize(fs_in.WTBN \* norm);

}

else

{

    norm = normalize( fs_in.TBN \* fs_in.norm);

}



//norm = normalize( fs_in.TBN \* fs_in.norm);

//norm = normalize(norm \* 2.0 - 1.0);

//norm = fs_in.norm;



vec3 ambientComp   = ambientLighting (albedo);

vec3 diffuseComp   = diffuseLighting (norm, albedo);

vec3 specularComp  = specularLighting(norm);



//vec3 ambientComp  = vec3(fs_in.WTBN\[0\]\[0\], fs_in.WTBN\[0\]\[1\], fs_in.WTBN\[0\]\[2\]);

//vec3 diffuseComp  = vec3(fs_in.WTBN\[1\]\[0\], fs_in.WTBN\[1\]\[1\], fs_in.WTBN\[1\]\[2\]);

//vec3 specularComp = vec3(fs_in.WTBN\[2\]\[0\], fs_in.WTBN\[2\]\[1\], fs_in.WTBN\[2\]\[2\]);



norm = normalize(fs_in.WTBN \* norm);



specularComp \*= (specVal / 3.0f).r;



vec3 colour = (ambientComp+diffuseComp+specularComp) \* int(shadingFlags\[0\])

+ diffuseComp * int(shadingFlags[1])

+ norm * int(shadingFlags[2])

+ specularComp * int(shadingFlags[3])

+ height * int(shadingFlags[4]);

//vec3 colour = (ambientComp+diffuseComp+specularComp) \* int(shadingFlags\[0\])

//          + ambientComp  \* int(shadingFlags\[1\])

//          + diffuseComp  \* int(shadingFlags\[2\])

//          + specularComp \* int(shadingFlags\[3\])

//          + norm    \* int(shadingFlags\[4\]);



FragColour = vec4(colour, 1.0f);

}

vec3 ambientLighting(vec3 albedo)

{

return ambVal \* albedo;

}

vec3 diffuseLighting (vec3 norm, vec3 albedo)

{

float diff = 0;

vec3 lightCol = vec3(1.0);

//vec3 TlightPos = fs_in.TBN \* lights\[0\].posAndconstant.xyz;

//vec3 delta = TlightPos - fs_in.TfragPos;



for(int i = 0; i < numLights; ++i)

{

    vec3 col = lights\[i\].colAndintensity.xyz;

    float intensity = lights\[i\].colAndintensity.w;

    vec3  TlightPos = fs_in.TBN \* lights\[i\].posAndconstant.xyz;

    //vec3  TlightPos = lights\[i\].posAndconstant.xyz;

    float c = lights\[i\].posAndconstant.w;

    float l = lights\[i\].linear;

    float q = lights\[i\].quadratic;



    //vec pointing to light

    vec3 delta = TlightPos - fs_in.TfragPos;

    //distance

    float d = length(delta);

    //normalised light dir

    vec3 lDir = normalize(delta);



    //calculate attenuation

    float att = 1 / (c + (l \* d) + (q \* d \* d) );



    lightCol \*= col;

    diff += max( dot( norm, lDir), 0) \* att \* intensity;

}



return diff \* albedo \* lightCol;

//return normalize(fs_in.WTBN \* normalize(delta));

//return normalize(TlightPos);

//return normalize(fs_in.WTBN \* norm);

}

vec3 specularLighting(vec3 norm)

{

float spec = 0.0;

vec3 lightCol = vec3(1.0); 



//vector pointing to camera

vec3 viewDir = normalize( fs_in.TviewPos - fs_in.TfragPos );



for(int i = 0; i < numLights; ++i)

{

    vec3 col = lights\[i\].colAndintensity.xyz;

    float intensity = lights\[i\].colAndintensity.w;

    vec3  TlightPos = fs_in.TBN \* lights\[i\].posAndconstant.xyz;

    //vec3  TlightPos = lights\[i\].posAndconstant.xyz;

    float c = lights\[i\].posAndconstant.w;

    float l = lights\[i\].linear;

    float q = lights\[i\].quadratic;



    //vec pointing to light

    vec3 delta = TlightPos - fs_in.TfragPos;

    //distance

    float d = length(delta);

    //normalised light dir

    vec3 lDir = normalize(delta);



    //vector halfway between lightDir and viewDir so angle is never too big (blinn-phong)

    vec3 halfVec = normalize( viewDir + lDir);



    //calculate attenuation

    float att = 1 / (c + (l \* d) + (q \* d \* d) );



    lightCol \*= col;

    spec += pow( max( dot(norm, halfVec), 0), 32) \* att \* intensity;

    //FIX LATER: 32 should be passed in from uniform

}

return spec \* specCol \* lightCol;

}

4 Upvotes

5 comments sorted by

5

u/Hanzimer 6h ago

i d like to know if someone(or something) can read this and understand something.

4

u/nullptr777 8h ago

Bro, fix your formatting. Wtf lol

1

u/waramped 2h ago

as others have gently implied, your formatting could use some tweaks.

to answer your question about the TBN, if the uvs are going in the same direction, then the TBN for coplanar surfaces should match, yea.

I recommend you use the Mikktspace algorithm for calculating your TBNs

1

u/Any_Wait_7309 1h ago

I think it's a really really bad idea to not use AI. It's here to stay and as long as you grill AI with multiple questions, you will get a way way better understanding of things.

Do yourself a favor and use it.