Specular component in ADSGourad and ADSPhong are computed with an incorrect
equation.
The correct specular component should be computed by the scalar product of the
reflection vector and the normalized position vector of the fragment/vertex
with respect to the camera (which is normalized(vPosition3) for ADSGourad)
The incorrect code...
// Specular Light
vec3 vReflection = normalize(reflect(-vLightDir, vEyeNormal));
float spec = max(0.0, dot(vEyeNormal, vReflection));
if(diff != 0) {
float fSpec = pow(spec, 128.0);
vVaryingColor.rgb += vec3(fSpec, fSpec, fSpec);
}
The code below fixes the specular calculation and also makes a small
optimization... if diff is zero, we dont need to calculate the specular
component.
// Specular Light
if (diff != 0){ // do this only if diffusion is non zero.
vec3 vReflection = normalize(reflect(-vLightDir, vEyeNormal));
vec3 vNormPos3 = normalize(vPosition3);
float spec = max(0.0, -dot(vNormPos3, vReflection)); // correct specular component
float fSpec = pow(spec, 128.0);
vVaryingColor.rgb += fSpec * specularColor.rgb;
}
The same problem also affects ADSPhong. The fix is as follows...
Add new out attribute vVaryingPosition to ADSPhong.vp
smooth out vec3 vVaryingLightDir;
smooth out vec3 vVaryingPosition;// new line
...
...
vVaryingLightDir = normalize(vLightPosition - vPosition3);
vVaryingPosition = vPosition3; // new line
and add correct specular calculation to ADSPhong.fp
smooth in vec3 vVaryingLightDir;
smooth in vec3 vVaryingPosition; // new line
...
...
// Specular Light
if(diff != 0) {
vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));
float spec = max(0.0, -dot(normalize(vVaryingPosition), vReflection));
float fSpec = pow(spec, 128.0);
vFragColor.rgb += fSpec * specularColor.rgb;
}
The incorrect and correct Phong lighting outputs are attached.
Original issue reported on code.google.com by nag.ra...@gmail.com on 17 Sep 2012 at 11:21
Original issue reported on code.google.com by
nag.ra...@gmail.com
on 17 Sep 2012 at 11:21Attachments: