第一部分:可编程着色器
早期的着色器模型(shader model)只支持底层汇编语言,而且顶点着色器的指令集和寄存器集和像素着色器有很大区别。
DX9时代带来了高级的,近似c语言的着色语言。例如CG、HLSL、GLSL等。
DX10引进了几何着色器,并带来了统一着色器架构,其DirectX术语为着色器模型4.0。在此统一着色器模型中,3种着色器支持差不多相同的指令集,以及差不多的能力,这些能力包含读取纹理内存。
1.内存访问
由于GPU实现了数据处理管道,必须非常谨慎地控制内存访问。着色器程序不能直接读写内存。取而代之,其内存访问只限于两种方式:寄存器和纹理。
GPT:对独立显卡来说,一般只能访问显存(VRAM)。纹理顶点数据需要先从主存上传到显存,之后着色器程序才能访问。
着色器寄存器:
着色器可用寄存器间接存取内存。
所有GPU寄存器是128位SIMD格式。每个寄存器能保存4个32位浮点数或者4个32位整数。
矩阵可由3个寄存器或4个寄存器表示。(cg中的float4x4类型)
GPU寄存器可以用来保存单个32位标量,通常会把该值复制到所有4个32位字段。
有些GPU能在16位字段上运算,称为half类型。
- ▷寄存器种类:
- 输入寄存器(input register):是着色器的主要数据来源。在顶点着色器中,输入寄存器含有顶点的属性数据,。在像素着色器中,输入寄存器含有对应某片段的顶点属性插值数据。在调用着色器之前,GPU会自动设置这些输入寄存器的值。
- 常数寄存器(constant register):常数寄存器的值是由应用程序设置的,应用程序按不同图元会设置不同的值。所谓”常数”是对于着色器而言的。其典型内容有模型观察矩阵、投影矩阵、光照参数等着色器需要的输入。
- 临时寄存器(trmporary register):临时寄存器只供着色器程序内部使用,通常用于存储中间计算结果。
- 输出寄存器(output register): 这些寄存器的内容由着色器填充,作为着色器仅有的输出形式。
当提交几何图元渲染时,应用程序要提供常数寄存器的值。在调用着色器程序之前,GPU会从显存自动复制顶点或片段属性数据至适当的输入寄存器。当程序执行完毕时,GPU会把输出寄存器写入显存,使数据能给予下个管道阶段。
GPU通常会把输出数据存储至缓存,使这些数据能重用而不需要重新计算。例如变换后顶点缓存(post-transform vertex cache)是用来存储顶点着色器最近处理过的结果。如果某三角形刚好引用到之前处理过的顶点,那么可行的话GPU就会读取变换后的顶点缓存。
纹理:
着色器也能够直接读取纹理。纹理数据是以纹理坐标寻址的,而不是使用绝对内存地址。GPU的纹理采样器会自动过滤纹理数据,适当地混合相邻纹素以及相邻Mipmap级数的值。
也可以关上纹理过滤,以直接存取某纹素的值。当纹理作为查找表之用时,关上纹理过滤就很有用。
着色器只能用间接方法写数据进纹理-把场景渲染至屏幕外帧缓冲。此功能称为渲染到纹理(render to texture)。
2.高级着色器语言入门
寄存器映射:
高级着色器语言如cg和glsl都仿照了C语言来制定。在cg或者glsl定义的struct及变量都会由着色器编译器把它们直接映射到寄存器。
定义这些映射的方法:
-
语义(semantic):在变量或者struct成员之后加冒号和名为语义的关键词。语义告诉编译器如何把变量或者数据成员绑定至个别顶点或者片段属性。
-
输入和输出:编译器会根据使用个别变量或struct的上下文,判断它们应映射至输入或输出寄存器。如果变量是以参数形式传入着色器主函数,那么就会当作输入。如果是返回值,那么就会当作输出。
-
uniform声明:要从应用程序常数寄存器取得数据,可以在声明变量时加入
uniform
关键字。(uniform声明可以用于函数参数)
内部函数:
除了C风格的运算符外,还可以使用内部函数(intrinsic)。例如矩阵变换函数、纹理采样函数等。
效果文件(CRE:着色器的封装)
除了着色器程序之外,GPU管道还需要一些额外信息(例如应用程序参数如何映射至uniform变量、渲染步骤、回退信息等),才能为着色器程序调用提供有意义的输入。我们可以使用名为效果文件(effect file)的的文件格式。
Cg里面效果文件格式为CgFX。
OGRE采用和CgFX类似的格式,名为材质文件(material file)。
GLSL使用XML格式的COLLADA文件描述效果。
CRE:Unity的ShaderLab+材质能看作一种效果文件,是对着色程序的封装。
- ⚪效果文件会使用以下层次结构:
- 在全局作用域定义struct、着色器程序(实现为多个主函数)、全局变量(映射至应用程序相关的常数参数)。
- 定义一个或多个技术(technique),每个技术代表渲染某视觉效果的方法。一个效果通常提供一个主要技术作为效果最高品质实现,另外再加上多个回退(fallback)供低级图形硬件使用。
- 每个技术内定义一个或多个渲染步骤(pass)。每个步骤描述如何渲染一整帧影像。通常一个步骤包含顶点/几何/片段着色器程序的main函数引用、多个参数绑定及可选的渲染状态设置。
(END)