Zh/Shader: Difference between revisions

From Valve Developer Community
< Zh
Jump to navigation Jump to search
No edit summary
m (obsolete language category)
 
(90 intermediate revisions by 5 users not shown)
Line 1: Line 1:
着色器是在 ''图形处理器(Graphics Processing Unit, GPU)'' 上运行的一套程序,用于确定应如何绘制对象。着色器替代了传统的固定渲染管线,可以实现图形计算中的渲染相关计算,由于其可编辑性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。着色器曾只存在于离线渲染(如 ''电影工业'')领域,而实时渲染领域的着色器则是在 Microsoft 推出 Shader Model(着色器模型) 后才被首次引入。
{{LanguageBar|title = 着色器}}
{{see also|[[:Category:Shaders]]}}


*Source 3D渲染中的所有内容都使用基于着色器绘制的方法
 
*着色器根据存储在 [[Material|材质]] 文件中的参数进行进一步工作,虽然看上去很简单,但里面存有非常复杂的来处理 ''实时阴影'' 、 ''照明'' 和 ''折射'' 等效果的配置信息。
着色器是在 ''图形处理器(Graphics Processing Unit, GPU)'' 上运行的一套程序,用于确定应如何绘制对象。着色器替代了传统的固定渲染管线,可以实现图形计算中的渲染相关计算,由于其可编程性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。
 
笼统地说,在 {{Source|4.1}} 之前的 {{gldsrc|4}} 使用简单的纹理映射 (Texture Mapping) 来展示材质,而 {{Source|4.1}} 优秀的着色器系统在此基础上加入了新的数学模型(例如 {{L|Phong_materials|Phong Specular}} 着色),使得材质表现更贴近真实。
 
{{Note| 现代计算机图形学领域将渲染管线内的所有组件都定义为着色器,不一定具备图形渲染功能。例如计算着色器 (''Compute Shader '')。我们日常所讨论的着色器大多都是使纹理材质有独特表现的一种固定程序,广义地来看,{{gldsrc|4}} 也具备着色器和着色模型 (Lambertian Diffuse)。}}
{{Note|  {{Source|4.1}} 一般使用 Forward 模式的渲染管线,在编写某些着色器时可能需要考虑到这个因素。 }}
 
*Source 的 3D 渲染中的所有内容都使用基于着色器绘制的方法,因为它运行着一个完整的渲染管线。
*着色器根据存储在 {{L|Material|材质}} 文件中的参数进行进一步工作,看似简单,但里面存有非常复杂的来处理 ''实时阴影'' 、 ''照明'' 和 ''折射'' 等特效的配置信息,它们一般由复杂的着色方程实现。
*着色频率和着色模型不应混为一谈。不同着色频率通过调整采样率来改变原有着色模型下的着色质量。
 
[[File:Phong-shading-sample (cropped).jpg|thumb|不同的着色频率:Flat Shading 和 Phong Shading]]


== 类型 ==
== 类型 ==
着色器(Shader)主要有顶点着色器(Vertex Shader,以下简称 VS)和像素着色器(Pixel Shader,以下简称 PS)两种(注:两种着色器在实现上略有不同)。
整个光栅化渲染管线内最重要的着色器是顶点着色器(Vertex Shader)和像素着色器(Pixel Shader)。{{L|Source}} SDK 提供了大量{{LCategory|Shaders|现成的着色器}}。


== 着色语言 ==
== 着色语言 ==
目前有三种主要的着色器语言:高阶着色器语言(HLSL),C for Graphics (Cg)和 OpenGL着色语言(GLSL)。Source 使用基于 HLSL 的着色器。而且 Cg 与其也非常相似,故大多数 Cg 着色器都可以快速轻松地移植到 HLSL。
目前有三种主要的着色器语言:高阶着色语言({{L|HLSL}}),C for Graphics ({{L|CG|Cg}}) 和 OpenGL 着色语言(GLSL)。Source 使用基于 HLSL 的着色器。HLSL 和 Cg 语言的语法基本相同,大多数 Cg 着色器都可以快速轻松地移植到 HLSL。
 
== Shader Model 着色器模型 ==
(以下简称 SM) SM 直接定义如何使 GPU  使用高阶着色技术,可以防止太老旧 GPU 运行基于新着色技术的程序。


