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); }