Unity Shader 学习笔记 (八) 语义词与语义绑定

Unity Shader 学习笔记 (八) 语义词与语义绑定


输入\输出修辞符(in\out\inout)

参数传递

参数传递是指:函数调用实参值初始化函数形参的过程。在C\C++中,根据形参值的改变是否会导致实参值的改变,参数传递分为“值传递(pass-by-value)”
和“引用传递(pass-by-reference)”。按值传递时,函数不会访问当前调用的实参,函数体处理的是实参的拷贝,也就是形参,所以形参值的改变不会影响实参值;
引用传递时,函数接收的是实参的存放地址,函数体中改变的是实参的值。C\C++采取指针机制构建引用传递,所以通常引用传递也称为“指针传递”。

Cg 语言中参数传递的方式

Cg 语言中参数传递方式同样分为“值传递”和“引用传递”,但指针机制并不被GPU 硬件所支持,所以Cg 语言采用不同的语法修辞符来区别“值传递”和“引用传递”。这些修辞符分别为:

1. in: 修辞一个形参只是用于输入,进入函数体时被初始化,且该形参值的改变不会影响实参值,这是典型的值传递方式。
2. out: 修辞一个形参只是用于输出的,进入函数体时并没有被初始化,这种类型的形参一般是一个函数的运行结果;
3. inout: 修辞一个形参既用于输入也用于输出,这是典型的引用传递。

举例如下:

void myFunction(out float x); //形参x,只是用于输出
void myFunction(inout float x); //形参x,即用于输入时初始化,也用于输出数据
void myFunction(in float x); //形参x,只是用于输入
void myFunction(float x); //等价与 in float x,这种用法和C\C++完全一致也可以使用return 语句来代替out 修辞符的使用。输入\输出修辞符通常和语义词一起使 //用,表示顶点着色程序和片段着色程序的输入输出。

语义词和语义绑定的概念

语义词,表示输入图元的数据含义(是位置信息,还是法向量信息),也表明这些图元数据存放的硬件资源(寄存器或者纹理缓冲区)。顶点着色程序和片段着色程序中Varying inputs 类型的输入,必须和一个语义词相绑定,这称之为 绑定语义(binding semantics)。

语义,分为输入语义和输入语义;输入语义和输出语义是有区别的。虽然一些参数经常会使用相同的绑定语义词,例如:顶点Shader 的输入参数,POSITION指应用程序传入的顶点位置,而输出参数使用POSITION 语义就表示要反馈给硬件光栅器的裁剪空间位置,光栅器把POSITION 当成一个位置信息。虽然两个语义都命名为POSITION,但却对应着图形流水线上不同的寄存器。

顶点着色程序的输入语义

下面这组绑定语义关键字被Cg 语言的所有vertex profile 所支持
POSITION 
BLENDWEIGHT
NORMAL 
TANGENT
BINORMAL 
PSIZE
BLENDINDICES 
TEXCOORD0---TEXCOORD7

举例如下:
in float4 modelPos: POSITION
in float4 modelNormal: NORMAL

下面这些语义词适用于所有的Cg vertex profiles作为输出语义和Cg fragment profiles的输入语义:
POSITION
PSIZE
FOG
COLOR0-COLOR1
TEXCOORD0-TEXCOORD7

片段着色程序的输入语义

片段着色程序的输出语义词较少,通常是COLOR。这是因为片段着色程序运行完毕后,就基本到了GPU流水线的末端了。 片段程序必须声明一个out向量
(三元或四元),绑定语义词COLOR,这个值将被用作该片断的最终颜色值。

语义绑定方法

1. 绑定语义放在函数的参数列表的参数声明后面中:

[const] [in | out | inout]<type><identifier> [ :
<binding-semantic>][=<initializer>]
其中,const 作为可选项,修辞形参数据;in、out、inout 作为可选项,说明数据的调用方式;type 是必选项,声明数据的类型;identifier 是必选项,形参变量名;一个冒号“:”加上一个绑定语义,是可选项;最后是初始化参数,是可选项。如下代码所示。形参列表中的参数一、参数二绑定到输入语义;参数三、参数四绑定到输出语义;尽管参数一和参数3 的绑定语义词一样,但前者是输入语义,后者是输出语义,所以这两个参数数据所对应的硬件位置是不一样的。

void mian_v(float4 position_obj : POSITION,
float3 normal_obj : NORMAL,
out float4 oPosition : POSITION,
out float4 oColor : COLOR,
uniform float4x4 modelViewProj)
{
………………
}



2. 绑定语义可以放在结构体(struct)的成员变量后面:

struct <struct-tag>
{
<type><identifier> [:<binding-semantic >];
};


举例如下,结构C2E1v_Outpu 中的2 个成员变量分别绑定到语义POSITION
和COLOR,然后在C2E1v_green 顶点程序入口函数中输出,所以C2E1v_Outpu
中的语义是输出语义。
struct C2E1v_Output {
float4 position : POSITION;
float3 color : COLOR;
};
C2E1v_Output C2E1v_green(float2 position : POSITION)
{
C2E1v_Output OUT;
OUT.position = float4(position,0,1);
OUT.color = float3(0,1,0);
return OUT;
}


3. 绑定语义词可以放在函数声明的后面,其形式为:


<type> <identifier> (<parameter-list>) [:<binding-semantic]
{
<body>
}
如下代码所示,顶点入口函数的声明后带有“COLOR”语义词,表示该函
数需要反馈一个颜色值,所以函数的返回类型为float4,函数体也必须以return
语句结束。
float4 main_v(float4 position: POSITION,
out float4 oposition : POSITION,
uniform float4x4 modelViewProj):COLOR
{
oposition = mul(modelViewProj,position);
float4 ocolor = float4(1.0,0,0,0);
return ocolor;
}


你可能感兴趣的:(Unity Shader 学习笔记 (八) 语义词与语义绑定)