上篇所述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;
}