当前位置:   article > 正文

Unity Shader基础【二】- HLSL基本语法_hlsl samplerstate

hlsl samplerstate

下面对微软所给的HLSL官方文档进行简单梳理,将其基本语法总结如下。

1 数据类型

1.1 缓存(Buffer)
  • 用法:Buffer Name

  • 示例:Buffer g_Buffer;

  • 说明:Type可以为标量、向量或一些矩阵类型

1.2 标量
  • bool:布尔值,true或false。

  • int: 32位有符号整型。

  • uint: 32位无符号整型。

  • dword: 32位无符号整型。

  • half: 16位浮点型。该类型只是为了保持语言兼容性,Direct3D 10将所有half都映射为float型,该类型不能用作标准全局变量。

  • float:32位浮点型。

  • fixed: 11位低精度浮点数。

  • double: 64位浮点型。
1.3 向量类型
  • 用法:TypeNumber Name 或 vector

1.4 矩阵类型
  • 用法:TypeNumberxNumber Name 或 matrix

1.5 采样器类型(Sampler)
  • 用法:

    Direct3D 9:

    sampler Name = SamplerType{ Texture = ; [state_name = state_value;] … };

    Direct3D 10之后:

    SamplerType Name[Index]{ [state_name = state_value;] … };

  • 示例:

    Direct3D 9:
    
    sampler MeshTextureSampler = 
    sampler_state
    {
        Texture = <g_MeshTexture>;
        MipFilter = LINEAR;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
    };
    
    Direct3D 10之后:
    
    SamplerState MeshTextureSampler
    {
        Filter = MIN_MAG_MIP_LINEAR;
        AddressU = Wrap;
        AddressV = Wrap;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 说明:
    sampler:只有Direct3D 9需要。

    Name:采样器名称

    [Index]:Direct3D 10后需要,定义数据长度

    SamplerType:采样器类型,可为: sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, sampler_state, SamplerState,SamplerComparisonState(仅Direct3D 10之后支持)。

    Texture = :纹理变量。

    state_name = state_value:可选状态设置,所有状态赋值必须出现在状态块中(大括号中),由分号分隔。

1.6 着色器类型(Shader)
  • 用法:

    Direct3D 10之后: SetXXXShader Compile( ShaderTarget, ShaderFunction );

    Direct3D 9之前: XXXShader = compile ShaderTarget ShaderFunction(…);

  • 示例:

    // Direct3D 10
    technique10 Render
    {
        pass P0
        {
            SetVertexShader( CompileShader( vs_4_0, VS() ) );
            SetGeometryShader( NULL );
            SetPixelShader( CompileShader( ps_4_0, PS() ) );
        }
    }
    
    // Direct3D 9
    technique RenderSceneWithTexture1Light
    {
        pass P0
        {          
            VertexShader = compile vs_2_0 RenderSceneVS( 1, true, true );
            PixelShader  = compile ps_2_0 RenderScenePS( true );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 说明:
    SetXXXShader: Direct3Dy调用底层API创建Shader对象,可为SetPixelShader、SetGeometryShader 或SetVertexShader。(Direct3D 9中XXXShader可为SetPixelShader或SetVertexShader)

    ShaderTarget: 用于编译的shader模型:vs_4_0, gs_4_0或ps_4_0

    ShaderFunction(…):Shader名称,包含着色器入口点函数名,当Shader被调用时,该函数会被执行;(…)表示函数参数,这些参数同样会被传递给创建Shader对象的API函数:SetPixelShader或SetVertexShader

1.7 纹理类型(Texture)
  • 用法:Type Name;

  • 示例:Texture2D g_MeshTexture;

  • 说明:Type可以为texture,Texture1D, Texture1DArray, Texture2D, Texture2DArray, Texture3D, TextureCube。

  • 备注:调用Texture在Direct3D 9和10中有比较大的差异

    //9
    Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;
    //10
    Output.RGBColor = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV) * In.Diffuse;
    
    • 1
    • 2
    • 3
    • 4
1.8 结构体

用法:

    struct struct2
    {
      int    a;
      float  b;
      int4x4 iMatrix;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

访问方式与C语言类似,通过.来访问。

1.9 自定义类型
  • 用法:typedef [const] Type Name[Index];

  • 示例:

    typedef int DWORD;
    typedef float FLOAT; 
    typedef vector <float, 4> VECTOR;
    typedef matrix <float, 4, 4> MATRIX;
    typedef string STRING;
    typedef texture TEXTURE;
    typedef pixelshader PIXELSHADER;
    typedef vertexshader VERTEXSHADER;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 说明:Type可以为HLSL定义的固定类型。

2 HLSL语义

2.1 顶点着色器(Vertex Shader)语义
输入描述类型
BINORMAL[n]次法线float4
BLENDINDICES[n]混合指数uint
BLENDWEIGHT[n]混合权重float
COLOR[n]固有色与高光色float4
NORMAL[n]法向量float4
POSITION[n]模型空间中顶点坐标float4
POSITIONT顶点坐标转置float4
PSIZE[n]点大小float
TANGENT[n]切线float4
TEXCOORD[n]纹理坐标float4
输出描述类型
COLOR[n]固有色与高光色float4
FOG顶点雾化值float
POSITION[n]齐次空间顶点坐标,将(x,y,z)除以w即可得到屏幕坐标空间,每个顶点Shader必须有该语义输出。float4
PSIZE点大小float
TESSFACTOR[n]曲面细分因子float
TEXCOORD[n]纹理坐标float4
2.2 像素着色器(Pixel Shader)语义
输入描述类型
COLOR[n]固有色与高光色float4
TEXCOORD[n]纹理坐标float4
VFACE用于标记一个背面图元的浮点标量值,负值表示面向背面,正值表示面向相机,该语义仅在Direct3D 9的Shader Model 3.0中可用,Direct3D 10以后使用SV_IsFrontFace替代float
VPOS屏幕空间像素位置(x,y). 该语义用于Direct3D 9,之后版本请使用SV_Positionfloat2
输出描述类型
COLOR[n]输出颜色float4
DEPTH[n]输出深度float
2.3 语义变化
Direct3D 10语义Direct3D 9等价语义
SV_DepthDEPTH
SV_PositionPOSITION
SV_TargetCOLOR
2.4 示例

套用《Unity Shader入门精要》一书中的内容作为示例:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unlit/TestShader"
{
    SubShader{
        Pass{
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            //通过结构体定义顶点着色器输入
            struct a2v{
                //POSTION语义:使用模型空间顶点坐标填充vertex变量
                float4 vertex : POSITION; 
                //NORMAL语义:使用模型空间法向量填充normal变量
                float3 normal : NORMAL; 
                //TEXCOORD0语义:使用模型第一套纹理坐标填充texcoord变量
                float4 texcoord : TEXCOORD0; 
            };

            struct v2f{
                //SV_POSTION语义:pos存储了裁剪空间中顶点位置信息
                float4 pos : SV_POSITION; 
                //COLOR0语义:color存储颜色信息
                float3 color : COLOR0;              
            };


            //SV_POSITION语义:顶点着色器的输出作为裁剪空间顶点坐标
            v2f vert(a2v v){
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);
                //将法向量从[-1, 1]映射至[0, 1],通过color传递给像素(片元)着色器
                o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
                return o;
            }

            //SV_Target语义:像素着色器的输出存储到一个渲染目标(RenderTarget)当中
            fixed4 frag(v2f i) : SV_Target{         
                return fixed4(i.color, 1.0);
            }
            ENDCG
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
2.5 问题
  • HLSL中POSTION与VS_POSITION的区别?

    SV_前缀的变量代表system value,在DX10以后的语义绑定中被使用代表特殊的意义,和POSITION用法并无不同。唯一区别是 SV_POSTION一旦被作为vertex shader的输出语义,那么这个最终的顶点位置就被固定了,直接进入光栅化处理,如果作为fragment shader的输入语义那么和POSITION是一样的,代表着每个像素点在屏幕上的位置,这个说法其实并不准确,事实是fragment 在view space空间中的位置,但直观的感受是如括号之前所述一般。

    在DX10版本之前没有引入SV_的预定义语义,POSITION被用作vertex shader的输入和输出,fragment shader的输入参数。但DX10之后就推荐使用SV_POSITION作为vertex shader的输出和fragment shader的输入,注意vertex shader的输入还是使用POSITION! 不过,DX10以后的代码依旧兼容POSITION作为全程表达。

3 函数

3.1 函数声明

HLSL的函数定义与C语言也基本类型,形式如下:

[StorageClass] [clipplanes()] [precise] Return_Value Name ( [ArgumentList] ) [: Semantic]
{
  [StatementBlock]
};
  • 1
  • 2
  • 3
  • 4

参数说明:

  • StorageClass: 重定义函数声明的修改器,目前仅支持inline,因此函数总是内联。
  • clipplanes:可选剪裁平面列表,最多为6个定义裁剪平面;该参数功能等同于SV_ClipDistance(特性层次高于9_x)
  • Return_Value: 返回值
  • Name:函数名
  • ArgumentList:参数列表
  • Semantic:返回值的语义(见上一节)
  • StatementBlock:函数块

示例:

struct VS_OUTPUT
{
    float4 Position   : SV_POSITION; 
    float4 Diffuse    : COLOR0;
    float2 TextureUV  : TEXCOORD0;
};

VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
                         float3 vNormal : NORMAL,
                         float2 vTexCoord0 : TEXCOORD,
                         uniform int nNumLights,
                         uniform bool bTexture,
                         uniform bool bAnimate )
{
    VS_OUTPUT Output;
    ...
    return Output;    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
3.2 函数参数

参数形式如下:

[InputModifier] Type Name [: Semantic] [InterpolationModifier] [= Initializers]
  • 1

参数说明:

  • InputModifier:可选参数,定义参数为输入、输出或两者皆是。 in为输入,out为输出,inout为输入输出,uniform为常量输入。不填时参数默认为in,被定义成uniform可视为全局变量,对于非顶层函数,uniform与in同义。
  • Type:参数类型
  • Name:参数名称
  • Semantic :参数语义
  • InterpolationModifier:插值修改器,用于定义着色器的插值函数,应用于函数参数时,仅用像素着色器函数输入参数
  • Initializers:初始值

示例:

VS_OUTPUT RenderSceneVS( 
  float4 vPos : POSITION,
  float3 vNormal : NORMAL,
  float2 vTexCoord0 : TEXCOORD,
  uniform int nNumLights,
  uniform bool bTexture,
  uniform bool bAnimate )
{
  ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
3.3 返回值

参数形式如下:

return [value];
  • 1

参数说明:返回值可为一个或多个值

示例:

float4x4 WorldViewProj;

struct VS_OUTPUT
{
    float4 Pos  : POSITION;
};

VS_OUTPUT VertexShader_Tutorial_1(float4 inPos : POSITION )
{
    VS_OUTPUT out;
    out.Pos = mul(inPos, WorldViewProj );
    return out;
};

float4 func(float2 a: POSITION): COLOR
{
    return float4(sin(length(a) * 100.0) * 0.5 + 0.5, sin(a.y * 50.0), 0, 1);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
3.4 签名

着色器签名是着色器函数输入或输出的一个参数列表(通过语义来实现),输入签名由着色器输入声明产生,输出签名由着色器输出声明产生,若输出签名为输入签名的子集(声明类型及顺序相同),则称输入签名兼容输出签名。最简单的兼容方式便是让着色器的输入输出为相同结构体。

示例一:可兼容签名(官方给出的例子是输入签名输出签名的子集,官方给出的上面定义应该是写错了

// Vertex Shader Output Signature
Struct VSOut
{
  float4 Pos: SV_Position;
  float3 MyNormal: Normal;
  float2 MyTex : Texcoord0;
}

// Pixel Shader Input Signature
Struct PSInWorks
{
  float4 Pos: SV_Position;
  float3 MyNormal: Normal;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

示例二:非兼容签名

// Vertex Shader Output Signature
Struct VSOut
{
  float4 Pos: SV_Position;
  float3 MyNormal: Normal;
  float2 MyTex : Texcoord0;
}

// Pixel Shader Input Signature
Struct PSInFails
{
  float3 MyNormal: Normal;
  float4 Pos: SV_Position;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4 流程控制语句

HLSL的流程控制语句与C语言基本相似,支持以下流程控制语句:

  • break
  • continue
  • discard
  • do
  • for
  • if
  • switch
  • while

比较特殊的流程控制语句仅为discard语句:

  • 功能:当前结果不输出至当前像素点。

  • 备注:该语句只能像素着色器调用,不能被几何着色器或顶点着色器调用。

参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/837491
推荐阅读
相关标签
  

闽ICP备14008679号