Version: 6000.3
语言: 中文
在着色器中使用 16 位精度
纹理采样器

将顶点数据输入着色器

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

通常,顶点数据输入是在结构中声明的,而不是 将它们一一列出。

输入内置顶点结构

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

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

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

Shader "VertexInputSimple" {
    SubShader {
        Pass {
            HLSLPROGRAM
            #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; }
            ENDHLSL
        }
    } 
}

输入自定义顶点结构

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

  • POSITION是顶点位置,通常是float3float4.
  • NORMAL是顶点法线,通常是float3.
  • TEXCOORD0是第一个 UV 坐标,通常float2,float3float4.
  • TEXCOORD1,TEXCOORD2TEXCOORD3分别是第 2、第 3 和第 4 个 UV 坐标。
  • TANGENT是切线向量(用于法线贴图),通常是float4.
  • COLOR是每个顶点的颜色,通常是float4.

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

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

Unity 还支持以下内容:

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

有关使用这些技术在内置渲染管线(Render Pipeline) 获取场景内容并将其显示在屏幕上的一系列作。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 位精度
纹理采样器