Shader入门学习记录④——Unity提供的CG/HLSL的语义

1. 什么是语义

	我们可以在unity创建的默认Shader中经常看到,SV_POSITION、POSITION、COLOR0等,这些大写的字母就是
CG/HLSL提供的语义。
	通俗来讲,这些语义可以让Shader知道从哪里读取数据,并吧数据输出到哪里,在CG/HLSL的shader流水线中是
不可或缺的。需要注意的是,Unity并没有支持所有的语义。通常情况下,输入输出这些变量并不需要特别的意义,也
就是说,我们可以自行解决这些变量的用途。顶点着色器的输出结构中我们用COLOR0语义去描述color变量,color变
量本身存储什么,Shader并不关心。
	然而Unity为了方便对模型数据的传输,对一些语义进行了特别的含义规定。例如,在顶点着色器的输入结构体
a2f用TEXCOORD0来描述texcoord,Unity会识别TEXCOORDO语义,以把模型的第一组纹理坐标填充到texcoord
中。需要注意的是,即使语义的名称一样,如果出现的位置不同,含义也不同。例如TEXCOORD0既可以用于描述
顶点着色器的输入结构体,也可以用于描述输出结构体。但在输入结构体中,TEXCOORD0有特别的含义,即把模型
的第一组纹理坐标存储在该变量中,而在输出结构体中,TEXCOORD0修饰的变量含义就可以由我们来决定。

2. SV 类语义

在DirectX10 以后,有了一种新的语义类型,就是 系统数值语义。这类语义是以SV开头的,SV代表的含义就是系统
数值。这些语义在渲染流水线中有特殊的含义,例如我们使用SV_POSITION 语义去修饰顶点着色器的输出变量pos,
那么就表示pos包含了可用于光栅化的变化后的顶点坐标(即齐次裁剪空间中的坐标)。用这些语义描述的变量是不
可以随意赋值的,因为流水线需要使用它们来完成特定的目的,例如渲染引擎会把用SV_POSITION 修复的变量经过
光栅化显示在屏幕上。又可以会看到用一个变量在不同的Shader里面使用了不同的语义修饰。例如,一些Shader 会
使用POSITION 而非SV_POSITION来修饰输出。SV_POSITION 是 DirectX 10中引入的系统数值语义,在绝大数平
台上,它和 POSITION 是等价的,但在某些平台(如索尼PS4)上必须使用SV_POSITION 来修饰着色器的输出,否
则无法让Shader正常工作。同样的例子还有COLOR 和 SV_Target。因为,为了让我们的Shader有更好的跨平台性,
对于这些有特殊含义的变量我们最好使用以SV开头的语义进行修饰。

3. Unity支持的语义

表1. 1 从应用阶传递模型数据给顶点着色器是Unity支持的常用语义
语义描述
POSITION模型空间中的顶点位置,通常是float4类型
NORMAL顶点法线,通常是float3类型
TANGENT顶点切线,通常是float4类型
TEXCOORDn该顶点的纹理坐标,TEXCOORD0 表示第一组纹理坐标,以此类推。通常是float2或者float4类型
COLOR顶点颜色,通常是fixed4或者float4类型
表 1. 2 从顶点着色器传递数据给片元着色器是Unity使用的常用语义
语义描述
SV_POSITION裁剪空间中的顶点坐标,结构体中必须包含一个用该语义修饰的变量。等同于DIrectX9中的POSITION,但最好使用SV_POSITION
COLOR0通常用于输出第一组顶点颜色,但不是必需的
COLOR1通常用于输出第二种顶点颜色,但不是必需的
TEXCOORD0~TEXCOORD7通常用于输出纹理坐标,但不是必需的

上面的语义中,除了SV_POSITION是有特殊含义外,其他语义对变量的含义没有明确要求,也就是说,我们可以存储任意值到这些语义描述变量中。通常,如果我们需要把一些自定义的数据从顶点着色器传递给片元着色器,一般选用TEXCOORD0等。

表 1. 2 Unity支持的片元着色器的输出语义
语义描述
SV_Target输出值将会存储到渲染目标中,等同于DIrectX9 中的 COLOR 语义,但最好使用 SV_Target

4. 关于结构体的定义

struct v2f{
	float4 pos :SV_POSITION;
	fixed3 color0 : COLOR0;
	fixed4 color1 : COLOR1;
	half value0 : TEXCOORD0;
	float2 value1 : TEXCOORD1;
}

需要注意的是,一个语义可以使用的寄存器只有能处理4个浮点数(float)。因此,如果我们想要定义矩阵类型,如果float34、float44等变量就需要使用更多的空间。一种方法是,把这些变量拆分成多个变量,例如对于float4*4的矩阵类型,我们可以拆分成4个float4类型的变量,每个变量存储了矩阵的一行数据。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值