修复grabpass制作的折射在水面以上也会扭曲的问题
程序员文章站
2024-02-14 09:49:46
...
之前被问到如何修复由于grabpass采样制作的水体折射问题:
如上图,这是一个浸没在水面的立方体,由于获取grabpass会同时获取水面上部分立方体的图像,因此在扭曲的时候会将立方体上半部分进行扭曲。
我的思路是通过对比深度图来确定是否有物体位于水上,水上的部分势必会遮挡住水面,因此深度值应该更小。既然我们能在grabpass图上通过偏移能采样到立方体,那么在深度图上同样能,下面是未经过偏移的深度采样:
fixed depth =LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)));
我们对他进行偏移:
fixed depth2 =LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.scrPos.xy+offset,i.scrPos.z,i.scrPos.w))));
offset
值具体内容在我上一篇文章中有提到。
将采样出来的深度值同当前水面的深度值进行比较,如果深度值大于当前水体深度,即物体在水下,就进行偏移,否则不进行动作:
if(depth2 >=i.scrPos.z){
offsetPos += offset;
}
现在看看效果:
可以看到,在边缘有一点点效果,我们增加一个_test
属性改变采样偏移倍率:
fixed depth2 =LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.scrPos.xy+_test*offset,i.scrPos.z,i.scrPos.w))));
这是效果:
可以看到,解决的还是比较好的,下面是新的折射部分shader代码,替换上一篇文章的shader源码即可:
//折射
float2 offset = normal.xz*_RefrDistortion * _RefractionTex_TexelSize.xy;
float2 offsetPos = i.grabPos.xy/i.grabPos.w;
//对深度图再次采样,确认是否采集到不应该采集的点
fixed depth2 =LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.scrPos.xy+_test*offset,i.scrPos.z,i.scrPos.w))));
if(depth2 >=i.scrPos.z){
offsetPos += offset;
}
fixed3 refrCol = tex2D(_RefractionTex,offsetPos).rgb;
上一篇: 树链剖分的学习理解