着色器

计算机图形学领域中，着色器（英語：shader）是一种计算机程序，原本用于进行图像的浓淡处理（计算图像中的光照、亮度、颜色等），但近来，它也被用于完成很多不同领域的工作，比如处理CG特效、进行与浓淡处理无关的影片后期处理（英语：video post-processing）、甚至用于一些与计算机图形学无关的其它领域。 使用着色器在图形硬件上计算渲染效果有很高的自由度。尽管不是硬性要求，但目前大多数着色器是针对GPU开发的。GPU的可编程绘图管线已经全面取代传统的固定管线，可以使用着色器语言对其编程。构成最终图像的像素、顶点、纹理，它们的位置、色相、饱和度、亮度、对比度也都可以利用着色器中定义的算法进行动态调整。调用着色器的外部程序，也可以利用它向着色器提供的外部变量、纹理来修改这些着色器中的参数。 在电影后期处理、计算机成像、电子游戏等领域，着色器常被用来制作各种特效。除了普通的光照模型，着色器还可以调整图像的色相、饱和度、亮度、对比度，生成模糊、高光、有体积光源、失焦、卡通渲染、色調分離、畸变、凹凸贴图、色键（即所谓的蓝幕、绿幕抠像效果）、边缘检测等效果。 1988年5月，Pixar公布了第三版RenderMan规范，将「着色器」的使用推广到了我们目前所知的各大应用领域。 随着图形处理器的进步，OpenGL和Direct3D等主要的图形软件库都开始支持着色器。第一批支持着色器的 GPU 仅支持像素着色器，但随着开发者逐渐认识到着色器的强大，很快便出现了顶点着色器。2000年，第一款支持可编程像素着色器的显卡 Nvidia GeForce 3（NV20）问世。Direct3D 10 和 OpenGL 3.2 则引入了几何着色器。 目前，图形硬件正在朝统一着色器模型（英语：Unified shader model）发展。 着色器是描述顶点或像素特征的简单程序。顶点着色器描述顶点的属性（位置、纹理坐标、颜色等），而像素着色器描述像素的特征（颜色、z深度和alpha值）。 基本图形管线如下所示： 中央处理器（CPU）发送指令(已编译的着色器程序)和几何数据到位于显卡内的图形处理器（GPU）。 顶点着色器执行几何变换。 若几何着色器位于图形处理器内并已激活，它便会修改一些场景中的几何结构。 若细分着色器位于图形处理器内并已激活，场景中的几何结构会被细分。 计算后的几何结构被三角化（分割为三角形）。 三角形被分解为2 × 2的像素块。 像素块通过片段着色器被修改。 进行深度测试；通过的片段将被写入屏幕，并可能被混合到帧缓冲区中。 常用的着色器有三种。比较老的显卡倾向于使用不同的处理单元处理不同类型的着色器，但新出的显卡通常都支持统一着色器模型（英语：Unified shader model），可以执行任意类型的着色器、更好地发挥显卡的处理能力。 二维着色器处理的是数字图像，也叫纹理，着色器可以修改它们的像素。二维着色器也可以参与三维图形的渲染。目前只有「像素着色器」一种二维着色器。 像素着色器（英語：pixel shader）也叫片段着色器（英語：fragment shader），用于计算「片段」的颜色和其它属性，此处的「片段」通常是指单独的像素。最简单的像素着色器只有输出颜色值；复杂的像素着色器可以有多个输入输出。像素着色器既可以永远输出同一个颜色，也可以考虑光照、做凹凸贴图、生成阴影和高光，还可以实现半透明等效果。像素着色器还可以修改片段的深度，也可以为多个渲染目标输出多个颜色。 三维图形学中，单独一个像素着色器并不能实现非常复杂的效果，因为它只能处理单独的像素，没有场景中其它几何体的信息。不过，像素着色器有屏幕坐标信息，如果将屏幕上的内容作为纹理传入，它就可以对当前像素附近的像素进行采样。利用这种方法，可以实现大量二维后期特效，例如模糊和边缘检测。 像素着色器还可以处理管线中间过程中的任何二维图像，包括精灵和纹理。因此，如果需要在栅格化后进行后期处理，像素着色器是唯一选择。 三维着色器处理的是三维模型或者其它几何体，可以访问用来绘制模型的颜色和纹理。顶点着色器是最早的三维着色器；几何着色器可以在着色器中生成新的顶点；细分曲面着色器（英語：tessellation shader）则可以向一组顶点中添加细节。 顶点着色器是最常见的一种 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框架的一部分。 现代电子游戏开发平台，如 Unity，Unreal Engine 和 Godot 越来越多的包含了基于节点的编辑器，允许创建着色器而无需编写实际的代码。向用户展现了包含相互连接的节点的有向图，允许用户将各种各样的纹理，映射和数学函数直接导向输出值，如漫反射颜色，高亮和强度，金属度/粗糙度，高度，法向量等。自动将这些图编译为实际的已编译的着色器。 GLSL SPIR-V HLSL 着色器语言 GPGPU Best Practices Memo. Cra.org. [2014-05-01]. （原始内容存档于2014-05-02）.  The RenderMan Interface Specification. （原始内容存档于2019-06-16）.  Pipeline Stages (Direct3D 10) (Windows). msdn.microsoft.com. [2021-09-15]. （原始内容存档于2010-05-21）.  存档副本. [2018-06-25]. （原始内容存档于2021-04-24）.  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