Geometry shader steals lighting?

Hi All,

I have my base shader which does mesh rendering

But if I add geometry shader between vertex/fragment shaders, the lighthing gets off, I thought I am able to add wireframe on top of my base shader.

#shader vertex
#version 430 core

layout (location = 0) in vec3 geo_Pos;
layout (location = 1) in vec2 geo_TexCoords;
layout (location = 2) in vec3 geo_Normal;
layout (location = 3) in vec3 geo_Tangent;
layout (location = 4) in vec3 geo_Bitangent;

/* Global information sent by the engine */
layout (std140) uniform EngineUBO {
    mat4    ubo_Model;
    mat4    ubo_View;
    mat4    ubo_Projection;
    vec3    ubo_ViewPos;
    float   ubo_Time;
};

/* Information passed to the fragment shader */
out VS_OUT {
    vec3        FragPos;
    vec3        Normal;
    vec2        TexCoords;
    mat3        TBN;
    flat vec3   TangentViewPos;
    vec3        TangentFragPos;
} vs_out;

out vec3 VPosition;

void main() {
    vs_out.TBN = mat3 (
        normalize(vec3(ubo_Model * vec4(geo_Tangent,   0.0))),
        normalize(vec3(ubo_Model * vec4(geo_Bitangent, 0.0))),
        normalize(vec3(ubo_Model * vec4(geo_Normal,    0.0)))
    );

    mat3 TBNi = transpose(vs_out.TBN);

    vs_out.FragPos          = vec3(ubo_Model * vec4(geo_Pos, 1.0));
    vs_out.Normal           = normalize(mat3(transpose(inverse(ubo_Model))) * geo_Normal);
    vs_out.TexCoords        = geo_TexCoords;
    vs_out.TangentViewPos   = TBNi * ubo_ViewPos;
    vs_out.TangentFragPos   = TBNi * vs_out.FragPos;

	VPosition = vec3(ubo_Model * vec4(geo_Pos, 1.0));
	
	gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0);
}

#shader geometry
#version 430 core

#extension GL_EXT_geometry_shader : enable

uniform float LineThickness = 1.0;
out vec3 distance;

layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

void main() {
	float lineTiickness = (10.0 - LineThickness) * 100.0;
	
	if (LineThickness <= 1.0)
		lineTiickness = 900.0;
		
	if (LineThickness >= 9.0)
		lineTiickness = 100.0;
	
	vec2 p0 = lineTiickness * gl_PositionIn[0].xy / gl_PositionIn[0].w;
	vec2 p1 = lineTiickness * gl_PositionIn[1].xy / gl_PositionIn[1].w;
	vec2 p2 = lineTiickness * gl_PositionIn[2].xy / gl_PositionIn[2].w;
	
	vec2 v0 = p2 - p1;
	vec2 v1 = p2 - p0;
	vec2 v2 = p1 - p0;
	
	float area = abs(v1.x * v2.y - v1.y * v2.x);
	
	distance = vec3(area / length(v0), 0, 0);
	gl_Position = gl_PositionIn[0];
	EmitVertex();
	
	distance = vec3(0, area / length(v1), 0);
	gl_Position = gl_PositionIn[1];
	EmitVertex();
	
	distance = vec3(0, 0, area / length(v2));
	gl_Position = gl_PositionIn[2];
	EmitVertex();
	
	EndPrimitive();
}

#shader fragment
#version 430 core

/* Global information sent by the engine */
layout (std140) uniform EngineUBO {
    mat4    ubo_Model;
    mat4    ubo_View;
    mat4    ubo_Projection;
    vec3    ubo_ViewPos;
    float   ubo_Time;
};

/* Information passed from the fragment shader */
in VS_OUT {
    vec3        FragPos;
    vec3        Normal;
    vec2        TexCoords;
    mat3        TBN;
    flat vec3   TangentViewPos;
    vec3        TangentFragPos;
} fs_in;

/* Light information sent by the engine */
layout(std430, binding = 0) buffer LightSSBO {
    mat4 ssbo_Lights[];
};

