要点
在片元着色器通过逆矩阵来重建世界坐标,性能消耗非常大。需要快速从深度纹理中重建世界坐标
目标效果
- 基于高度的雾效
- 不均匀雾效
准备
- 噪声纹理
过程
重建世界坐标
利用 近裁面的四个方向向量,插值后在片元着色器中,乘以深度值得到,点对于摄像机的偏移,再加上摄像机的位置得到。
float4 worldPos = _worldSpaceCameraPos + linearDepth * interpolatedRay _worldSpaceCameraPos:摄像机在世界空间下的位置 linearDepth:由深度纹理得到的线性深度值 interpolatedRay:由顶点着色器输出(近裁剪面中心到四个角的向量)并插值后得到的射线,不仅包含了该像素到摄像机的方向,也包含了距离信息。 PS: 因为后处理本身处理的是一个quad,所以可以这么插值interpolatedRay
雾计算
在unity内置的雾效中有三种计算方式: 得到fogDensity 后,再乘一下直接调雾浓度的参数,最后用来插值
float fogDensity = (_FogEnd - worldPos.y) / (_FogEnd - _FogStart);
fogDensity = saturate(fogDensity * _FogDensity);
fixed4 finalColor = tex2D(_MainTex, i.uv);
finalColor.rgb = lerp(finalColor.rgb, _FogColor.rgb, fogDensity);
不均匀雾
加入噪音的偏移
float2 speed = _Time.y * float2(_FogXSpeed, _FogYSpeed);
float noise = (tex2D(_NoiseTex, i.uv + speed).r - 0.5) * _NoiseAmount;
float fogDensity = (_FogEnd - worldPos.y) / (_FogEnd - _FogStart);
fogDensity = saturate(fogDensity * _FogDensity * (1 + noise));
总结
想起来重建像素的世界坐标这个方法,可以用于自己软渲染管线的shadowmap实现,可以节省好多矩阵运算。
|