Source 支持 SM 2.0(包括 PS 2.0b)和 SM 3.0。''其中 SM 3.0 是一次巨大飞跃,支持浮点精度运算,是现代高画质游戏的基石。因此 Source 的 shader 本身具有极强的拓展性。''
== 着色模型 ==
Shader Model (以下简称 SM)是一种编程模型,直接地定义了如何使 GPU 运行高阶着色技术,同时可以防止太老的 GPU 运行新着色技术的程序。(防止显卡爆炸)
{{L|Source}} 支持 SM 2.0(包括 PS 2.0b)和 SM 3.0. ''其中 SM 3.0 是一次巨大飞跃,支持浮点精度运算,是现代高画质游戏的基石。因此 Source 的 shader 本身具有极强的拓展性。''
{{Note|  SM 3.0 的着色器可能无法在 macOS 和 Linux 系统上正常工作,因为 Valve 的转接层 (DirectX To OpenGL) <code>togl</code>只支持 SM 3.0 的部分特性,如果想要着色器正常工作,你应该考虑做一个 SM 2.0b 标准的着色器。}}
{{ModernConfirm| 对于 vulkan_wrapper 的情况未知 ( {{L|Source}} 并不原生支持 Vulkan API, 只能通过 <code>dxvk</code> 进行转译。)}}


注:为 SM 3.0 编写的着色器可能无法在 Mac 和 Linux 系统上正常工作,因为 Valve 的''图形Wrapper''运行这个时缺乏某些支持。
*为较新的 GPU 创建着色器时,请务必记住去支持那些较旧 GPU 用的着色器,否则这样会对老玩家产生很多限制。


*为较新的GPU创建着色器时,请务必记住去支持那些较旧GPU用的着色器,否则你会发现这样会很快地把游戏规格限制得寥寥无几。
*旧的 GPU 可能要“着色器回退 (shader fallbacks)”,如果新版SM用不了,那么游戏会使用旧版 SM。


*旧的GPU可能要“着色器回退 (shader fallbacks)”,如果新SM用不了,那么游戏会使用旧SM。
== 像素着色器 ==
 
每个被渲染的像素都与像素着色器有关。像素着色器需要来自顶点的插值输入,然后再用它来栅格化图像。像素着色器可以产生涉及单个像素颜色的大量效果,例如 ''折射'' 、''逐像素照明'' 和 ''反射'' 等等。
== Pixel Shader 像素着色器 ==
(以下简称 PS)每个被渲染的像素都与像素着色器有关。PS需要来自顶点属性插值的输入,然后再用它来栅格化图像。PS可以产生涉及单个像素颜色的大量效果,例如 ''折射'' 、''逐像素照明'' 和 ''反射'' 等等。


===像素着色器 示例===
===像素着色器 示例===


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


// 指定一个纹理采样器,其实际来源在是 vmt 中确定的
{{CodeBlock|lines=14|<nowiki>// 纹理采样器
  sampler2D Texture0 : register( s0 );
  sampler2D Texture0 : register( s0 );
  // PS返回像素的颜色值(所以这里是float4)
  // 像素着色器返回像素的颜色值(所以这里是float4)
  float4 main( float2 texCoord  : TEXCOORD0 ) : COLOR
  float4 main( float2 texCoord  : TEXCOORD0 ) : COLOR
  {
  {
   // 在指定的纹理坐标处对纹理进行采样
   // 在指定的纹理坐标处对纹理进行采样
   float4 tex = tex2D( Texture0, texCoord );
   float4 tex = tex2D( Texture0, texCoord );
   // 用灰度去显示像素颜色值
   // 利用灰度信息得到像素的颜色值
   // - 在像素颜色与指定矢量之间执行点积
   // - 在像素颜色与指定矢量做点乘
   // - 在整个图像处理过程中,对于灰度级效果,可寻到 ''0.222、0.707、0.071''
   // - 处理过程中对于 Grayscale 有如下数值 ''0.222、0.707、0.071''
   float4 grey = dot(float3(0.222, 0.707, 0.071), tex);
   float4 grey = dot(float3(0.222, 0.707, 0.071), tex);
   // 以float4的形式返回像素颜色          
   // 以float4浮点数的形式返回像素颜色          
   return grey;
   return grey;
  }
  }
</nowiki>}}
== 顶点着色器 ==
顶点着色器应用于 ''可编程管线(Programmable Pipeline)'' 上运作的每个 ''顶点(Vertex)''。其最基本的功能是将几何体的顶点通过矩阵变换 (Transform) (具体包括世界空间 (Model Transform) 变换,视角变换 (View Transform) 和屏幕空间投影变换 (Projection Transform),三者合一即为图形学上大名鼎鼎的 "MVP 变换" )转为屏幕空间坐标等等,以便下一流程(例如三角形装配,遍历,像素着色器等)操作,顶点着色器负责处理模型数据并对这些数据执行输出操作,然后系统对顶点着色器输出的数据进行插值,再把插值结果送到像素着色器。顶点着色器也从网格(Mesh)接收其他信息,包括法线、切线和纹理 UV 坐标 等。
{{Note| 顶点着色器无法创建或销毁顶点。它处理的各顶点之间是无法相互访问的。}}


