unity 水波效果

这篇博客详细介绍了如何在Unity中通过法线扰动模拟水波效果,主要包括计算折射、反射及混合这两个值的步骤。使用grabpass获取屏幕纹理,然后在片元着色器中计算屏幕坐标并进行折射采样。反射值则直接从立方体贴图采样,通过Fresnel公式混合反射和折射的比例,最终实现逼真的水波效果。
摘要由CSDN通过智能技术生成

在这里插入图片描述 这个水波效果并非真实的让顶点去运动而产生的的效果,而是通过法线扰动而产生的模拟效果,产生效果主要分为三个步骤,第一个步骤是计算折射,第二个步骤是计算反射,最后一个步骤是混合反射和折射的值。
首先是计算折射值,这个也是这三个中最复杂的一个部分,首先折射所采样的纹理是通过grabpass来实现的,grabpass可以在渲染完毕所有的不透明物体之后把渲染完毕的图形存储到一个纹理中,然后在下一个pass中就可以调用这个纹理了,而这个例子中的grabpass得到的纹理就是上图去掉水流的纹理。
然后我们需要获取屏幕坐标来对grabpass得到的_RefractionTex进行采样,想弄明白这个采样过程还是得回去好好看看渲染流水线。
首先使用o.scrPos = ComputeGrabScreenPos(o.pos);来获取屏幕坐标,不过得注意,这个坐标是齐次坐标,是没有除过w的,而且顶点着色器里面也不能去除w,因为顶点着色器得到的结果将会差值到片元着色器中,除以w之后会破坏它的线性,导致差值的结果变的不正确,因此,我们还需要在片元着色器中除以w来得到真正的屏幕坐标。
我们来观察一下ComputeGrabScreenPos的源码:

inline float4 ComputeGrabScreenPos (float4 pos) {
    #if UNITY_UV_STARTS_AT_TOP
    float scale = -1.0;
    #else
    float scale = 1.0;
    #endif
    float4 o = pos * 0.5f;
    o.xy = float2(o.x, o.y*scale) + o.w;
#ifdef UNITY_SINGLE_PASS_STEREO
    o.xy = TransformStereoScreenSpaceTex(o.xy, pos.w);
#endif
    o.zw = pos.zw;
    return o;
}

去掉那些对平台进行特殊处理的代码,这代码翻译过来的意思就是,
o.x = pos.x/2+pos.w/2,o.y = pos.y/2+pos.w/2,o.zw = pos.zw;
稍微变一下
o.x = (pos.x/pos.w+1)*pos.w/2(把(-1,1)范围的NDC映射到(0,1)的视口坐标)
把它最后再除一个pos.w就是最终的视口坐标了,也就是说把NDC转换为了除以w之前的视口坐标
接下来就是计算偏移的代码

float2 offset = bump.xy * _Distortion * _Refractio
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值