Code Knight

Programming is so cool
随笔 - 52, 文章 - 0, 评论 - 14, 引用 - 0
数据加载中……

shader小综

注明:摘自七星重剑的BLOG
纹理(Texture)&取样器(Sampler)

这 俩东西可以看作特殊类型变量。纹理就是Shader中用到的贴图资源,这我想没什么好说的。来解释一下取样器:实际上每张贴图在使用的时候都要用一个取样 器。取样器相当于这样一个结构,除了保存贴图本身数据之外,还包括过滤参数等取样信息。通常,读取贴图这样的指令接收的都是取样器类型的参数而并非直接接 收纹理贴图。声明及使用纹理或取样器跟使用普通变量一样。这里有一些初始化取样器的方法,还是等到后面的实例中讲述吧。

Semantic & Annotation

任 何类型的变量(包括纹理和取样器),我们都可以用Semantic或Annotation修饰来起到一些特殊作用。Semantic暂时翻译成语义; Annotation暂时翻译成注解,这是HLSL中独特的东西。下面这两行中,第一个变量冒号后面的POSITION就是Semantic,第二个变量 后面用一对尖括号<>圈起来的表达式就是Annotation,一组<>中可以有很多个表达式。
float3 OmniPos : POSITION;
texture TexMap < string name = "test.dds"; >;

一般来讲,Semantic是告诉应用程序或D3D这个被修饰的变量是做什么用的,Annotation是告诉程序这个变量怎么用。 很云山雾罩是吗,是这样,在应用程序代码中,是可以调用D3D的API认出Semantic和Annotation的。例如上面这两行,程序的逻辑就可能 是这样:首先写主程序的甲和写Shader的乙约定好POSITION标识该变量代表灯泡A的位置,甲在程序里写:{灯泡A.位置 = XXX; 找到Shader中带POSITION的变量; 给该变量赋值为灯泡A.位置; return;} 那么甲可以不知道乙在Shader中给这个要用灯泡A位置的变量起了什么名,而且乙可以在好几个Shader中给用这个数据的变量起不同的名。然后,甲和 乙再约定遇到Annotation中的“name”就将后面的字符串作为文件名建立贴图。于是甲的程序就从Shader中读出了一个文件名,建立了一个贴 图以供这个texture变量使用。Semantic和Annotation大概就这么用,首先要约定好各个Semantic和Annotation都是 什么意思,这是up to you的,然后就是通过它们的标识来给变量赋值或作其他辅助性工作了。

既然都是做辅助说明的为什么还要分成Semantic和Annotation,我的想法是Semantic简单方便而Annotation能干的事更多。不说这个了,无关大局。要说的是,D3D也跟我们约定了一套Semantic,它们大体上都能顾名思义,控制流

控 制流,就是if…else,for,while什么的。在CPU中,这些控制流造成的实际上是指令跳转。但在GPU中指令跳转并不被广泛的支持,以往的大 部分显卡只懂得按顺序一句一句执行指令。因此HLSL的编译器可能会做出诸如展开循环、遍历分支等等莽撞的事来适应显卡。所以使用时要特别小心,而且不是 所有情况的控制流语句都被支持。

函数

HLSL 中提供了很多函数可供调用,在Direct3D 文档 -> DirectX Graphics -> Reference -> HLSL Shader Reference -> HLSL Intrinsic Functions中有这些函数的详细列表。也可自己写函数用,但是在较早的Shader版本中,就像内联函数一样编译时最终要将函数展开插入到函数调用 处。还有一点我想你一定会想到的就是主函数会是什么。Vertex Shader和Pixel Shader各自需要一个主函数,由程序员来指定!没错,程序员在Shader外部指定。

posted on 2009-12-27 22:17 Code Knight 阅读(357) 评论(1)  编辑 收藏 引用 所属分类: 图形学

评论

# re: shader小综  回复  更多评论   

很好的文章,简单明了
2009-12-28 00:34 | Davy.xu

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理