== Vertex Shader 顶点着色器 ==
(以下简称 VS)VS应用于 ''可编程管线(Programmable Pipeline)'' 上运作的每个 ''顶点(Vertex)''。其最基本的功能是将几何体转换为 ''屏幕空间(Screen-Space)'' 坐标,以便 ''PS'' 去栅格化图像。顶点着色器可以修改这些位置坐标以执行网格变形。它们还可以从 ''网格(Mesh)'' 接收其他信息,包括 ''法线、切线和纹理坐标'' , 然后VS就执行写入 ''(输出寄存器)'' 操作,再然后,在PS中的顶点之间对写入的值进行插值。'''注意!顶点着色器 无法创建或销毁顶点;它一次对单个顶点进行操作,将一个未处理的顶点作为输入并输出单个处理的顶点。
'''
=== 顶点着色器 示例 ===
=== 顶点着色器 示例 ===
这是个 ''传递着色器'', 它不会对顶点数据进行大改,只会把数据传递到PS的阶段罢了。
顶点着色器多数情况下只是扮演搬运工的角色, 它不会对顶点数据进行大改。


// 这个头文件提供 common VS 的定义
{{CodeBlock|lines=24|<nowiki> // 头文件
  #include "common_vs_fxc.h"
  #include "common_vs_fxc.h"
  // 定义输出结构
  // 输出结构
  struct VS_OUTPUT
  struct VS_OUTPUT
  {
  {
Line 59: Line 72:
   float2 texCoord  : TEXCOORD0;
   float2 texCoord  : TEXCOORD0;
  };
  };
  // 获取 ''位置矢量''(float4)
  // 获取位置矢量(float4)
  // 返回 ''VS_OUTPUT'' 结构
  // 返回 VS_OUTPUT
  VS_OUTPUT main( float4 inPos: POSITION )
  VS_OUTPUT main( float4 inPos: POSITION )
  {
  {
   // 声明一下要补充的空的 VS_OUTPUT
   // 声明需补充的空的 VS_OUTPUT
   VS_OUTPUT o = (VS_OUTPUT) 0;
   VS_OUTPUT o = (VS_OUTPUT) 0;
   // 计算 ''输入位置'' 的符号
   // 计算 ''输入位置'' 的符号
   inPos.xy = sign( inPos.xy);
   inPos.xy = sign( inPos.xy);
   // 用 ''输入的 xy'' 来设定输出位置
   // 用 已输入的 xy 值来确定输出的位置值
   o.pos = float4( inPos.xy, 0.0f, 1.0f);
   o.pos = float4( inPos.xy, 0.0f, 1.0f);
   // 进入到范围 [0,1]
   // 进入范围 [0,1]
   o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f;
   o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f;
   return o;
   return o;
  }
  }
</nowiki>}}


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


=== Post-process 后处理 ===
=== 后处理 ===
后处理着色器通常是在屏幕内已quad rendered的内容上工作的PS。quad使用帧缓冲区的Copy进行纹理处理,然后PS可以改变渲染输出来创建各种效果,比如把基本的color改成更高级的后处理,例如运动模糊(motion blur)和泛光(bloom)。
后处理着色器通常是在屏幕内已经渲染好的四边形的内容上工作的像素着色器。这些四边形(2x2 像素块,一般像素着色器执行着色的最小粒度)会进一步被各 Buffer 上的数据来进行纹理处理,然后再送到像素着色器来进一步渲染,输出图元后再创建各种效果,比如把一些基础的颜色经过后处理管道来达到最佳效果,例如动态模糊(motion blur)和泛光(bloom)。


