Effect & HLSL Guide – Semantics(十三)
本文版权归我所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,欢迎大家和我交流。
作者:clayman
Blog:http://blog.csdn.net/soilwork
clayman_joe@yahoo.com.cn
介绍HLSL或者DirectX / XNA的书中都很少会详细讲解Semantics,DirectX SDK对此也是草草带过,加上这个单词本身对汉语来说含义比较难懂,因此Semantics常常成了HLSL中鲜为人知的一部分。然而,对于构建复杂Effect系统来说,Semantics作为DirectX / XNA和shader之间传输数据的纽带,有相当重要的作用。
Semantics究竟是什么呢?简单来说,它是描述shader中变量的原数据,用来表示某个变量的语义。它与DirectX中D3DDECLUSAGE或者XNA中VertexElementUsage枚举的作用相当类似。
Semantics有什么用呢?Shader程序使用Semantics作为标记,实现数据从CPU到GPU的绑定。
为什么使用Semantics呢? 在Semantics出现之前,shader程序员常常直接使用寄存器名来绑定数据。这样做有两个缺点,首先,编译器无法对代码进行优化,其次,维护移植起来也相当不方便。Semantics隐藏了寄存器的复杂性,所有积存器的分配都由编译器来为你处理,同时,对外提供了一个统一的接口。
如何使用Semantics呢?先来看Semantics的语法:
[ Modifiers] ParameterType ParameterName [ : Semantic] = [ Initializers]
比如:
float4x4 WorldMatrix : WORLD;
冒号前面的部分,声明了一个变量myWorldMatrix,你也许希望用它来表示世界坐标变换。但是,编译器对此一无所知,只会把它当作一个普通的float4x4变量来对待。然而,添加了冒号以及标准Semantics WORLD之后,无论变量叫什么名字,编译器都会知道这个变量将被当作坐标变换矩阵来使用。注意,Semantics本身并不区分大小写,只是习惯上用大写表示。
从类型上来看,Semantics可以分为vertex/pixel semantics和普通变量semantics两种。
对于标记了vertex/pixel semantics值的变量来说,顶点会自动把vertex shader输入顶点或输出数据中相应的值绑定到变量上。
比如:
vs_main( float4 pos : Position, our float3 oColor : COLOR0){…}
Shader会自动把输入顶点中的位置信息绑定到pos变量上,此外
ps_main( float3 diffColor : COLOR0){…}
则会把vertex shader的输出颜色COLOR0绑定到diffColor变量。
对于普通变量semantics来说,则主要用来与外部数据进行绑定。在开发复杂Effect系统时,除非在开发先就有非常详细的变量命名规则,否则,程序将淹没在各种不同的Effect变量名间。每次调用Effect.SetValue()方法时,你都不得不查看HLSL代码中所用的具体变量名,这无疑是开发者的噩梦。然而,只要使用了semantics,这个问题就变的简单了。通过DirectX中的ID3DXBaseEffect::GetParameterBySemantic()或者XNA中的EffectParameterCollection.GetParameterBySemantic()方法,能轻易得到对应某个semantics的变量名,从而为它赋值,大大节约了开发时间。这也是ms推荐使用标准semantics的原因。
需要说明的是在DirectX中,似乎只列出了标准的vertex/pixel semantics,此外,还有相当数量的标准普通变量semantics,他们几乎涵盖了shader中所有可能用到的变量用法。
~~~~~~~~~~~~~~~~~~瞌睡的分隔线~~~~~~~~~~~~~~~~~
这是一篇迟到了太久的blog,已经有很长时间没有更新Effect & HLSL系统的内容了。不再翻译《 the complete effect and hlsl guide》,以后会挑选部分内容,或其他一些资料来写。下一次可能写一些关于Annotation的内容。
唉,上班真累,每天回家就不想动了,好多学习计划也被打乱,期待五一。