版本:Unity 6 (6000.0)
语言:English
在着色器中使用 16 位精度
纹理采样器

将顶点数据输入着色器

对于 Cg/HLSL 顶点程序MeshUnity 中的主要图形基元。网格构成了 3D 世界的很大一部分。Unity 支持三角形或四边形多边形网格。Nurbs、Nurms、细分曲面必须转换为多边形。 更多信息
请参阅 词汇表
顶点数据作为输入传递给顶点着色器函数。每个输入都需要指定一个 语义:例如,POSITION 输入是顶点位置,NORMAL 是顶点法线。

通常,顶点数据输入在结构中声明,而不是逐个列出。

输入内置顶点结构

一些常用的顶点结构在 UnityCG.cginc 包含文件 中定义,在大多数情况下,只需使用这些结构就足够了。这些结构是

  • appdata_base:位置、法线和一个纹理坐标。
  • appdata_tan:位置、切线、法线和一个纹理坐标。
  • appdata_full:位置、切线、法线、四个纹理坐标和颜色。
  • appdata_img:顶点 着色器在 GPU 上运行的程序。 更多信息
    请参阅 词汇表
    输入,包含位置和一个纹理坐标。

示例

此着色器根据网格的法线对网格进行着色,并使用 appdata_base 作为顶点程序输入

Shader "VertexInputSimple" {
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
         
            struct v2f {
                float4 pos : SV_POSITION;
                fixed4 color : COLOR;
            };
            
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.color.xyz = v.normal * 0.5 + 0.5;
                o.color.w = 1.0;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target { return i.color; }
            ENDCG
        }
    } 
}

输入自定义顶点结构

要访问不同的顶点数据,您需要自己声明顶点结构,或向顶点着色器添加输入参数。顶点数据由 Cg/HLSL 语义 标识,并且必须来自以下列表

  • POSITION 是顶点位置,通常是 float3float4
  • NORMAL 是顶点法线,通常是 float3
  • TEXCOORD0 是第一个 UV 坐标,通常是 float2float3float4
  • TEXCOORD1TEXCOORD2TEXCOORD3 分别是第二个、第三个和第四个 UV 坐标。
  • TANGENT 是切线向量(用于法线贴图),通常是 float4
  • COLOR 是每个顶点的颜色,通常是 float4

当网格数据包含的组件少于顶点着色器输入所需的组件时,其余组件将用零填充,除了 .w 组件,其默认值为 1。例如,网格纹理坐标通常是只有 x 和 y 组件的二维向量。如果顶点着色器声明一个带有 TEXCOORD0 语义的 float4 输入,则 顶点着色器在渲染 3D 模型时在模型的每个顶点上运行的程序。 更多信息
请参阅 词汇表
收到的值将包含 (x,y,0,1)。

为了获得最佳的跨平台支持,将顶点输出和片段输入标记为 TEXCOORDn 语义。

Unity 还支持以下内容

  • VPOS - 正在渲染的 像素计算机图像中的最小单位。像素大小取决于屏幕分辨率。像素光照是在每个屏幕像素处计算的。 更多信息
    请参阅 词汇表
    的位置。着色器必须具有 #pragma target 3.0 编译指令,并且应将裁剪空间位置作为单独的“out”变量输出。为了获得最大可移植性,请使用 UNITY_VPOS_TYPE 类型,该类型在大多数平台上都是 float4
  • VFACE - 渲染的表面是面向 相机在场景中创建特定视点的图像的组件。输出要么绘制到屏幕上,要么作为纹理捕获。 更多信息
    请参阅 词汇表
    还是背对相机。着色器必须具有 #pragma target 3.0 编译指令。
  • SV_VertexID - 正在处理的顶点的索引。着色器必须具有 #pragma target 3.5 编译指令。

有关使用这些技术在内置 渲染管线一系列操作,将场景的内容显示在屏幕上。Unity 允许您从预构建的渲染管线中选择,或编写自己的渲染管线。 更多信息
请参阅 词汇表
中可视化顶点数据的示例,请参阅 可视化顶点数据

常量缓冲区宏

Direct3D 11 将所有着色器变量分组到“常量缓冲区”中。大多数 Unity 内置变量已经分组,但对于您自己的着色器中的变量,根据更新频率预期将它们放在单独的常量缓冲区中可能会更优化。

为此,请使用 CBUFFER_START(name)CBUFFER_END

CBUFFER_START(MyRarelyUpdatedVariables)
    float4 _SomeGlobalValue;
CBUFFER_END

如果您使用 GPU 计算缓冲区图形缓冲区 来设置变量的值,请确保缓冲区和常量缓冲区在您构建的所有图形 API 上都具有匹配的数据布局。有关更多信息,请参阅 使用常量缓冲区与 GPU 缓冲区

注意:您无法将结构添加到常量缓冲区。

插值器计数限制

总共可以使用多少个插值器变量来传递从顶点到片段着色器的信息,存在限制。限制取决于平台和 GPU,一般准则是

  • 最多 8 个插值器:Direct3D 11 9.x 级别(Windows Phone)。由于插值器计数有限,但每个插值器都可以是一个 4 分量向量,因此一些着色器将事物打包在一起以保持在限制范围内。例如,您可以在一个 float4 变量中传递两个纹理坐标(.xy 用于一个坐标,.zw 用于第二个坐标)。
  • 最多 10 个插值器:着色器模型 3.0 (#pragma target 3.0)。
  • 最多 16 个插值器:OpenGL ES 3.0(Android)、Metal(iOS)。
  • 最多 32 个插值器:Direct3D 10 着色器模型 4.0 (#pragma target 4.0)。

无论您的特定目标硬件是什么,出于性能原因,通常最好尽可能少地使用插值器。

其他资源

在着色器中使用 16 位精度
纹理采样器