解答:編輯 fragmentShader 變數,在 vec3 normal = normalize( vNormal ); 之後替換為:
for ( int i = 0; i < 2; i++) {
vec3 offset = (i==0) ? vWorldPosition : -vWorldPosition;
offset.y = 0.0;
vec3 jiggledNormal = normalize( normal + uGroove * normalize( offset ) );
// 漫射:N * L。法向量必須正規化,因為經過內插計算
float diffuse = max( dot( jiggledNormal, lVector ), 0.0);
// 漫射貢獻減半,因為有兩個法向量
gl_FragColor.rgb += 0.5 * uKd * uMaterialColor * uDirLightColor * diffuse;
// 鏡面反射:N * H 的指數。H 是往光的向量加上往攝影機的向量正規化
vec3 viewPosition = normalize( vViewPosition );
vec3 pointHalfVector = normalize( lVector + viewPosition );
float pointDotNormalHalf = max( dot( jiggledNormal, pointHalfVector ), 0.0 );
float specular = uKs * pow( pointDotNormalHalf, shininess );
specular *= diffuse * (2.0 + shininess)/8.0;
// 這樣可能會切斷高光,但是比奇怪的閃爍好
if (diffuse <= 0.0) { specular = 0.0; }
// 鏡面反射貢獻減半,因為有兩個法向量
gl_FragColor.rgb += 0.5 * uDirLightColor * uSpecularColor * specular;
}