注:某些文件已不再包含在 SDK 中。 这里给出一些可用作替代示例的着色器 ''sdk_bloom.cpp sdk_bloom.ps20.fxc''
高级的后期处理着色器[如动态模糊(motion blur)和泛光(bloom)的着色器]可能还需要使用自定义 {{L|RenderTarget}}。有关将后处理着色器与模组集成的更多信息,请参阅 {{L|Custom_Postprocessing_Effects}}
Source SDK 同时也提供了一些实例(''sdk_postprocess.cpp sdk_postprocess_vs20.fxc sdk_postprocess_ps20.fxc'')


高级后期处理着色器[如运动模糊(motion blur)和泛光(bloom)着色器]可能还需要使用自定义 Render Target。有关将后处理着色器与模组集成的更多信息,请参阅 Custom_Postprocessing_Effects
=== 逐对象 / 逐物体 ===
Source 中的逐对象着色器适用于具有由 {{L|VMT|Valve 材质 (.vmt)}} 援引的着色器的任何对象,比如 模型,笔刷 等。逐对象着色器可用于创建折射材质、动态地修改模型顶点或实现其他高级渲染效果。例如我们可以使用 Shadow Volume 采样数据写回 Stencil Buffer 来逐对象地投射高效率的动态阴影,但是请注意,目前没人在 Source 里实践过 Shadow Volume,我们一般使用 Shadowmap 或逐对象的阴影纹理。


=== Per-object 逐对象 ===
Source SDK 同时也提供逐对象着色器的示例[在光照贴图(lightmap)里]  ''sdk_lightmap.cppsdk_lightmap_vs20.fxcsdk_lightmap_ps20.fxc'')
Source 中的逐对象着色器适用于具有 Valve材质 (.vmt) 中引用的着色器的任何对象,例如 model 等。逐对象着色器可用于创建折射材质、动态地修改模型顶点或其他高级渲染效果。


Source SDK 同时也提供逐对象着色器地示例[在光照贴图(lightmap)里]  (''sdk_lightmap.cppsdk_lightmap_vs20.fxcsdk_lightmap_ps20.fxc'')
== 扩展链接 ==
 
