读书笔记12《Unity Shader入门精要》
第 13 章 使用深度和法线纹理
Unity 中的获取方法
在 Unity 中获取深度纹理:
1 | camera.depthTextureMdoe = DepthTextureMode.Depth; |
在 Shader 中通过_CameraDepthTexture访问。
获取 深度+法线纹理:
1 | camera.depthTextureMode = DepthTextureMode.DpethNormals; |
在 Shader 中通过_CameraDepthNormalsTexture访问。
让一个摄像机同时产生一张深度纹理 和 一张深度+法线纹理
1 | camera.depthTextureMdoe |= DepthTextureMode.Depth; |
Unity 有统一宏 SAMPLE_DEPTH_TEXTURE 对深度纹理采样。
1 | float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv); |
深度纹理的值是非线性的,需要变换。 是负数, 是范围在 [0, 1] 的线性深度值。
当然,Unity 中有辅助函数来进行上述计算。
查看方法
如果摄像机需要生成深度和法线纹理,那么在 Frame Debugger 中就能看到。看到的深度纹理是非线性的,而深度+法线纹理是由 Unity 编码后的结果。
想要看到线性的深度值:
1 | float depth = SMAPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv); |
法线方向:
1 | fixed3 normal = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, i.uv).xy); |
基于速度映射的运动模糊
实践
实现使用速度映射图的运动模糊。
本节实现的运动模糊适用与场景静止、摄像机快速运动的情况。若摄像机静止,对快速运动的物体不会产生效果。
全局雾效
重建世界坐标
只需要知道摄像机在世界空间下的位置,以及世界空间下该像素相对于摄像机的偏移量,把它们相加就可以得到该像素的世界坐标。
1 | float4 worldPos = _WorldSpaceCameraPos + linearDepth * interpolatedRay; |
interpolatedRay 来源于对近裁切平面的 4 个角的某个特定向量的插值。
雾的计算
1 | float3 afterFog = f * fogColor + (1 - f) * origColor; |
雾效系数 f 有多种算法。Unity 内置的雾效实现有三种:
线性(Linear), 和 分别表示受雾影响的最大距离和最小距离
指数(Exponential), 是控制雾的浓度的参数
指数的平方(Exponential Squared), 是控制雾的浓度的参数
实践
基于高度的雾效
实践
在 Unity 中实现基于屏幕后处理的雾效。
- UnityCG.cginc 里包含 appdata_img 结构体。小心重复。
改进的边缘检测
实践
在 Unity 中实现基于深度和法线纹理的描边效果。
- 在 OnRenderImage 函数前添加 [ImageEffectOpaque] 属性,这样这个函数就会在不透明物体渲染完成之后(半透明物体渲染之前),调用。也就是不会给半透明物体描边。
- 标题: 读书笔记12《Unity Shader入门精要》
- 作者: 铁名_IronName
- 创建于 : 2026-01-28 09:43:54
- 更新于 : 2026-02-15 15:21:03
- 链接: https://blog.ironname.top/2026/01/28/读书笔记12《Unity-Shader入门精要》/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论