/* Uniforms (Tweakable from the material editor) */
uniform vec2        u_TextureTiling           = vec2(1.0, 1.0);
uniform vec2        u_TextureOffset           = vec2(0.0, 0.0);
uniform vec4        u_Diffuse                 = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec3        u_Specular                = vec3(1.0, 1.0, 1.0);
uniform float       u_Shininess               = 100.0;
uniform float       u_HeightScale             = 0.0;
uniform bool        u_EnableNormalMapping     = false;
uniform sampler2D   u_DiffuseMap;
uniform sampler2D   u_SpecularMap;
uniform sampler2D   u_NormalMap;
uniform sampler2D   u_HeightMap;
uniform sampler2D   u_MaskMap;
uniform vec4		u_LineColor				  = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4		u_MeshColor				  = vec4(0.7, 0.7, 0.7, 1.0);

/* Global variables */
vec3 g_Normal;
vec2 g_TexCoords;
vec3 g_ViewDir;
vec4 g_DiffuseTexel;
vec4 g_SpecularTexel;
vec4 g_HeightTexel;
vec4 g_NormalTexel;

vec3 UnPack(float p_Target) {
    return vec3 (
        float((uint(p_Target) >> 24) & 0xff)    * 0.003921568627451,
        float((uint(p_Target) >> 16) & 0xff)    * 0.003921568627451,
        float((uint(p_Target) >> 8)  & 0xff)    * 0.003921568627451
    );
}

bool PointInAABB(vec3 p_Point, vec3 p_AabbCenter, vec3 p_AabbHalfSize) {
    return (
        p_Point.x > p_AabbCenter.x - p_AabbHalfSize.x && p_Point.x < p_AabbCenter.x + p_AabbHalfSize.x &&
        p_Point.y > p_AabbCenter.y - p_AabbHalfSize.y && p_Point.y < p_AabbCenter.y + p_AabbHalfSize.y &&
        p_Point.z > p_AabbCenter.z - p_AabbHalfSize.z && p_Point.z < p_AabbCenter.z + p_AabbHalfSize.z
    );
}

vec2 ParallaxMapping(vec3 p_ViewDir) {
    const vec2 parallax = p_ViewDir.xy * u_HeightScale * texture(u_HeightMap, g_TexCoords).r;
    return g_TexCoords - vec2(parallax.x, 1.0 - parallax.y);
}

vec3 BlinnPhong(vec3 p_LightDir, vec3 p_LightColor, float p_Luminosity) {
    const vec3  halfwayDir          = normalize(p_LightDir + g_ViewDir);
    const float diffuseCoefficient  = max(dot(g_Normal, p_LightDir), 0.0);
    const float specularCoefficient = pow(max(dot(g_Normal, halfwayDir), 0.0), u_Shininess * 2.0);

    return p_LightColor * g_DiffuseTexel.rgb * diffuseCoefficient * p_Luminosity + ((p_Luminosity > 0.0) ? (p_LightColor * g_SpecularTexel.rgb * specularCoefficient * p_Luminosity) : vec3(0.0));
}

float LuminosityFromAttenuation(mat4 p_Light) {
    const vec3  lightPosition   = p_Light[0].rgb;
    const float constant        = p_Light[0][3];
    const float linear          = p_Light[1][3];
    const float quadratic       = p_Light[2][3];

    const float distanceToLight = length(lightPosition - fs_in.FragPos);
    const float attenuation     = (constant + linear * distanceToLight + quadratic * (distanceToLight * distanceToLight));
    return 1.0 / attenuation;
}

vec3 CalcPointLight(mat4 p_Light) {
    /* Extract light information from light mat4 */
    const vec3 lightPosition    = p_Light[0].rgb;
    const vec3 lightColor       = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];

    const vec3  lightDirection  = normalize(lightPosition - fs_in.FragPos);
    const float luminosity      = LuminosityFromAttenuation(p_Light);

    return BlinnPhong(lightDirection, lightColor, intensity * luminosity);
}

vec3 CalcDirectionalLight(mat4 light) {
    return BlinnPhong(-light[1].rgb, UnPack(light[2][0]), light[3][3]);
}

vec3 CalcSpotLight(mat4 p_Light) {
    /* Extract light information from light mat4 */
    const vec3  lightPosition   = p_Light[0].rgb;
    const vec3  lightForward    = p_Light[1].rgb;
    const vec3  lightColor      = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];
    const float cutOff          = cos(radians(p_Light[3][1]));
    const float outerCutOff     = cos(radians(p_Light[3][1] + p_Light[3][2]));

    const vec3  lightDirection  = normalize(lightPosition - fs_in.FragPos);
    const float luminosity      = LuminosityFromAttenuation(p_Light);

    /* Calculate the spot intensity */
    const float theta           = dot(lightDirection, normalize(-lightForward)); 
    const float epsilon         = cutOff - outerCutOff;
    const float spotIntensity   = clamp((theta - outerCutOff) / epsilon, 0.0, 1.0);
    
    return BlinnPhong(lightDirection, lightColor, intensity * spotIntensity * luminosity);
}

