着色器

计算机图形学领域中，着色器（）是一种计算机程序，原本用于进行图像的浓淡处理（计算图像中的光照、亮度、颜色等），但近来，它也被用于完成很多不同领域的工作，比如处理CG特效、进行与浓淡处理无关的、甚至用于一些与计算机图形学无关的其它领域。

使用着色器在图形硬件上计算渲染效果有很高的自由度。尽管不是硬性要求，但目前大多数着色器是针对GPU开发的。GPU的可编程绘图管线已经全面取代传统的固定管线，可以使用着色器语言对其编程。构成最终图像的像素、顶点、纹理，它们的位置、色相、饱和度、亮度、对比度也都可以利用着色器中定义的算法进行动态调整。调用着色器的外部程序，也可以利用它向着色器提供的外部变量、纹理来修改这些着色器中的参数。

在电影后期处理、计算机成像、电子游戏等领域，着色器常被用来制作各种特效。除了普通的光照模型，着色器还可以调整图像的色相、饱和度、亮度、对比度，生成模糊、高光、有体积光源、失焦、卡通渲染、色調分離、畸变、凹凸贴图、色键（即所谓的蓝幕、绿幕抠像效果）、边缘检测等效果。

历史 
1988年5月，Pixar公布了第三版RenderMan规范，将「着色器」的使用推广到了我们目前所知的各大应用领域。

随着图形处理器的进步，OpenGL和Direct3D等主要的图形软件库都开始支持着色器。第一批支持着色器的 GPU 仅支持像素着色器，但随着开发者逐渐认识到着色器的强大，很快便出现了顶点着色器。2000年，第一款支持可编程像素着色器的显卡 Nvidia GeForce 3（NV20）问世。Direct3D 10 和 OpenGL 3.2 则引入了几何着色器。

目前，图形硬件正在朝发展。

设计 
着色器是描述顶点或像素特征的简单程序。顶点着色器描述顶点的属性（位置、纹理坐标、颜色等），而像素着色器描述像素的特征（颜色、z深度和alpha值）。

基本图形管线如下所示：
 中央处理器（CPU）发送指令(已编译的着色器程序)和几何数据到位于显卡内的图形处理器（GPU）。
 顶点着色器执行几何变换。
 若几何着色器位于图形处理器内并已激活，它便会修改一些场景中的几何结构。
 若细分着色器位于图形处理器内并已激活，场景中的几何结构会被细分。
 计算后的几何结构被三角化（分割为三角形）。
 三角形被分解为2 × 2的像素块。
 像素块通过片段着色器被修改。
 进行深度测试；通过的片段将被写入屏幕，并可能被混合到帧缓冲区中。

种类 
常用的着色器有三种。比较老的显卡倾向于使用不同的处理单元处理不同类型的着色器，但新出的显卡通常都支持，可以执行任意类型的着色器、更好地发挥显卡的处理能力。

二维着色器 
二维着色器处理的是数字图像，也叫纹理，着色器可以修改它们的像素。二维着色器也可以参与三维图形的渲染。目前只有「像素着色器」一种二维着色器。

像素着色器 

像素着色器（）也叫片段着色器（），用于计算「片段」的颜色和其它属性，此处的「片段」通常是指单独的像素。最简单的像素着色器只有输出颜色值；复杂的像素着色器可以有多个输入输出。像素着色器既可以永远输出同一个颜色，也可以考虑光照、做凹凸贴图、生成阴影和高光，还可以实现半透明等效果。像素着色器还可以修改片段的深度，也可以为多个渲染目标输出多个颜色。

三维图形学中，单独一个像素着色器并不能实现非常复杂的效果，因为它只能处理单独的像素，没有场景中其它几何体的信息。不过，像素着色器有屏幕坐标信息，如果将屏幕上的内容作为纹理传入，它就可以对当前像素附近的像素进行采样。利用这种方法，可以实现大量二维后期特效，例如模糊和边缘检测。

像素着色器还可以处理管线中间过程中的任何二维图像，包括精灵和纹理。因此，如果需要在栅格化后进行后期处理，像素着色器是唯一选择。

