文章目录
前言
在上篇文章中,我们实现了水面的反射。
在这篇文章中,我们来实现一下水的焦散效果。
一、原理
和深度贴花使用的方法是一致的。
主要步骤:
1、 通过深度图,得到 对应像素 在 世界空间下的Z值
2、得到模型顶点在 观察空间 下的坐标
3、由以上两点得到 深度图像素 对应的 xyz 值
4、最后,转化到 模型本地空间下,用其对焦散纹理采样
二、实现
1、获取深度图
(因为要考虑之前的水下扭曲效果,需要把深度图扭曲一下)
- 获取 屏幕空间下的UV坐标
float2 screenUV = i.positionCS.xy / _ScreenParams.xy;
- 使用_Distort控制得到线性插值在 screenUV 和 normalTex之间的扭曲UV
(在之前的文章中,有完整过程)
float2 distortUV = lerp(screenUV,normalTex.xy,_Distort);
- 使用该UV采样得到,水下扭曲后的深度纹理
half4 depthDistortTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,distortUV);
- 使深度图 转化到 观察空间下
half depthDistortScene = LinearEyeDepth(depthDistortTex.x,_ZBufferParams);
2、在顶点着色器中,转化 得到顶点在 观察空间下的坐标值
o.positionWS = TransformObjectToWorld(v.positionOS);
o.positionVS = TransformWorldToView(o.positionWS);
3、使用公式计算得到,深度图 z 对应的 xy 值
公式在贴花的那篇文章有推导
- W x = P x W z − P z W_x = \frac{P_xW_z}{-P_z} Wx=−Pz