雾效在自定义Shader中的运用

一.介绍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为黑色,那么综合上面所讲,这三句代码的意思就是越远越暗,符合我们对雾效的定义和预期。

四.应用示例

没有雾效:

attachmentId-78

有雾效:

attachmentId-79

很明显使用雾效后远处更暗一点,更自然一些

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值