着色器
着色器(shader)应用于计算机图形学领域,指一组供计算机图形资源在执行渲染任务时使用的指令。程序员将着色器应用于图形处理器(GPU)的可编程流水线,来实现三维应用程序。这样的图形处理器有别于传统的固定流水线处理器,为GPU编程带来更高的灵活性和适应性。
目录 |
背景[编辑]
从技术的角度来看,着色器是渲染器的一个部分,它负责计算目标的颜色。
随着图形处理单元的进步,主要的图形软件库,像OpenGL和Direct3D都开始将目光投向更高阶的功能,即用着色器给新型的GPU编程,这就需要开发一系列的应用程序接口(API)满足着色功能。这样的改动出现在OpenGL的1.5版本和Direct3D的8版本。
着色器的种类[编辑]
Direct3D和OpenGL都使用了以下三种着色器:
- 顶点着色器处理每个顶点,将顶点的空间位置投影在屏幕上,即计算顶点的二维坐标。同时,它也负责顶点的深度缓冲(Z-Buffer)的计算。顶点着色器可以掌控顶点的位置、颜色和纹理坐标等属性,但无法生成新的顶点。顶点着色器的输出传递到流水线的下一步。如果有之后定义了几何着色器,则几何着色器会处理顶点着色器的输出数据,否则,光栅化器继续流水线任务。
- 几何着色器可以从多边形网格中增删顶点。它能够执行对CPU来说过于繁重的生成几何结构和增加模型细节的工作。Direct3D版本10增加了支持几何着色器的API, 成为Shader Model 4.0的组成部分。OpenGL只可通过它的一个插件来使用几何着色器,但极有可能在3.1版本中该功能将会归并。几何着色器的输出连接光栅化器的输入。
- 像素着色器(Direct3D),常常又称为片断着色器(OpenGL),处理来自光栅化器的数据。光栅化器已经将多边形填满并通过流水线传送至像素着色器,后者逐像素计算颜色。像素着色器常用来处理场景光照和与之相关的效果,如凸凹纹理映射和调色。名称片断着色器似乎更为准确,因为对于着色器的调用和屏幕上像素的显示并非一一对应。举个例子,对于一个像素,片断着色器可能会被调用若干次来决定它最终的颜色,那些被遮挡的物体也会被计算,直到最后的深度缓冲才将各物体前后排序。
统一着色器模型将上述三种着色器统一起来,发布于OpenGL和Direct3D 10里面。
由于这些类型的着色器终究会用在GPU的流水线中,下面简述它们是如何被安排在流水线中的。
简化图形流水线[编辑]
对于图形流水线的一般描述,参见图形流水线。
- 中央处理器(CPU)发送指令(编译的着色器程序)和几何数据到位于显卡内的图形处理器(GPU)。
- 顶点着色器执行几何变换和光照计算。
- 若几何着色器位于图形处理器内,它便会修改一些几何信息。
- 计算后的几何模型被三角化(分割为三角形)。
- 三角形被映射为2×2的像素块。
并行计算[编辑]
着色器被用来同时处理大量的数据,比如屏幕上的一整块像素群,或者一个模型结构的所有顶点。并行计算适用于这样的情况,而且当今的GPU也设计有多核结构来极大的提高处理效率。
对着色器编程[编辑]
OpenGL从版本1.5开始集成了一种类C语言的着色语言,称为OpenGL着色语言(GLSL)。同时NVidia也开发了Cg,其语法与GLSL类同。
在Direct3D里,着色器使用高级着色器语言(HLSL)。它的数据类型和允许的算法复杂程度因不同的版本而异。下表简述了Direct3D的不同版本:
| Direct3D 版本 | 像素着色器 | 顶点着色器 |
|---|---|---|
| 8.0 | 1.0, 1.1 | 1.0, 1.1 |
| 8.1 | 1.2, 1.3, 1.4 | 1.0, 1.1 |
| 9.0 | 2.0 | 2.0 |
| 9.0a | 2_A, 2_B | 2.x |
| 9.0c | 3.0 | 3.0 |
| 10.0 | 4.0 | 4.0 |
| 10.1 | 4.1 | 4.1 |
| 11 | 5.0 | 5.0 |
XNA中实现Shader[编辑]
XNA中实现Shader很简单。對XNA程式來說,Shader是一個小程式,只要把shader文件(.fx)导入到Contents 即可,會自动生成素材。再透過XNA Effect class 來加载和编译shader。HLSL可以在XNA或是DirectX使用。
舊版:
effect = Content.Load("MyShader");
effect.CurrentTechnique = effect.Techniques ["AmbientLight" ];
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
...
pass.End();
}
effect.End(); // 終止使用 effect
新版(4.0):
effect = Content.Load("MyShader");
effect.CurrentTechnique = effect.Techniques ["AmbientLight" ];
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
...
}
外部链接[编辑]
- Geometry shader tutorial
- nVidia releases a new programming environment and language compiler specifically for writing science applications that run on the shader units of its graphics cards. Also see developer's home page.
- OpenGL geometry shader extension
参见[编辑]
- GLSL: OpenGL Shading Language @ Lighthouse 3D - GLSL Tutorial
- Steve Upstill: The RenderMan Companion: A Programmer's Guide to Realistic Computer Graphics, Addison-Wesley, ISBN 0-201-50868-0
- David S. Ebert, F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, Steven Worley: Texturing and modeling: a procedural approach, AP Professional, ISBN 0-12-228730-4. Ken Perlin is the author of Perlin noise, an important procedural texturing primitive.
- Randima Fernando, Mark Kilgard. The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics, Addison-Wesley Professional, ISBN 0-321-19496-9
- Randi J. Rost: OpenGL Shading Language, Addison-Wesley Professional, ISBN 0-321-19789-5
- Riemer's DirectX & HLSL Tutorial: HLSL Tutorial using DirectX with lots of sample code
- GPGPU: general purpose GPU
- MSDN: Pipeline Stages (Direct3D 10)
引用[编辑]
- ^ Search ARB_shader_objects for the issue "32) Can you explain how uniform loading works?". This is an example of how a complex data structure must be broken in basic data elements.
- ^ Required machinery has been introduced in OpenGL by ARB_multitexture but this specification is no more available since its integration in core OpenGL 1.2.
- ^ Search again ARB_shader_objects for the issue "25) How are samplers used to access textures?". You may also want to check out "Subsection 2.14.4 Samplers".