I am using OpenGL ES 2.0 to develop an Android game in Java. Currently I am writing my own vertex and fragment shader. I encountered a weird problem in my fragment shader: normalize(u_LightPos - v_Position) is DIFFERENT from normalize(normalize(u_LightPos - v_Position)), where u_LightPos is a uniform and v_Position a varying.
Why is normalize() not idempotent? Why do I have to call it twice to get an actually normal (length 1) vector? This is very confusing.
EDIT:
Here is the vertex shader:
uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;
attribute vec4 a_Position;
attribute vec3 a_Normal;
varying vec3 v_Position;
varying vec3 v_Normal;
void main() {
v_Position = vec3(u_MVMatrix * a_Position);
v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));
gl_Position = u_MVPMatrix * a_Position;
}
And here is the fragment shader:
precision mediump float;
uniform vec3 u_LightPos;
uniform vec4 u_Color;
varying vec3 v_Position;
varying vec3 v_Normal;
void main() {
float distance = length(u_LightPos - v_Position);
vec3 lightVector = normalize(normalize(u_LightPos - v_Position));
float diffuse = max(dot(v_Normal, lightVector), 0.0);
gl_FragColor = u_Color * diffuse;
}
If I don't double normalize the lightVector, the dot product will be > 1.1, as I have tested. And no, normalizing v_Normal doesn't change that fact.
precision mediump float. - Kenjiu_LightPosand the approximate range ofv_Position? I wonder if there could still be a precision issue if those values are very large. Does anything change if you set the precision tohighp? - Reto Koradi