三维着色器 
三维着色器处理的是三维模型或者其它几何体，可以访问用来绘制模型的颜色和纹理。顶点着色器是最早的三维着色器；几何着色器可以在着色器中生成新的顶点；细分曲面着色器（）则可以向一组顶点中添加细节。

顶点着色器 
顶点着色器是最常见的一种 3D 着色器，对每个交给图形处理器的顶点都运行一次。目的是将每个顶点在虚拟空间中的 3D 坐标变换到在屏幕上显示的 2D 坐标（深度缓冲（Z-Buffer）的深度值也是如此）。顶点着色器可以掌控顶点的位置、颜色和纹理坐标等属性，但无法生成新的顶点。顶点着色器的输出传递到流水线的下一步。如果有之后定义了几何着色器，则几何着色器会处理顶点着色器的输出数据，否则，光栅化器继续流水线任务。

几何着色器 
几何着色器在 OpenGL 3.2 和 Direct3D 10 中被引入, 以前可在带扩展的 OpenGL 2.0+ 中使用。改类型的着色器可以生成新的图形基元，比如点，线和三角形。几何着色器可以从多边形网格中增删顶点。它能够执行对 CPU 来说过于繁重的生成几何结构和增加模型细节的工作。Direct3D 10 增加了支持几何着色器的API，成为 Shader Model 4.0 的组成部分。OpenGL 只可通过它的一个插件来使用几何着色器，但极有可能在3.1版本中该功能将会归并。几何着色器的输出连接光栅化器的输入。

曲面细分着色器 

曲面细分着色器作為一類新的著色器，在 OpenGL 4.0 和 Direct3D 11 中被引入，並在著色器的模型增加了兩個階段：曲面細分控制著色器(或外殼著色器)和曲面細分評估著色器(或域著色器)。這允許了較簡單的網格藉由特定函式計算，實時被細分成更細膩的網格。這個函示可以與多種變數相關，包含與視點的距離，因此可以主動調整細節層次，使較接近相機的物體有著較多細節。藉由在著色器單元中才加上細節，這還可以大幅降低網格所需的頻寬，也不需要降採樣記憶體中的網格。有些計算方式可以上採樣任意的網格，有些則允許「提示」網格所要凸顯的頂點和邊緣。

图元和网格着色器 
大约 2017 年, 图元着色器做为新的着色器阶段被 AMD Vega 微体系结构所支持。类似可以访问必要数据的计算着色器来处理几何体。

光线追踪着色器 
光线追踪着色器被微软的 DirectX 光线追踪，Khronos Group 的 Vulkan，GLSL 和 SPIR-V，苹果的 Metal 所支持。

计算着色器 
计算着色器并不仅限于图形应用程序，还有使用相同的通用图形处理单元执行资源的程序。它们可能在图形管线中被使用，比如额外的动画阶段或光照算法。 一些渲染 API 允许计算着色器轻松的与图形管线共享数据资源。

并行处理 
着色器被用来同时处理大量的数据，比如屏幕上的一整块像素群，或者一个模型结构的所有顶点。并行计算适用于这样的情况，而且当今的GPU也设计有多核结构来极大的提高处理效率。

编程 
用于编写着色器的编程语言取决于目标环境。官方的OpenGL和OpenGL ES着色语言是OpenGL着色语言，也称为GLSL，官方的Direct3D着色语言是高级着色器语言，也称为HLSL。Cg是英伟达开发的第三方着色语言，可输出OpenGL和Direct3D着色器；然而，自2012年以来，它一直被弃用。苹果发布了自己的着色语言，称为Metal着色语言，作为Metal框架的一部分。

GUI 着色器编辑器 
现代电子游戏开发平台，如 Unity，Unreal Engine 和 Godot 越来越多的包含了基于节点的编辑器，允许创建着色器而无需编写实际的代码。向用户展现了包含相互连接的节点的有向图，允许用户将各种各样的纹理，映射和数学函数直接导向输出值，如漫反射颜色，高亮和强度，金属度/粗糙度，高度，法向量等。自动将这些图编译为实际的已编译的着色器。

另见 
 GLSL
 SPIR-V
 HLSL
 着色器语言
 GPGPU

参考资料

拓展阅读 
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)

外部链接 
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

计算机图形学