vec3 CalcAmbientBoxLight(mat4 p_Light) {
    const vec3  lightPosition   = p_Light[0].rgb;
    const vec3  lightColor      = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];
    const vec3  size            = vec3(p_Light[0][3], p_Light[1][3], p_Light[2][3]);

    return PointInAABB(fs_in.FragPos, lightPosition, size) ? g_DiffuseTexel.rgb * lightColor * intensity : vec3(0.0);
}

vec3 CalcAmbientSphereLight(mat4 p_Light) {
    const vec3  lightPosition   = p_Light[0].rgb;
    const vec3  lightColor      = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];
    const float radius          = p_Light[0][3];

    return distance(lightPosition, fs_in.FragPos) <= radius ? g_DiffuseTexel.rgb * lightColor * intensity : vec3(0.0);
}

in vec3 distance;
out vec4 FragColor;

void main() {
    g_TexCoords = u_TextureOffset + vec2(mod(fs_in.TexCoords.x * u_TextureTiling.x, 1), mod(fs_in.TexCoords.y * u_TextureTiling.y, 1));

    /* Apply parallax mapping */
    if (u_HeightScale > 0)
        g_TexCoords = ParallaxMapping(normalize(fs_in.TangentViewPos - fs_in.TangentFragPos));

    /* Apply color mask */
    if (texture(u_MaskMap, g_TexCoords).r != 0.0) {
        g_ViewDir           = normalize(ubo_ViewPos - fs_in.FragPos);
        g_DiffuseTexel      = texture(u_DiffuseMap,  g_TexCoords) * u_Diffuse;
        g_SpecularTexel     = texture(u_SpecularMap, g_TexCoords) * vec4(u_Specular, 1.0);

        if (u_EnableNormalMapping) {
            g_Normal = texture(u_NormalMap, g_TexCoords).rgb;
            g_Normal = normalize(g_Normal * 2.0 - 1.0);   
            g_Normal = normalize(fs_in.TBN * g_Normal);
        }

        else {
            g_Normal = normalize(fs_in.Normal);
        }

        vec3 lightSum = vec3(0.0);

        for (int i = 0; i < ssbo_Lights.length(); ++i) {
            switch(int(ssbo_Lights[i][3][0])) {
                case 0: lightSum += CalcPointLight(ssbo_Lights[i]);         break;
                case 1: lightSum += CalcDirectionalLight(ssbo_Lights[i]);   break;
                case 2: lightSum += CalcSpotLight(ssbo_Lights[i]);          break;
                case 3: lightSum += CalcAmbientBoxLight(ssbo_Lights[i]);    break;
                case 4: lightSum += CalcAmbientSphereLight(ssbo_Lights[i]); break;
            }
        }
		
		FragColor = vec4(lightSum, g_DiffuseTexel.a);
    }

    else {
        FragColor = vec4(0.0);
    }
	
	float d = min(distance.x, min(distance.y, distance.z));
	float I = exp2(-2 * d * d);
	
	FragColor = FragColor + I * u_LineColor + (1.0 - I) * u_MeshColor;
}

Is there anything I missed?

Thanks

I believe your geometry shader needs to pass through the varyings (interpolators) from your vertex shader to your fragment shader.

https://www.khronos.org/opengl/wiki/Geometry_Shader#Inputs

HI @Dark_Photon Can you please give me more hint? :slight_smile:

Your problem is there: this statement is incorrect.

Output variables go to the next shader stage. Because you used a GS, the “next shader stage” is the geometry shader. Which does nothing with those values. Hence the fragment shader never sees them (and I’m surprised you didn’t get a link error).

And as previously stated, please use geometry shader functionality correctly. If you’re using gl_PositionIn, you’re relying on an outdated extension, not proper GS functionality.

Sorry I wasn’t good at Geometey Shader.

#shader vertex
#version 430 core

