With infinite light source and only ambient and diffuse lights — no specular light, it seems the rendering results of vertex lighting and fragment lighting should be the same, because all the lighting calculations are linear and it means calculation-then-interpolation and interpolation-then-calculation should be the same. However, the actual results are still not exactly the same, with fragment lighting still smoother. What did I misunderstand? Or is it just because of loss of arithmetic precision during calculation-then-interpolation?
Code of fragment lighting:
// Vertex shader
attribute vec4 Position;
attribute vec3 Normal;
uniform mat4 Projection;
uniform mat4 Modelview;
uniform mat3 NormalMatrix;
varying vec3 EyespaceNormal;
void main(void)
{
EyespaceNormal = NormalMatrix * Normal;
gl_Position = Projection * Modelview * Position;
}
// Fragment shader
varying mediump vec3 EyespaceNormal;
uniform highp vec3 LightPosition;
uniform highp vec3 DiffuseMaterial;
uniform highp vec3 AmbientMaterial;
void main(void)
{
highp vec3 N = normalize(EyespaceNormal);
highp vec3 L = normalize(LightPosition);
highp float df = max(0.0, dot(N, L));
lowp vec3 color = AmbientMaterial + df * DiffuseMaterial;
gl_FragColor = vec4(color, 1);
}
Code of vertex lighting:
// Vertex shader
attribute vec4 Position;
attribute vec3 Normal;
uniform mat4 Projection;
uniform mat4 Modelview;
uniform mat3 NormalMatrix;
uniform highp vec3 LightPosition;
uniform highp vec3 DiffuseMaterial;
uniform highp vec3 AmbientMaterial;
varying lowp vec3 Color;
void main(void)
{
highp vec3 EyespaceNormal = NormalMatrix * Normal;
highp vec3 N = normalize(EyespaceNormal);
highp vec3 L = normalize(LightPosition);
highp float df = max(0.0, dot(N, L));
Color = AmbientMaterial + df * DiffuseMaterial;
gl_Position = Projection * Modelview * Position;
}
// Fragment shader
varying lowp vec3 Color;
void main(void)
{
gl_FragColor = vec4(Color, 1);
}