着色器

维基百科,自由的百科全书
跳转至: 导航搜索

着色器英语shader)应用于计算机图形学领域,指一组供计算机图形资源在执行渲染任务时使用的指令。程序员将着色器应用于图形处理器(GPU)的可编程流水线,来实现三维应用程序。这样的图形处理器有别于传统的固定流水线处理器,为GPU编程带来更高的灵活性和适应性。

背景[编辑]

从技术的角度来看,着色器是渲染器的一个部分,它负责计算目标的颜色。

随着图形处理单元的进步,主要的图形软件库,像OpenGLDirect3D都开始将目光投向更高阶的功能,即用着色器给新型的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();
 ... 
 }

外部链接[编辑]

参见[编辑]

引用[编辑]

  1. ^ 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.
  2. ^ 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.
  3. ^ 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".