简介
摄像机可以生成深度纹理,可用于实现自定义光照模型或水体等效果的制作。
深度纹理
深度纹理(Depth Texture)中的像素值通常表示从摄像机到 游戏对象(Game Object)的深度值,介于 0 和 1 之间,0 表示距离相机最近,1 表示距离相机最远。这些值通常是非线性分布的,因为它们经过 深度缓冲(Depth Buffer)或 Z 缓冲的映射,目的是为了更好地处理精度问题,特别是在远距离时。这样的非线性分布通常遵循透视投影矩阵的深度缓冲公式。
深度纹理的精度
深度纹理可以具有多种精度,通常包括 16 位、24 位和 32 位。为了适应移动设备,Blockman Go 使用 16 位精度是合理的选择。这意味着深度值用 16 位存储,可以在 0 到 65535 之间的范围内表示深度值,再映射到 0 到 1 之间。
深度纹理信息
根据深度纹理信息,会返回一个高精度值(通常在 0 到 1 之间),这些值代表了从相机到物体的深度。在渲染过程中,深度测试(Depth Test)决定哪个像素在最终图像中可见。较近的物体会覆盖较远的物体,这样可以确保深度较浅(即距离较近)的物体出现在深度较深的物体前面。

基于深度纹理的渲染顺序示意图。
渲染队列和深度纹理的关系
在渲染过程中,游戏对象的 材质(Material)有一个 渲染队列值(Render Queue)属性,这个属性值决定了游戏对象的渲染顺序。渲染队列小于等于 3000 的游戏对象通常被认为是不透明的,这些对象会首先渲染并写入深度缓冲。
只有这些不透明游戏对象的深度信息会被写入深度纹理,因为深度缓冲通常只在不透明对象渲染时更新。透明对象一般不会写入深度缓冲,因为它们的深度信息不适合用于后续的深度测试。
读取深度纹理
在 SandMod 的渲染管线中,摄像机会根据其当前帧捕获的内容绘制 颜色纹理(Color Texture)和 深度纹理(Depth Texture),此时摄像机的颜色纹理和深度纹理是不可被读取的。
如果此时您需要读取对应摄像机当前帧绘制的深度纹理信息制作一些特殊效果(如水体扰动等),您需要在该摄像机对应的 摄像机(Camera)组件(Component)中将 需要深度纹理(Require Depth Texture)属性值设置为 勾选(True)。

此时 SandMod 会在缓存中复制一份当前帧的深度纹理,随后您可以在 着色器(Shader)中通过声明名为 _DepthTexture 的采样器,读取摄像机的深度纹理信息,并制作相关效果。

读取摄像机当前帧深度纹理的底层逻辑示意图。其中:1. 红色箭头表示 读取(Read)过程;2. 蓝色箭头表示 绘制(Draw)过程;3. 灰色箭头表示 复制(Copy)过程。