== 扩展链接 / 引用 ==
* [http://www.bit-tech.net/hardware/2005/07/25/guide_to_shaders/1 A bluffer's guide to Shader Models]
* [http://www.bit-tech.net/hardware/2005/07/25/guide_to_shaders/1 A bluffer's guide to Shader Models]
* [http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html NVIDIA - The Cg tutorial]
* [http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html NVIDIA - The Cg tutorial]
Line 100: Line 111:
* [http://www.moddb.com/games/half-life-2/tutorials/post-process-shader Post-Process Shader Tutorial from Wraiyth]
* [http://www.moddb.com/games/half-life-2/tutorials/post-process-shader Post-Process Shader Tutorial from Wraiyth]


[[Category: Simplified Chinese]]
{{ACategory|Glossary}}
[[Category: Glossary]]
{{ACategory|Programming}}
[[Category: Programming]]
[[Category:Shaders:zh-cn|*]]
[[Category: Shaders|*]]
{{ACategory|Technical}}
[[Category: Technical]]
 
{{ACategory|Material_System}}

Latest revision as of 04:20, 22 August 2024

English (en)Español (es)Русский (ru)Українська (uk)中文 (zh)Translate (Translate)
参见:  Category:Shaders


着色器是在 图形处理器(Graphics Processing Unit, GPU) 上运行的一套程序,用于确定应如何绘制对象。着色器替代了传统的固定渲染管线,可以实现图形计算中的渲染相关计算,由于其可编程性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。

笼统地说,在 起源 起源 之前的 金源 金源 使用简单的纹理映射 (Texture Mapping) 来展示材质,而 起源 起源 优秀的着色器系统在此基础上加入了新的数学模型(例如 Phong Specular(en) 着色),使得材质表现更贴近真实。

Note.png注意: 现代计算机图形学领域将渲染管线内的所有组件都定义为着色器,不一定具备图形渲染功能。例如计算着色器 (Compute Shader )。我们日常所讨论的着色器大多都是使纹理材质有独特表现的一种固定程序,广义地来看,金源 金源 也具备着色器和着色模型 (Lambertian Diffuse)。
Note.png注意: 起源 起源 一般使用 Forward 模式的渲染管线,在编写某些着色器时可能需要考虑到这个因素。
  • Source 的 3D 渲染中的所有内容都使用基于着色器绘制的方法,因为它运行着一个完整的渲染管线。
  • 着色器根据存储在 材质(en) 文件中的参数进行进一步工作,看似简单,但里面存有非常复杂的来处理 实时阴影照明折射 等特效的配置信息,它们一般由复杂的着色方程实现。
  • 着色频率和着色模型不应混为一谈。不同着色频率通过调整采样率来改变原有着色模型下的着色质量。
不同的着色频率:Flat Shading 和 Phong Shading

类型

整个光栅化渲染管线内最重要的着色器是顶点着色器(Vertex Shader)和像素着色器(Pixel Shader)。Source(en) SDK 提供了大量现成的着色器(en)

着色语言

目前有三种主要的着色器语言:高阶着色语言(HLSL(en)),C for Graphics (Cg(en)) 和 OpenGL 着色语言(GLSL)。Source 使用基于 HLSL 的着色器。HLSL 和 Cg 语言的语法基本相同,大多数 Cg 着色器都可以快速轻松地移植到 HLSL。

着色模型

Shader Model (以下简称 SM)是一种编程模型,直接地定义了如何使 GPU 运行高阶着色技术,同时可以防止太老的 GPU 运行新着色技术的程序。(防止显卡爆炸) Source(en) 支持 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(en) 并不原生支持 Vulkan API, 只能通过 dxvk 进行转译。)
  • 为较新的 GPU 创建着色器时,请务必记住去支持那些较旧 GPU 用的着色器,否则这样会对老玩家产生很多限制。
  • 旧的 GPU 可能要“着色器回退 (shader fallbacks)”,如果新版SM用不了,那么游戏会使用旧版 SM。

像素着色器

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

像素着色器 示例

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

  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 ); // 利用灰度信息得到像素的颜色值 // - 在像素颜色与指定矢量做点乘 // - 处理过程中对于 Grayscale 有如下数值 ''0.222、0.707、0.071'' float4 grey = dot(float3(0.222, 0.707, 0.071), tex); // 以float4浮点数的形式返回像素颜色 return grey; }

顶点着色器

顶点着色器应用于 可编程管线(Programmable Pipeline) 上运作的每个 顶点(Vertex)。其最基本的功能是将几何体的顶点通过矩阵变换 (Transform) (具体包括世界空间 (Model Transform) 变换,视角变换 (View Transform) 和屏幕空间投影变换 (Projection Transform),三者合一即为图形学上大名鼎鼎的 "MVP 变换" )转为屏幕空间坐标等等,以便下一流程(例如三角形装配,遍历,像素着色器等)操作,顶点着色器负责处理模型数据并对这些数据执行输出操作,然后系统对顶点着色器输出的数据进行插值,再把插值结果送到像素着色器。顶点着色器也从网格(Mesh)接收其他信息,包括法线、切线和纹理 UV 坐标 等。

Note.png注意: 顶点着色器无法创建或销毁顶点。它处理的各顶点之间是无法相互访问的。

顶点着色器 示例

顶点着色器多数情况下只是扮演搬运工的角色, 它不会对顶点数据进行大改。

  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 中的大多数特效和材质都非常非常依赖其像素着色器组件。

后处理

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

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

逐对象 / 逐物体

Source 中的逐对象着色器适用于具有由 Valve 材质 (.vmt)(en) 援引的着色器的任何对象,比如 模型,笔刷 等。逐对象着色器可用于创建折射材质、动态地修改模型顶点或实现其他高级渲染效果。例如我们可以使用 Shadow Volume 采样数据写回 Stencil Buffer 来逐对象地投射高效率的动态阴影,但是请注意,目前没人在 Source 里实践过 Shadow Volume,我们一般使用 Shadowmap 或逐对象的阴影纹理。

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

扩展链接