webgl 反射天空球

webgl 反射天空球

下面图片的场景中,湖水把天空的云朵,晚霞都反射出来了。现在我们也来模拟一下这个场景,天空球之前已经实现了。

img

这次要实现的效果,如下图所示,正方体表面是光滑的,可以反射天空球中的图像。

GIF 2021-12-3 16-24-15

在绘制天空盒的时候,摄像机在盒子内部,所以需要看到盒子里面,可以使用 gl.cullFace(gl.FRONT) 删除外面

当绘制正面正方体的时候,而箱子在摄像机外部,正常情况要能够看到盒子外面,所以在绘制箱子时,我们要把背面剔除方式改回背面剔除 gl.cullFace(gl.BACK)

有时候,天空盒经过视图投影矩阵作用之后,不一定在场景的最后面(也就是 Z 值坐标不是 1.0),所以,在天空盒后面的物体我们就看不到了。针对这个问题,一般采取的做法是修改顶点着色器,将天空盒的 Z 值强制改为 1.0,即在裁剪坐标系的最后面。

1
gl_Position = (u_Matrix * a_Position).xyww;

w/w = 1.0。所以经过裁剪变换后,gl_Position 的Z 值坐标始终会是 1.0。

镜面反射的实现思路:已知当前片元的入射角,法线,求出反射角,反射角的值就是该片元所反射到的天空盒的纹理坐标。

纹理映射
1
2
3
4
5
void main(){
vec3 incident = normalize(v_Position - u_CameraPosition); //入射角
vec3 reflection = reflect(incident, v_Normal); //反射角
gl_FragColor = textureCube(u_Skybox, reflection);
}

完整效果


webgl 反射天空球
http://example.com/2024/05/23/webgl/webgl 反射天空球/
Author
John Doe
Posted on
May 23, 2024
Licensed under