layout (location = 0) in vec3 geo_Pos;
layout (location = 1) in vec2 geo_TexCoords;
layout (location = 2) in vec3 geo_Normal;
layout (location = 3) in vec3 geo_Tangent;
layout (location = 4) in vec3 geo_Bitangent;

/* Global information sent by the engine */
layout (std140) uniform EngineUBO {
    mat4    ubo_Model;
    mat4    ubo_View;
    mat4    ubo_Projection;
    vec3    ubo_ViewPos;
    float   ubo_Time;
};

/* Information passed to the geometry shader */
out DATA {
    vec3        FragPos;
    vec3        Normal;
    vec2        TexCoords;
    mat3        TBN;
    flat vec3   TangentViewPos;
    vec3        TangentFragPos;
    vec4        glPosition;
    vec3        distance;
} vs_out;

void main() {
    vs_out.TBN = mat3 (
        normalize(vec3(ubo_Model * vec4(geo_Tangent,   0.0))),
        normalize(vec3(ubo_Model * vec4(geo_Bitangent, 0.0))),
        normalize(vec3(ubo_Model * vec4(geo_Normal,    0.0)))
    );

    mat3 TBNi = transpose(vs_out.TBN);

    vs_out.FragPos          = vec3(ubo_Model * vec4(geo_Pos, 1.0));
    vs_out.Normal           = normalize(mat3(transpose(inverse(ubo_Model))) * geo_Normal);
    vs_out.TexCoords        = geo_TexCoords;
    vs_out.TangentViewPos   = TBNi * ubo_ViewPos;
    vs_out.TangentFragPos   = TBNi * vs_out.FragPos;
	
	gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0);

    vs_out.glPosition = gl_Position;
}

#shader geometry
#version 430 core

/* Information passed from the vertex shader */
in DATA {
    vec3        FragPos;
    vec3        Normal;
    vec2        TexCoords;
    mat3        TBN;
    flat vec3   TangentViewPos;
    vec3        TangentFragPos;
    vec4        glPosition;
    vec3        distance;
} gs_in[];

/* Information passed to the fragment shader */
out DATA {
    vec3        FragPos;
    vec3        Normal;
    vec2        TexCoords;
    mat3        TBN;
    flat vec3   TangentViewPos;
    vec3        TangentFragPos;
    vec4        glPosition;
    vec3        distance;
} gs_out;

uniform float LineThickness = 1.0;

layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

void main() {
	float lineTiickness = (10.0 - LineThickness) * 100.0;
	
	if (LineThickness <= 1.0)
		lineTiickness = 900.0;
		
	if (LineThickness >= 9.0)
		lineTiickness = 100.0;

	vec2 p0 = lineTiickness * gs_in[0].glPosition.xy / gs_in[0].glPosition.w;
	vec2 p1 = lineTiickness * gs_in[1].glPosition.xy / gs_in[1].glPosition.w;
	vec2 p2 = lineTiickness * gs_in[2].glPosition.xy / gs_in[2].glPosition.w;

	vec2 v0 = p2 - p1;
	vec2 v1 = p2 - p0;
	vec2 v2 = p1 - p0;	

	float area = abs(v1.x * v2.y - v1.y * v2.x);
	
	for (int i = 0; i < 3; i++) {
		if (i == 0)
			gs_out.distance = vec3(area / length(v0), 0, 0);

		else if (i == 1)
			gs_out.distance = vec3(0, area / length(v1), 0);

		else if (i == 2)
			gs_out.distance = vec3(0, 0, area / length(v2));

		gs_out.FragPos = gs_in[i].FragPos;
		gs_out.Normal = gs_in[i].Normal;
		gs_out.TexCoords = gs_in[i].TexCoords;
		gs_out.TBN = gs_in[i].TBN;
		gs_out.TangentViewPos = gs_in[i].TangentViewPos;
		gs_out.TangentFragPos = gs_in[i].TangentFragPos;
		gl_Position = gs_in[i].glPosition;

		EmitVertex();
	}
	
	EndPrimitive();
}

#shader fragment
#version 430 core

/* Global information sent by the engine */
layout (std140) uniform EngineUBO {
    mat4    ubo_Model;
    mat4    ubo_View;
    mat4    ubo_Projection;
    vec3    ubo_ViewPos;
    float   ubo_Time;
};

