上篇所述ADSGouraud着色会使镜面高亮部分有闪烁,这是由于三角形之间的不连续造成的,这种不连续则是由颜色值在空间中进行的是线性插值导致的。这些亮线实际上是相互独立的三角形之间的缝隙。
有一种方法可以减弱这种现象,叫做Phong着色,在Phong着色时,我们不在顶点之间进行颜色插值,二十载顶点之间进行表面法线的插值。而这种Phong着色也是目前的主流着色方法。
这两种着色基本代码相同,GLSL代码不同。
说白了就是把光线处理部分放在面片着色器中
.vp
#version 120
attribute vec4 vVertex;
attribute vec3 vNormal;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
varying vec3 vVaryingNormal;
varying vec3 vVaryingLightDir;
void main(void)
{
vVaryingNormal = normalMatrix * vNormal;
vec4 vPosition4 = mvMatrix * vVertex;
vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
vVaryingLightDir = normalize(vLightPosition - vPosition3);
gl_Position = mvpMatrix * vVertex;
}
.fp
#version 120
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
varying vec3 vVaryingNormal;
varying vec3 vVaryingLightDir;
void main(void)
{
float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
vec4 vFragColor = diff * diffuseColor;
vFragColor += ambientColor;
vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));
float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));
if(diff != 0) {
float fSpec = pow(spec, 128.0);
vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
}
gl_FragColor=vFragColor;
}