GPU Gems 3 · Chapter 23. High-Speed, Off-Screen Particles

从粒子填充率出发,解释如何用离屏低分辨率目标、深度下采样和边缘修复稳定烟雾火焰等大面积粒子效果。

学习目标

  • 能解释大面积烟雾粒子的主要成本为什么来自屏幕片元,而不是粒子系统的顶点数量
  • 能修改 Off-Screen Particle Lab 的缩放、模式、深度、soft particles 与边缘阈值,比较粒子像素和伪影风险
  • 能回答:什么时候低分辨率足够,什么时候需要 mixed-resolution 的 Sobel 与 stencil 修复

先问:为什么一团烟会拖垮整帧

想象一团几乎填满画面的烟雾。它看起来柔软、没有清晰轮廓,但画面上的每一层半透明形状都要被读取、混合和写回。即使这些形状本身很简单,重复覆盖同一片屏幕也会把时间耗在“同一个小格被算很多次”上。

本章解决的是:把这类柔软画面先画到一个更小的临时画布,再放回主画面。没有这条路径,粒子数量一多,帧率会随覆盖区域突然下降;只把画布缩小,又会让岩石般的锐利细节变成块状和闪烁。

1. 让低频粒子先在小画布上完成大部分工作

粒子常用来表示烟、雾、火焰和爆炸。这些画面的颜色与透明度变化通常比较缓慢,没有大量细小锐边,属于低频内容。因此,用主画面的一部分分辨率采样,视觉上仍然可以保持柔和,只需在最后做一次放大和合成。

缩放比例不是固定规则。应用可以根据速度与质量目标选择 1、2、4、8 等比例,也可以使用非幂次比例。比例越激进,粒子片元和混合越少,但越容易丢掉高频轮廓;飞石、碎片等锐利粒子不适合直接套用同一策略。

fewer shaded particle pixels, same scene compositionfull-resolution targetevery particle shades many pixelsoff-screen targetrender, then upsample and compositelow-frequency fog tolerates this scale

2. 先识别 overdraw,再决定是否值得缩小

粒子系统的顶点数量可能只有几百个,但每个半透明四边形都会参与像素着色与混合。相机正对爆炸或烟柱时,一个粒子甚至可以覆盖整个屏幕,最终成本取决于被处理的粒子像素数量,而不是 draw call 看起来有多短。

因此先问“粒子是不是低频、是不是覆盖了大片屏幕”。如果粒子很小,离屏目标的额外缩放、放大、边缘检测反而可能比原始绘制更贵;如果粒子填满屏幕,降低粒子像素通常能把最坏情况的帧率拉回可控范围。

3. 用匹配尺寸的深度目标保留遮挡关系

离屏粒子不能只画在一个透明黑底上,否则它会穿过墙、角色或武器。完整流程是:先正常绘制实体场景并写主 z buffer;把 z buffer 缩小到离屏目标的大小;粒子绘制时在像素阶段读取对应的小深度;最后才把粒子目标放大合成。

下采样深度时取每个区域的最大深度,可以减少粒子贴着实体边缘时产生的 halo。它不是完美的几何重建,却是一个保守、适合 GPU 纹理读取的近似。深度目标尺寸必须和颜色目标匹配,否则颜色和遮挡会沿不同的网格采样,出现错位边缘。

depth-aware off-screen composition1 · solid scenewrite main z2 · downsamplesmall depth target3 · particlestest before blend4updepth must be downsampled at the same scale as the particle target

4. 用 soft particles 把硬切换变成渐隐

最简单的深度测试是:粒子比场景更远就丢弃,否则保留。这会在粒子平面和实体表面相交处留下硬边。soft particles 不再只做二值判断,而是把两者的深度差送入缩放和 saturate,得到从零到一的 alpha 权重。

这只是离屏管线的副作用增强,不会解决分辨率不足造成的块状问题。它解决的是“相交处太硬”,而边缘检测解决的是“低分辨率无法表达尖锐轮廓”,两者针对不同的伪影来源。

turn a hard depth cut into a soft fadefar from scene: alpha staysnear scene: alpha fadeszFade = saturate(scale × (particleDepth − sceneDepth))

5. 用 Sobel 找出低分辨率无法表达的边缘