/* Information passed from the fragment shader */
in DATA {
    vec3        FragPos;
    vec3        Normal;
    vec2        TexCoords;
    mat3        TBN;
    flat vec3   TangentViewPos;
    vec3        TangentFragPos;
    vec4        glPosition;
    vec3        distance;
} fs_in;

/* Light information sent by the engine */
layout(std430, binding = 0) buffer LightSSBO {
    mat4 ssbo_Lights[];
};

/* Uniforms (Tweakable from the material editor) */
uniform vec2        u_TextureTiling           = vec2(1.0, 1.0);
uniform vec2        u_TextureOffset           = vec2(0.0, 0.0);
uniform vec4        u_Diffuse                 = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec3        u_Specular                = vec3(1.0, 1.0, 1.0);
uniform float       u_Shininess               = 100.0;
uniform float       u_HeightScale             = 0.0;
uniform bool        u_EnableNormalMapping     = false;
uniform sampler2D   u_DiffuseMap;
uniform sampler2D   u_SpecularMap;
uniform sampler2D   u_NormalMap;
uniform sampler2D   u_HeightMap;
uniform sampler2D   u_MaskMap;
uniform vec4		u_LineColor				  = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4		u_MeshColor				  = vec4(0.7, 0.7, 0.7, 1.0);

/* Global variables */
vec3 g_Normal;
vec2 g_TexCoords;
vec3 g_ViewDir;
vec4 g_DiffuseTexel;
vec4 g_SpecularTexel;
vec4 g_HeightTexel;
vec4 g_NormalTexel;

vec3 UnPack(float p_Target) {
    return vec3 (
        float((uint(p_Target) >> 24) & 0xff)    * 0.003921568627451,
        float((uint(p_Target) >> 16) & 0xff)    * 0.003921568627451,
        float((uint(p_Target) >> 8) & 0xff)     * 0.003921568627451
    );
}

bool PointInAABB(vec3 p_Point, vec3 p_AabbCenter, vec3 p_AabbHalfSize) {
    return (
        p_Point.x > p_AabbCenter.x - p_AabbHalfSize.x && p_Point.x < p_AabbCenter.x + p_AabbHalfSize.x &&
        p_Point.y > p_AabbCenter.y - p_AabbHalfSize.y && p_Point.y < p_AabbCenter.y + p_AabbHalfSize.y &&
        p_Point.z > p_AabbCenter.z - p_AabbHalfSize.z && p_Point.z < p_AabbCenter.z + p_AabbHalfSize.z
    );
}

vec2 ParallaxMapping(vec3 p_ViewDir) {
    const vec2 parallax = p_ViewDir.xy * u_HeightScale * texture(u_HeightMap, g_TexCoords).r;
    return g_TexCoords - vec2(parallax.x, 1.0 - parallax.y);
}

vec3 BlinnPhong(vec3 p_LightDir, vec3 p_LightColor, float p_Luminosity) {
    const vec3  halfwayDir          = normalize(p_LightDir + g_ViewDir);
    const float diffuseCoefficient  = max(dot(g_Normal, p_LightDir), 0.0);
    const float specularCoefficient = pow(max(dot(g_Normal, halfwayDir), 0.0), u_Shininess * 2.0);

    return p_LightColor * g_DiffuseTexel.rgb * diffuseCoefficient * p_Luminosity + ((p_Luminosity > 0.0) ? (p_LightColor * g_SpecularTexel.rgb * specularCoefficient * p_Luminosity) : vec3(0.0));
}

float LuminosityFromAttenuation(mat4 p_Light) {
    const vec3  lightPosition   = p_Light[0].rgb;
    const float constant        = p_Light[0][3];
    const float linear          = p_Light[1][3];
    const float quadratic       = p_Light[2][3];

    const float distanceToLight = length(lightPosition - fs_in.FragPos);
    const float attenuation     = (constant + linear * distanceToLight + quadratic * (distanceToLight * distanceToLight));
    return 1.0 / attenuation;
}

vec3 CalcPointLight(mat4 p_Light) {
    /* Extract light information from light mat4 */
    const vec3 lightPosition  = p_Light[0].rgb;
    const vec3 lightColor     = UnPack(p_Light[2][0]);
    const float intensity     = p_Light[3][3];

    const vec3  lightDirection  = normalize(lightPosition - fs_in.FragPos);
    const float luminosity      = LuminosityFromAttenuation(p_Light);

    return BlinnPhong(lightDirection, lightColor, intensity * luminosity);
}

