返回介绍

使用深度纹理

发布于 2021-06-20 00:15:07 字数 2406 浏览 1102 评论 0 收藏 0

可以创建深度纹理,其中每个像素包含一个高精度的“深度”值(请参阅 RenderTextureFormat.Depth)。这主要在一些效果需要有场景深度时使用(例如,软粒子、屏幕空间环境光遮蔽和半透明均需要场景深度)。

深度纹理中的像素值范围是 0 到 1,同时呈非线性分布。精度通常是 24 位或 16 位,具体取决于所使用的深度缓冲区。从深度纹理读取时,会返回一个 0..1 范围内的高精度值。如果需要获取与相机的距离或者线性值,则需手动计算。

Unity 中的深度纹理在不同平台上的执行是不同的。

  • 在 Direct3D 9 (Windows) 上,深度纹理可以是本地的深度缓冲区,也可以是单通道 32 位浮点纹理(“R32F”Direct3D 格式)。
    • 图形卡必须支持本地深度缓冲区(INTZ 格式)或浮点渲染纹理中的任何一个,以便使其正常运行。
    • 当渲染进深度纹理时,片段程序必须输出需要的数值。
    • 当从深度纹理读取时,颜色的红色组件包含高精度数值。
  • 在 OpenGL (Mac OS X) 上,深度纹理是本地的 OpenGL 深度缓冲区(请参阅 ARB_depth_texture)。
    • 图形卡必须支持 OpenGL 1.4 或 ARB_depth_texture 扩展。
    • 深度纹理与渲染的 Z 缓冲区内容相对应,它使用片段程序输出的结果。
  • OpenGL ES 2.0 (iOS/Android) 与上面的 OpenGL 十分类似。
  • 和 OpenGL 一样,Direct3D 11 (Windows) 也具有本地深度纹理功能。
  • Flash (Stage3D) 使用按颜色编码的深度纹理来模仿它所需要的高精度。

使用深度纹理帮助宏

大多数时候,深度纹理用于渲染从相机的深度。在此情况下,UnityCG.cginc include file 包含一些宏以处理上述难题:

  • UNITY_TRANSFER_DEPTH(o):计算顶点的视角空间深度,并输出到 o(必须是 float2)中。渲染进深度纹理时,在顶点程序中使用。在有本地深度纹理的平台上,该宏不会起任何作用,因为 Z 缓冲区的值是隐式渲染的。
  • UNITY_OUTPUT_DEPTH(i):从 i 返回视角空间深度(必须是 float2)。渲染进深度纹理时,在片段程序中使用。在有本地深度纹理的平台上,该宏总是返回 0,因为 Z 缓冲区的值是隐式渲染的。
  • COMPUTE_EYEDEPTH(i):计算顶点的视角空间深度,并输出到 o。渲染进深度纹理时,在顶点程序中使用。
  • DECODE_EYEDEPTH(i):从深度纹理 i 得到高精度值,返回相应的视角空间深度。该宏在 Direct3D 中仅返回 i*FarPlane。在有本地深度纹理的平台上,它进行线性化并扩展该值,从而匹配相机的范围。

例如,这个着色器渲染其对象的深度:

Shader "Render Depth" {
SubShader {
    Tags { "RenderType"="Opaque" }
    Pass {
        Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

struct v2f {
    float4 pos : SV_POSITION;
    float2 depth : TEXCOORD0;
};

v2f vert (appdata_base v) {
    v2f o;
    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    UNITY_TRANSFER_DEPTH(o.depth);
    return o;
}

half4 frag(v2f i) : COLOR {
    UNITY_OUTPUT_DEPTH(i.depth);
}
ENDCG
    }
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文