一.介绍Three.js中的Fog
雾在生活场景中的使用其实非常广泛,比如我们去看秋天的晨雾,公路的尽头,远处的海面时,远处的景色总是要模糊一些不如近景那么清晰那么亮,这将在计算机中怎么表现呢?然后就衍生处了Fog这个类。
Fog这个类包含定义线性雾的参数,也就是说,密度随着距离的增加呈线性增长
构造器Fog(hex, near, far)
这个hex参数被传递给 Color 构造函数来设置颜色属性。hex是一个十六进制整数或CSS样式的字符串
属性
cocol
雾的颜色。比如:如何设置为黑色,远处的物体将被渲染成黑色。
near
开始应用雾的最小距离。若距离当前相机小于near个单位,则该对象不会受到雾的影响。
far
结束应用雾的最大距离。若距离当前相机大于far个单位,则该对象不会收到雾的影响
二.场景上的简单运用
this.scene.fog = new THREE.Fog(0x000000, 0, 100); //添加雾的效果
直接new一个赋值到scene上即可
三.自定义shader上的使用
const mat = new THREE.ShaderMaterial({ //自定义shader材质
vertexShader: vs,
fragmentShader: fs,
uniforms: this.uniforms,
transparent: true,
side: THREE.DoubleSide, //双面
wireframe: false,
fog: true, //雾效
});
创建ShaderMaterial时添加属性fog为true即可,该值默认为false
然后设置shander中雾的参数
setFog(fog) {
this.uniforms.fogColor = { type: 'c', value: fog.color };
this.uniforms.fogNear = { type: 'f', value: fog.near };
this.uniforms.fogFar = { type: 'f', value: fog.far };
}
若scene上已有fog属性,这里可以用this.stage.scene.fog来传到shader中。
当我们已经拿到fog的属性时,就可以在shader中运用了,运用如下:
#ifdef USE_FOG =
float depth = gl_FragCoord.z / gl_FragCoord.w;
float fogFactor = smoothstep( fogNear, fogFar, depth );
gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); //z越小,颜色越暗
#endif
gl_FragCoord.w 是裁剪空间 clip.w 的倒数即 1/clip.w , 由上面的透视投影矩阵的推导过程可以看出,为了凑透视除法, clip.w 值就是 眼坐标系 z 值的负数,也就是距离相机的距离。
1.由上,我们可以知道gl_FragCoord.z / gl_FragCoord.w就表示当前片元和camera之间的距离即深度;
2.再由smoothstep( fogNear, fogFar, depth )来得到一个平滑的因子fogFactor,深度越到,该因子值越大。
3.再通过mix来混合得到最终的rgb值
GLSL内置mix函数 介绍
mix(x,y,a) a控制混合结果 return x(1-a) +y*a 返回 线性混合的值
即fogFactor值越大,fogColor占比越大。假设fogColor为黑色,那么综合上面所讲,这三句代码的意思就是越远越暗,符合我们对雾效的定义和预期。
四.应用示例
没有雾效:
有雾效:
很明显使用雾效后远处更暗一点,更自然一些