Version: 5.3 (switch to 5.4b)
Custom Shader GUI
Текстура глубины камеры

Использование текстур глубины

Существует возможность создавать рендер-текстуры, где каждый пиксель содержит точное значение “глубины” (см. RenderTextureFormat.Depth). Это в основном используется, когда для каких-нибудь эффектов нужно, чтобы глубина сцены была доступна (например, для мягких частиц, SSAO, полупрозрачности потребуется глубина сцены).

Значения пикселей в текстуре глубины находятся в диапазоне от 0 до 1 с нелинейным распространением. Точность обычно 24 или 16 бит, в зависимости от используемого буфера глубины. При обращении к текстуре глубины возвращается высокоточное значение в диапазоне от 0 до 1. Если вам нужно получить расстояние от камеры или линейное значение, то вам следует вычислять это вручную.

Depth textures are supported on most modern hardware and graphics APIs. Special requirements are listed below:

  • В Direct3D 11 (Windows) присутствует поддержка нативной текстуры глубины точно так же, как и в OpenGL.
  • Direct3D 9 (Windows) requires a graphics driver to support “INTZ” texture format to get depth textures.
  • Видеокарта должна поддерживать расширение GL_OES_depth_texture.
  • Видеокарта должна поддерживать расширение GL_OES_depth_texture.
  • Direct3D 11 feature level 9.x (common on Windows Phone devices) does not support depth textures.

Использование макроса-помощника текстуры глубины

Большая часть времени текстуры глубины используются, чтобы рендерить глубину относительно камеры. Подключаемый файл UnityCG.cginc содержит некоторые макросы, чтобы решать ситуацию без дополнительных сложностей:

  • UNITY_TRANSFER_DEPTH(o): вычисляет глубину вершин в пространстве зрителя и присваивает это значение переменной o (которая должна быть типа float2). Используйте это в вершинной программе, когда рендерите в текстуру глубины. На платформах с нативными текстурами глубины этот макрос не делает абсолютно ничего, потому что значение Z-буфера безоговорочно рендерится.
  • UNITY_OUTPUT_DEPTH(i): возвращает глубину пространства зрителя из переменной i (которая должна быть типа float2). Используйте это в фрагментной программе, когда рендерите в текстуру глубины. На платформах с нативными текстурами глубины этот макрос возвращает ноль, потому что значение Z-буфера безоговорочно рендерится.
  • COMPUTE_EYEDEPTH(i): вычисляет глубину вершин в пространстве зрителя и выдаёт значение в переменную o. Используйте это в вершинных программах, когда не рендерите в текстуру глубины.
  • DECODE_EYEDEPTH(i): даёт высокоточное значение из текстуры глубины i, возвращает соответствующую глубину пространства зрителя. В Direct3D этот макрос просто возвращает i*FarPlane. На платформах с нативными текстурами глубины значение становится линейным и расширяется до предела камеры.

Например, этот шейдер будет рендерить глубину своих объектов:

Shader "Render Depth" {
SubShader {
    Tags { "RenderType"="Opaque" }
    Pass {
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) : SV_Target {
    UNITY_OUTPUT_DEPTH(i.depth);
}
ENDCG
    }
}
}

Смотрите так же

Custom Shader GUI
Текстура глубины камеры