如何:设计域着色器

域着色器是协同工作以实现 分割的三个阶段中的第三个阶段。 域着色器从外壳着色器中的转换控制点和 UV 坐标生成表面几何图形。 本主题演示如何设计域着色器。

为固定函数细化器生成的每个点调用一次域着色器。 输入是贴片上点的 UV[W] 坐标,以及外壳着色器的所有输出数据,包括控制点和修补常量。 输出是以所需的任何方式定义的顶点。 如果要将输出发送到像素着色器,则输出必须包含用SV_Position语义) 表示的位置 (。

设计域着色器

  1. 定义域属性。

    [domain("quad")]
    

    域是为象限补丁定义的。

  2. 使用域位置系统值声明外壳上 的位置

    • 对于象限补丁,请使用 float2。
    • 对于三个补丁,请将 float3 (用于大中心坐标)
    • 对于等值线,请使用 float2。

    因此,象限修补程序的域位置如下所示:

    float2 UV : SV_DomainLocation
    
  3. 定义其他输入。

    其他输入来自外壳着色器,由用户定义。 这包括修补程序的输入控制点(其中可能有 1 到 32 个点)和输入补丁常量数据。

    控制点由用户定义,通常 (在如何:设计外壳着色器) 中定义这样的结构:

    const OutputPatch<BEZIER_CONTROL_POINT, 16> bezpatch
    

    修补程序常量数据也是用户定义的,可能类似于 如何:设计外壳着色器) 中定义的 (如下所示:

    HS_CONSTANT_DATA_OUTPUT input
    
  4. 添加用户定义的代码以计算输出;这构成域着色器的主体。

    此结构包含用户定义的域着色器输出。

    struct DS_OUTPUT
    {
        float3 vNormal    : NORMAL;
        float2 vUV        : TEXCOORD;
        float3 vTangent   : TANGENT;
        float3 vBiTangent : BITANGENT;
    
        float4 vPosition  : SV_POSITION;
    };
    

    函数从细化器) 获取每个输入 UV (,并在此位置评估 Bezier 补丁。

    [domain("quad")]
    DS_OUTPUT BezierEvalDS( HS_CONSTANT_DATA_OUTPUT input, 
                            float2 UV : SV_DomainLocation,
                            const OutputPatch<BEZIER_CONTROL_POINT, 16> bezpatch )
    {
        DS_OUTPUT Output;
    
        // Insert code to compute the output here.
    
        return Output;    
    }
    

    对于固定函数细化器生成的每个点,将调用函数一次。 由于此示例使用象限补丁,因此输入域位置 (SV_DomainLocation) 是 float2 (UV) ;三个补丁具有 float3 输入位置 (UVW 大中心坐标) ,等值线将具有 float2 输入域位置。

    函数的其他输入直接来自外壳着色器。 在此示例中,每个控制点有 16 个控制点作为 BEZIER_CONTROL_POINT,以及修补常量数据 (HS_CONSTANT_DATA_OUTPUT) 。 输出是包含任何所需数据的顶点 - 在此示例中 DS_OUTPUT

设计域着色器后,请参阅 如何:创建域着色器

如何使用 Direct3D 11

细化概述