着色器

From Valve Developer Community
< Zh
Revision as of 19:09, 18 March 2023 by BlueMicro (talk | contribs)
Jump to navigation Jump to search
English (en)Español (es)Русский (ru)Українська (uk)中文 (zh)Translate (Translate)

着色器是在 图形处理器(Graphics Processing Unit, GPU) 上运行的一套程序,用于确定应如何绘制对象。着色器替代了传统的固定渲染管线,可以实现图形计算中的渲染相关计算,由于其可编辑性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。着色器曾只存在于离线渲染(如 电影工业)领域,而实时渲染领域的着色器则是在 Microsoft 推出 Shader Model(着色器模型) 后才被首次引入。

  • Source 3D渲染中的所有内容都使用基于着色器绘制的方法
  • 着色器根据存储在 材质 文件中的参数进行进一步工作,看似简单,但里面存有非常复杂的来处理 实时阴影照明折射 等效果的配置信息。

类型

着色器(Shader)主要有顶点着色器(Vertex Shader)和像素着色器(Pixel Shader)两种

着色语言

目前有三种主要的着色器语言:高阶着色器语言(HLSL),C for Graphics (Cg) 和 OpenGL 着色语言(GLSL)。Source 使用基于 HLSL 的着色器。而且 Cg 与其也非常相似,故大多数 Cg 着色器都可以快速轻松地移植到 HLSL。

着色模型

Shader Model (以下简称 SM)是一种编程模型,直接地定义了如何使 GPU 运行高阶着色技术,同时可以防止太老的 GPU 运行新着色技术的程序。(防止显卡爆炸) Source 支持 SM 2.0(包括 PS 2.0b)和 SM 3.0. 其中 SM 3.0 是一次巨大飞跃,支持浮点精度运算,是现代高画质游戏的基石。因此 Source 的 shader 本身具有极强的拓展性。

Note.png注意:SM 3.0 的着色器可能无法在 macOS 和 Linux 系统上正常工作,因为 Valve 的转接层 (DirectX To OpenGL) togl只支持 SM 3.0 的部分特性,如果想要着色器正常工作,你应该考虑做一个 SM 2.0b 标准的着色器。
证实: 对于 vulkan_wrapper 的情况未知 ( Source 并不原生支持 Vulkan API, 只能通过 dxvk 进行转译。)
  • 为较新的 GPU 创建着色器时,请务必记住去支持那些较旧 GPU 用的着色器,否则这样会对老玩家产生很多限制。
  • 旧的 GPU 可能要“着色器回退 (shader fallbacks)”,如果新版SM用不了,那么游戏会使用旧版 SM。

像素着色器

每个被渲染的像素都与像素着色器有关。像素着色器需要来自顶点的插值输入,然后再用它来栅格化图像。像素着色器可以产生涉及单个像素颜色的大量效果,例如 折射逐像素照明反射 等等。

像素着色器 示例

这里我们提供一个像素着色器示例,可以在 Source 中使用。此着色器旨在用作 Post-processing (即 后处理) ,并创建灰度值。

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
// 指定纹理采样器 sampler2D Texture0 : register( s0 ); // 像素着色器返回像素的颜色值(所以这里是float4) float4 main( float2 texCoord  : TEXCOORD0 ) : COLOR { // 在指定的纹理坐标处对纹理进行采样 float4 tex = tex2D( Texture0, texCoord ); // 利用灰度信息得到像素的颜色值 // - 在像素颜色与指定矢量之间执行点积 // - 在图像处理过程中,对于灰度级有如下数值 ''0.222、0.707、0.071'' float4 grey = dot(float3(0.222, 0.707, 0.071), tex); // 以float4浮点数的形式返回像素颜色 return grey; }

顶点着色器

顶点着色器应用于 可编程管线(Programmable Pipeline) 上运作的每个 顶点(Vertex)。其最基本的功能是将几何体转换为 屏幕空间(Screen-Space) 坐标,以便 像素着色器 去栅格化图像。顶点着色器可以修改这些位置坐标以执行网格变形。它们还可以从 网格(Mesh) 接收其他信息,包括 法线、切线和纹理坐标 , 然后顶点着色器就执行写入 (输出寄存器) 操作,再然后,在像素着色器中的顶点之间对写入的值进行插值。注意!顶点着色器 无法创建或销毁顶点;它一次对单个顶点进行操作,将一个未处理的顶点作为输入并输出单个处理的顶点。

顶点着色器 示例

顶点着色器只是个搬运工, 它不会对顶点数据进行大改,只是会把数据送到像素着色器阶段罢了。

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
// 这个头文件提供一般顶点着色器的定义 #include "common_vs_fxc.h" // 定义输出结构 struct VS_OUTPUT { // 位置矢量 (float4) float4 pos  : POSITION0; // 纹理坐标(uv - float2) float2 texCoord  : TEXCOORD0; }; // 获取 ''位置矢量''(float4) // 返回 ''VS_OUTPUT'' VS_OUTPUT main( float4 inPos: POSITION ) { // 声明需补充的空的 VS_OUTPUT VS_OUTPUT o = (VS_OUTPUT) 0; // 计算 ''输入位置'' 的符号 inPos.xy = sign( inPos.xy); // 用 已输入的 xy 值来确定输出的位置值 o.pos = float4( inPos.xy, 0.0f, 1.0f); // 进入范围 [0,1] o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f; return o; }

着色器在起源引擎中的应用

Source 提供两种不同形式的着色器,分别是 后处理型逐对象型 ,Source 中的大多数特效和材质都非常非常依赖其像素着色器组件。

后处理

后处理着色器通常是在屏幕内已经渲染好的四边形的内容上工作的像素着色器。这些四边形会进一步被 Framebuffer 上的数据来被进行纹理处理,然后再送到像素着色器来进一步渲染,输出图元后再创建各种效果,比如把一些基础的颜色经过后处理管道来达到最佳效果,例如动态模糊(motion blur)和泛光(bloom)。

注:某些文件已不再包含在 SDK 中。

高级的后期处理着色器[如动态模糊(motion blur)和泛光(bloom)的着色器]可能还需要使用自定义 Rendertarget。有关将后处理着色器与模组集成的更多信息,请参阅 Custom_Postprocessing_Effects

逐对象

Source 中的逐对象着色器适用于具有 Valve 材质 (.vmt) 中引用的着色器的任何对象,比如 模型,笔刷 等。逐对象着色器可用于创建折射材质、动态地修改模型顶点或其他高级渲染效果。

Source SDK 同时也提供逐对象着色器的示例[在光照贴图(lightmap)里] (sdk_lightmap.cppsdk_lightmap_vs20.fxcsdk_lightmap_ps20.fxc)

扩展链接 / Reference

注释

本文具有时效性。原文一些已经无法使用的文件路径,介绍说明等已删除。