从Render Texture(CPU端)获取像素深度的最简方法?
获取RenderTexture像素深度值的简便方案
不用额外写着色器显示深度,Unity本身提供了直接读取深度缓冲的方式,下面是两种实用方法:
方法1:直接读取RenderTexture的深度缓冲到Texture2D
首先要保证你的RenderTexture创建时开启了深度缓冲(创建面板里把Depth Buffer Format设为24位或其他非None选项),然后按以下步骤来:
- 将目标RenderTexture设为当前活跃渲染目标:
RenderTexture.active = 你的捕获RenderTexture - 创建一个格式为
TextureFormat.RFloat的Texture2D(专门存浮点深度数据,比RGBA更节省内存) - 调用
Graphics.ReadPixels时,最后一个参数传true——这个参数就是告诉Unity读取深度缓冲而不是颜色缓冲 - 之后遍历Texture2D的像素,通过
.r通道就能拿到0~1范围的原始深度值
示例代码:
RenderTexture captureRT = 你的场景捕获RenderTexture; RenderTexture.active = captureRT; // 创建适配深度数据的纹理 Texture2D depthTexture = new Texture2D(captureRT.width, captureRT.height, TextureFormat.RFloat, false); // 读取深度缓冲到纹理 depthTexture.ReadPixels(new Rect(0, 0, captureRT.width, captureRT.height), 0, 0, true); depthTexture.Apply(); // 遍历像素获取深度 for (int y = 0; y < captureRT.height; y++) { for (int x = 0; x < captureRT.width; x++) { float rawDepth = depthTexture.GetPixel(x, y).r; // 可选:转换为线性深度或世界空间深度 // float linearDepth = Linear01Depth(rawDepth); // float worldDepth = Camera.main.farClipPlane * linearDepth; } } // 清理状态 RenderTexture.active = null; Destroy(depthTexture);
方法2:利用相机的深度纹理模式
如果你的RenderTexture是相机渲染输出的,可以先给相机设置depthTextureMode = DepthTextureMode.Depth,这样相机会自动生成深度纹理。之后你可以直接通过相机的目标RenderTexture获取深度缓冲引用,要是需要CPU端遍历,还是结合方法1的ReadPixels来读取就行。
注意点
- 必须开启RenderTexture的深度缓冲,否则读不到任何深度数据
- 直接读到的0~1深度值是非线性的(和透视投影有关),需要的话用Unity内置的
Linear01Depth或LinearEyeDepth转成线性深度 - 读完后一定要把
RenderTexture.active设回null,避免干扰后续的渲染流程
内容的提问来源于stack exchange,提问作者drygloss
相关产品推荐
相关产品推荐

