内容
- 简介
- 获取深度图
- 线性化深度值
- 深度图浅析
1. 简介
屏幕后处理,指的是在渲染完整个场景得到屏幕图像后, 再对这个图像进行一系列操作,来实现各种屏幕特效。比如说景深效果的实现(离摄像机/焦距越远的部分,图片越模糊),这时候我们需要获取屏幕图像上每个像素点对应的物体相对于摄像机的距离,即深度。在Unity中,我们可以通过“深度图”(一张存储着高精度深度信息的渲染纹理)来获取深度信息。
2. 获取深度图
下面是获取深度图的步骤:
-
设置摄像机的depthTextureMode,告诉摄像机你需要一张深度纹理:
Camera.main.depthTextureMode = DepthTextureMode.Depth;
- 然后,我们就可以在shader中通过属性 _CameraDepthTexture 获取深度图:
sampler2D _CameraDepthTexture;
- 接着我们对深度图采样,来获取深度图中存取的信息。
- 这里可以使用 tex2D 采样,但有些平台上需要一些特殊处理(如PS3和PSP2),因此 Unity 提供了一个统一的宏 SAMPLE_DEPTH_TEXTURE,用来处理由于平台差异造成的问题:
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv); //i.uv对应了当前像素的纹理坐标
- 类似的宏还有SAMPLE_DEPTH_TEXTURE_PROJ 和SAMPLE_DEPTH_TEXTURE_LOD:
float depth2 = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screen);
float depth3 = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.uv,0,0)));
3. 线性化深度值
上面采样后获取的 depth 就是深度值了,But!这里获取的深度值大多情况下是不能直接使用的!还需要经过一步叫做“线性化”的操作,暂时不需要知道它是怎么实现的,这里Unity提供了两个线性化的接口,代码如下:
//得到的深度值范围:[Near,Far] Near(近裁剪平面) Far(远裁剪平面)
float LinearDepth1 = LinearEyeDepth(depth);
//得到的深度值范围:[0,1]
float LinearDepth2 &