我正在尝试通过WebGL着色器中的各向异性模拟某种镜面反射,类似于本教程here中描述的那样。
我意识到,虽然很容易获得像Utah teapot这样的球形的令人信服的结果,但是通过对平面或正方形几何体实施各向异性照明来获得美观的照明效果却要困难得多。
在阅读了nVIDIA的这篇论文Anisotropic Lighting using HLS之后,我开始玩以下着色器:
vec3 surfaceToLight(vec3 p) {
return normalize(p - v_worldPos);
}
vec3 anisoVector() {
return vec3(0.0,0.0,1.0);
}
void main() {
vec3 texColor = vec3(0.0);
vec3 N = normalize(v_normal); // Interpolated directions need to be re-normalized
vec3 L = surfaceToLight(lightPos);
vec3 E = anisoVector();
vec3 H = normalize(E + L);
vec2 tCoords = vec2(0.0);
tCoords.x = 2.0 * dot(H, N) - 1.0; //The value varies with the line of sight
tCoords.y = 2.0 * dot(L, N) - 1.0; //each vertex has a fixed value
vec4 tex = texture2D(s_texture, tCoords);
//vec3 anisoColor = tex.rgb; // show texture color only
//vec3 anisoColor = tex.aaa; // show anisotropic term only
vec3 anisoColor = tex.rgb * tex.aaa;
texColor += material.specular * light.color * anisoColor;
gl_FragColor = vec4(texColor, u_opacity);
}
这是我实际得到的(几何没有纹理坐标且法线没有折痕):
我知道我不能简单地将上述论文中描述的方法用于所有事情,但至少,对我而言,这似乎是实现快速 simulated 各向异性照明的一个很好的起点
遗憾的是,我无法完全理解用于创建纹理的数学运算,所以我问是否有任何一种方法可以
调整片段着色器这一部分的纹理坐标
tCoords.x = 2.0 * dot(H, N) - 1.0;
tCoords.y = 2.0 * dot(L, N) - 1.0;
调整纹理内的Alpha通道的形状(在RGBA层和结果下方)
...为平面几何(如右侧的立方体)获得美观的垂直镜面反射。
有人知道吗?
顺便说一句,如果有人感兴趣,请注意纹理应该被镜像:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
...这是PNG的纹理(nVIDIA的原始纹理为TGA格式)。