vec3 CalcDirectionalLight(mat4 light) {
    return BlinnPhong(-light[1].rgb, UnPack(light[2][0]), light[3][3]);
}

vec3 CalcSpotLight(mat4 p_Light) {
    /* Extract light information from light mat4 */
    const vec3  lightPosition   = p_Light[0].rgb;
    const vec3  lightForward    = p_Light[1].rgb;
    const vec3  lightColor      = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];
    const float cutOff          = cos(radians(p_Light[3][1]));
    const float outerCutOff     = cos(radians(p_Light[3][1] + p_Light[3][2]));

    const vec3  lightDirection  = normalize(lightPosition - fs_in.FragPos);
    const float luminosity      = LuminosityFromAttenuation(p_Light);

    /* Calculate the spot intensity */
    const float theta           = dot(lightDirection, normalize(-lightForward)); 
    const float epsilon         = cutOff - outerCutOff;
    const float spotIntensity   = clamp((theta - outerCutOff) / epsilon, 0.0, 1.0);
    
    return BlinnPhong(lightDirection, lightColor, intensity * spotIntensity * luminosity);
}

vec3 CalcAmbientBoxLight(mat4 p_Light) {
    const vec3  lightPosition   = p_Light[0].rgb;
    const vec3  lightColor      = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];
    const vec3  size            = vec3(p_Light[0][3], p_Light[1][3], p_Light[2][3]);

    return PointInAABB(fs_in.FragPos, lightPosition, size) ? g_DiffuseTexel.rgb * lightColor * intensity : vec3(0.0);
}

vec3 CalcAmbientSphereLight(mat4 p_Light) {
    const vec3  lightPosition   = p_Light[0].rgb;
    const vec3  lightColor      = UnPack(p_Light[2][0]);
    const float intensity       = p_Light[3][3];
    const float radius          = p_Light[0][3];

    return distance(lightPosition, fs_in.FragPos) <= radius ? g_DiffuseTexel.rgb * lightColor * intensity : vec3(0.0);
}

out vec4 FragColor;

void main() {
    g_TexCoords = u_TextureOffset + vec2(mod(fs_in.TexCoords.x * u_TextureTiling.x, 1), mod(fs_in.TexCoords.y * u_TextureTiling.y, 1));

    /* Apply parallax mapping */
    if (u_HeightScale > 0)
        g_TexCoords = ParallaxMapping(normalize(fs_in.TangentViewPos - fs_in.TangentFragPos));

    /* Apply color mask */
    if (texture(u_MaskMap, g_TexCoords).r != 0.0) {
        g_ViewDir           = normalize(ubo_ViewPos - fs_in.FragPos);
        g_DiffuseTexel      = texture(u_DiffuseMap,  g_TexCoords) * u_Diffuse;
        g_SpecularTexel     = texture(u_SpecularMap, g_TexCoords) * vec4(u_Specular, 1.0);

        if (u_EnableNormalMapping) {
            g_Normal = texture(u_NormalMap, g_TexCoords).rgb;
            g_Normal = normalize(g_Normal * 2.0 - 1.0);   
            g_Normal = normalize(fs_in.TBN * g_Normal);
        }

        else {
            g_Normal = normalize(fs_in.Normal);
        }

        vec3 lightSum = vec3(0.0);

        for (int i = 0; i < ssbo_Lights.length(); ++i) {
            switch(int(ssbo_Lights[i][3][0])) {
                case 0: lightSum += CalcPointLight(ssbo_Lights[i]);         break;
                case 1: lightSum += CalcDirectionalLight(ssbo_Lights[i]);   break;
                case 2: lightSum += CalcSpotLight(ssbo_Lights[i]);          break;
                case 3: lightSum += CalcAmbientBoxLight(ssbo_Lights[i]);    break;
                case 4: lightSum += CalcAmbientSphereLight(ssbo_Lights[i]); break;
            }
        }

        FragColor = vec4(lightSum, g_DiffuseTexel.a);
    }

    else {
        FragColor = vec4(0.0);
    }
	
	float d = min(fs_in.distance.x, min(fs_in.distance.y, fs_in.distance.z));
	float I = exp2(-2 * d * d);
	
	FragColor = FragColor + I * u_LineColor + (1.0 - I) * u_MeshColor;
}

Is this what you mentioned?

Thanks

Hi, thanks for the input

You saved my day :slight_smile: