Version: Unity 6.0 (6000.0)
语言 : 中文
从内置渲染管线中的着色器库导入文件
使用 GrabPass 命令获取当前帧缓冲区

使用内置渲染管线中的内置着色器函数

Unity 在 UnityCG.cginc 中提供了许多内置实用函数,旨在使编写着色器更简单,更轻松。

变换位置

功能: 描述:
float4 UnityObjectToClipPos(float3 pos) 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间。这等效于__mul(UNITY_MATRIX_MVP, float4(pos, 1.0)),应该在适当的位置使用。| |float3 UnityObjectToViewPos(float3 pos)|将对象空间中的点变换到视图空间。这等效于 mul(UNITY_MATRIX_MV, float4(pos, 1.0)).xyz__,应该在适当的位置使用。

变换其他值

功能: 描述:
float3 WorldSpaceViewDir (float4 v) 返回从给定对象空间顶点位置朝向摄像机的世界空间方向(未标准化)。
float3 ObjSpaceViewDir (float4 v) 返回从给定对象空间顶点位置朝向摄像机的对象空间方向(未标准化)。
float2 ParallaxOffset (half h, half height, half3 viewDir) 计算视差法线贴图的 UV 偏移。
fixed Luminance (fixed3 c) 将颜色转换为亮度(灰阶)。
fixed3 DecodeLightmap (fixed4 color) 从 Unity 光照贴图(RGBM 或 dLDR,具体取决于平台)解码颜色。
float4 EncodeFloatRGBA (float v) 将 (0..1) 范围浮点数编码为 RGBA 颜色,用于存储在低精度渲染目标中。
float DecodeFloatRGBA (float4 enc) 将 RGBA 颜色解码为浮点数。
float2 EncodeFloatRG (float v) 将 (0..1) 范围浮点数编码为 float2。
float DecodeFloatRG (float2 enc) 解码先前编码的 RG 浮点数。
float2 EncodeViewNormalStereo (float3 n) 将视图空间法线编码为 0 到 1 范围内的两个数字。
float3 DecodeViewNormalStereo (float4 enc4) 从 enc4.xy 解码视图空间法线。

前向渲染 helper 函数

仅当使用前向渲染(ForwardBase 或 ForwardAdd 通道类型)时,这些函数才有用。

功能: 描述:
float3 WorldSpaceLightDir (float4 v) 根据给定的对象空间顶点位置计算朝向光源的世界空间方向(未标准化)。
float3 ObjSpaceLightDir (float4 v) 根据给定对象空间顶点位置计算朝向光源的对象空间方向(未标准化)。
float3 Shade4PointLights (...) 计算四个点光源的光照,将光源数据紧密打包到矢量中。前向渲染使用它来计算每顶点光照。

屏幕空间 helper 函数

以下 helper 函数可计算用于采样屏幕空间纹理的坐标。它们返回 float4,其中用于纹理采样的最终坐标可以通过透视除法(例如 xy/w)计算得出。

这些函数还处理渲染纹理坐标中的平台差异

功能: 描述:
float4 ComputeScreenPos (float4 clipPos) 计算用于执行屏幕空间贴图纹理采样的纹理坐标。输入是裁剪空间位置。
float4 ComputeGrabScreenPos (float4 clipPos) 计算用于 GrabPass 纹理采样的纹理坐标。输入是裁剪空间位置。

顶点光照 helper 函数

仅当使用每顶点光照着色器(“Vertex”通道类型)时,这些函数才有用。

功能: 描述:
float3 ShadeVertexLights (float4 vertex, float3 normal) 根据给定的对象空间位置和法线计算四个每顶点光源和环境光的光照。

阴影贴图宏

根据平台的不同,声明和采样阴影贴图可能会有很大差异。Unity 有几个宏可帮助解决这个问题:

宏: 用途:
UNITY_DECLARE_SHADOWMAP(tex) 声明一个名为“tex”的阴影贴图纹理变量。
UNITY_SAMPLE_SHADOW(tex,uv) 在给定的“uv”坐标处采样阴影贴图纹理“tex”(XY 分量是纹理位置,Z 分量是要比较的深度)。返回单个浮点值,阴影项的范围在 0 到 1 之间。
UNITY_SAMPLE_SHADOW_PROJ(tex,uv) 与上面类似,但是会读取投影阴影贴图。“uv”是一个 float4,所有其他分量除以 .w 来执行查找。

tex 的格式必须为 RenderTextureFormat.Shadowmap

__注意:__并非所有显卡都支持阴影贴图。使用 SystemInfo.SupportsRenderTextureFormat 来检查支持情况。

深度纹理 helper 宏

大多数情况下,深度纹理用于渲染距离摄像机的深度。在此情况下,UnityCG.cginc include 文件包含的一些宏可以处理上述复杂问题:

  • COMPUTE_EYEDEPTH(i):计算顶点的眼睛空间深度并将其在__o__ 中输出。当__不__渲染到深度纹理时,在顶点程序中使用此宏。
  • DECODE_EYEDEPTH(i)/LinearEyeDepth(i):通过深度纹理 i 给出高精度值时,返回相应的眼睛空间深度。
  • Linear01Depth(i):通过深度纹理 i 给出高精度值时,返回相应的线性深度,范围在 0 到 1 之间。
  • UNITY_TRANSFER_DEPTH(o):已弃用。计算顶点的眼睛空间深度并将其在 o 中输出(必须是 float2)。在具有本机深度纹理的平台上,此宏不执行任何操作,因为 Z 缓冲区值是隐式渲染的。
  • UNITY_OUTPUT_DEPTH(i):已弃用。从 i 返回眼睛空间深度(必须为 float2)。在具有本机深度纹理的平台上,此宏始终返回零,因为 Z 缓冲区值是隐式渲染的。

__注意:__在 DX11/12 和 Metal 中,Z 缓冲区范围是 1 到 0,并定义了 UNITY_REVERSED_Z。在其他平台上,范围是 0 到 1。

例如,以下着色器将渲染其游戏对象的深度:

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 = UnityObjectToClipPos(v.vertex);
                UNITY_TRANSFER_DEPTH(o.depth);
                return o;
            }

            half4 frag(v2f i) : SV_Target {
                UNITY_OUTPUT_DEPTH(i.depth);
            }
            ENDCG
        }
    }
}
从内置渲染管线中的着色器库导入文件
使用 GrabPass 命令获取当前帧缓冲区