把画面全部恢复到全分辨率会失去离屏渲染的意义。更省的方式是在小目标的颜色和 alpha 上做 Sobel filter,找出变化突然的地方。大多数柔软内部区域没有明显边缘,可以继续使用放大后的结果;只有少量边缘区域需要更精细的粒子重绘。

边缘检测结果写成 mask。合成离屏粒子时,同时把 mask 写到 stencil buffer;下一次全分辨率粒子绘制只在 stencil 允许的位置执行。pixel shader 可以通过 discard 避免为非边缘像素写入 stencil,从而把全分辨率工作限制在少数区域。

repair only the edges that low resolution cannot representsmall targetblocky edgeSobeledge maskstencilfull-res patchimage-processing cost stays low because the mask selects only a minority of pixels

6. mixed-resolution 在速度和细节之间分配预算

mixed-resolution rendering 不是简单的“低分辨率加一个滤镜”。它把粒子工作拆成两类:主体低频部分尽量缩小,边缘和局部高频部分用全分辨率重建。额外的 edge detection、stencil 和合成也在低分辨率完成,因此复杂度增加不一定意味着成本大幅增加。

它仍然有边界:如果粒子系统在屏幕上只占很小区域,低分辨率处理的固定开销可能超过节省的粒子像素;如果粒子包含很多锐利碎片,低分辨率目标在采样时已经丢掉的信息无法完全找回。选择方案时要同时看屏幕覆盖、频率和可接受的伪影。

7. 把深度、粒子和修边串成可调的渲染循环

float4 ParticlePS(ParticleIn input) {
  float sceneDepth = depthSampler.Sample(linearSampler, input.screenUV).r;
  float zFade = saturate(scale * (input.depth - sceneDepth));
  float4 particle = shadeParticle(input);
  particle.a *= zFade;
  return particle;
}
 
// Low-resolution target is upsampled and composited first.
// A Sobel mask then enables a full-resolution particle pass.

代码只展示 pixel shader 的深度侧:离屏目标负责降低粒子片元数量,downsampled depth buffer 负责遮挡,soft particles 负责交界渐隐。mixed-resolution 的全分辨率补画由 stencil mask 决定,而不是让每个像素都重新执行。

分步1 / 3

先建立与颜色目标匹配的深度目标

完整绘制实体场景并写主 z buffer,再按离屏颜色目标的尺寸下采样;粒子阶段读取这张小深度图,保持遮挡关系。

depth-aware off-screen composition1 · solid scenewrite main z2 · downsamplesmall depth target3 · particlestest before blend4updepth must be downsampled at the same scale as the particle target
fewer shaded particle pixels, same scene compositionfull-resolution targetevery particle shades many pixelsoff-screen targetrender, then upsample and compositelow-frequency fog tolerates this scale
GPU Gems 3 · Chapter 23

Off-Screen Particle Lab

可交互

调整分辨率缩放、渲染模式、深度下采样、soft particles 和边缘阈值,观察粒子片元与图像处理的真实取舍。

mixed-resolution edge repair混合分辨率把 Sobel + stencil 修复限制在少数边缘像素。particle pixels 2.9M · image pixels 3.2M · edge share 14% · soft depth fade hides hard intersections
粒子像素2.9M
图像处理像素3.2M
边缘修复占比14%
块状伪影风险33%

本章小结

  • 大面积低频粒子适合先绘制到较小的离屏目标
  • downsampled depth buffer 让离屏粒子仍能正确遮挡
  • soft particles 用深度差消除交界硬边
  • Sobel 与 stencil 只修复低分辨率暴露的少数边缘
  • mixed-resolution 要同时权衡屏幕覆盖、频率和固定处理成本

练习

问题 1|修改 Demo 代码。 把 Lab 的 render mode 切到 low,再把 off-screen scale 从 2× 调到 8×;你预计粒子像素、图像处理像素和伪影风险如何变化?

问题 2|诊断穿墙粒子。 离屏烟雾能正确显示,但总是穿过场景中的实体物体,请检查哪三个资源和阶段?

问题 3|场景选型。 全屏烟雾、远处小型碎石、近景带硬轮廓的爆炸分别如何选择 high、low 或 mixed?

名词解释

本章出现的专业名词,用大白话再讲一遍。

off-screen rendering
overdraw
downsampled depth buffer
soft particles
Sobel filter
mixed-resolution rendering

资料与写作方式声明

本章以GPU Gems 3 · Chapter 23. High-Speed, Off-Screen Particles权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…