I'm trying to implement very simple diffuse shader in GLSL/openGL. Here's what I got: Vertex shader:
#version 130
in vec3 vertPos3D;
in vec3 vertNormal3D;
uniform mat3 transpMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;
varying vec3 vertNormal;
varying vec3 lightVector;
void main()
{
vec4 res_pos = projectionMatrix * viewMatrix * vec4(vertPos3D.xyz, 1.0);
gl_Position = res_pos;
mat4 pm = projectionMatrix * viewMatrix;
vertNormal = (viewMatrix * vec4(vertNormal3D, 0)).xyz;
lightVector = (viewMatrix * vec4(lightPosition, 1.0)).xyz - (viewMatrix * vec4(vertPos3D.xyz, 1.0)).xyz;
}
Fragment Shader:
#version 130
out vec4 color;
varying vec3 lightVector;
varying vec3 vertNormal;
void main()
{
float dot_product = max(normalize(dot(lightVector, vertNormal)), 0.0);
color = dot_product * vec4( 1.0, 1.0, 1.0, 1.0 );
}
As soon as I multiply final color with dot_product, nothing displays. I remove dot_product, everything works (except diffuse lightning ofc.). I'm afraid it's something obvious I'm missing.
A problem:
normalize(dot(lightVector, vertNormal))
dot
in GLSL 1.3 returns a float.
normalize
accepts a vector, not a float.
documentation for dot
documentation for normalize
A Solution, at least to this problem:
In Fragment shader, replace
float dot_product = max(normalize(dot(lightVector, vertNormal)), 0.0);
with
float dot_product = clamp(dot(lightVector, vertNormal), 0., 1.);
It looks like you are using max and normalize to avoid negative numbers returned from dot
. This is exactly what clamp
is for. Here's the documentation for clamp
Use
float dot_product = max(dot(normalize(lightVector), normalize(normalVector)), 0.0);
Dylan Holmes answer is slightly incorrect:
Still the lightVector needs to be normalized!
And clamping is unnecessary. max
was correct. A dot product never returns a value higher then 1.0 if input vectors are normalized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With