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