基于图像的可变速率着色 (ImageBased Variable Rate Shading ,Attachment Shading Rate)是一种利用屏幕空间下的着色频率图像附件(Shading Rate Image, 下文简称 SRI)将 光栅化 与 像素着色频率 解耦的技术,可实现按区域灵活控制片元着色频率。
该技术能够有效削减冗余的像素操作,在最大限度降低对视觉保真度影响的前提下,显著提升图形管线的渲染效率。
为什么需要ImageBased VRS ?
游戏画面里往往存在大面积平滑区域:天空、墙壁、水面、雾气,其相邻像素颜色几乎一致。如果对这些颜色相近的像素都进行着色计算的话,其实是一种巨大的浪费。
现代的GPU硬件提供了 “可变速率着色”技术,将“哪些像素被画”和“画得多精细”这两个问题分开进行处理。以下图中的 8*8 的像素块为例,通过调整着色计算频率,可以在保留三角形的像素边缘的同时,减少着色计算的次数。
![]()
Shading Rate分别设置为1×1, 2×2, 4×4时的着色计算情况
着色频率不为1*1时,着色求值点可能落在三角形外。默认使用的外推(Extrapolation)计算的着色值可能导致反常的结果。可以在shader中使用限定符 centroid 移动着色求值点到三角形的覆盖范围内。
ImageBased VRS 把“哪些像素被画”和“画得多精细”两个问题分开处理:颜色变化平缓的区域用低精度着色,边缘和细节区域则保持高精度。做到提升渲染效率,而几乎不损失画面效果。
![]()
下方图为渲染结果;上方图为将着色频率可视化的结果
图中,紫色部分代表采用了着色频率为 4×4 的区域。可以清晰地看到,天空部分因为颜色过于相近,使用较低频率的着色计算即可保证渲染质量。
对比RendererBased VRS
对比先前团结引擎推出的基于Pipeline Shading Rate (管线着色频率)技术实现的RendererBased VRS方案, ImageBased VRS 提供了更为精细的着色频率调控粒度。
RendererBased VRS 通过在Draw Call前设置管线着色频率进行控制,同一个 Renderer/Draw Call 上只能使用相同频率;
![]()
通过RendererBased VRS根据深度对不同的Renderer使用不同的着色频率。最远处的Renderer显示为紫色,为 4×4 着色频率
ImageBased VRS 按 8×8 ~ 32×32 的像素块划分屏幕并指定着色频率,同一个 Renderer/Draw Call 内不同区域也可以使用不同着色频率。
![]()
图中每个像素对应屏幕上一个 8×8 ~ 32×32 大小的像素块。天空等颜色相近的区域显示为紫色, 为 4×4着色频率
RendererBased VRS 和 ImageBased VRS 二者的使用并不冲突,可以通过 “CombinerOps” 进行组合,供开发者可以灵活选择片元最终生效的着色频率。
![]()
RendererBased VRS 使用的管线着色频率作为A0 着色频率输入;ImageBased VRS 使用的图像附件着色频率作为 B1 着色频率输入
根据使用的图形API的不同,“CombinerOps” 提供的组合方式可能有所不同。
![]()
常见的组合方式及其示例
ImageBased VRS 技术原理
上文我们提到ImageBased VRS 以 8×8 ~ 32×32 的像素块为粒度控制着色频率。实践中,着色频率信息使用一张R8_UINT 格式的着色频率图像附件(Shading Rate Image, SRI)记录。这张图像附件为按比例缩小的屏幕空间贴图,每个像素对应屏幕上的一个像素块,将像素块X, Y 两个方向上独立的着色频率合并编码为一个 UINT 值,使用该UINT值记录为像素块使用的着色频率。着色计算阶段,GPU 会通过像素位置查询这张图像附件,找到其记录的着色频率。
![]()
R8_UINT 格式的着色频率图像附件;UINT 取值在0~10之间
ImageBased VRS 提供根据像素的感知亮度梯度,或运动幅度计算着色频率的方法,以生成着色频率图像附件。
如果根据感知亮度梯度进行计算,需要在上一帧末尾对画面作Sobel边缘检测,计算每个像素块内沿 X, Y方向感知亮度的最大梯度。将梯度与用户设置的阈值进行比较,判断当前画面中各个像素块合适的着色频率。对于X, Y方向上颜色变化极小的方向使用4×、中等的 2×、剧烈变化的 1×; 当前帧中根据Motion Vector进行重投影,使图像附件对应当前帧的像素分布。
如果根据运动幅度进行计算,则依赖Motion Vector计算像素块X, Y方向上的最小运动速度。将运动速度与用户设置的阈值进行比较判断,对运动幅度大的方向使用4×, 中等的 2×、较小的 1×。
当同时启用感知亮度和运动幅度进行计算时,会在重投影阶段将运动幅度纳入计算。
简言之,感知亮度梯度越小,或移动速度越大,着色频率越低。
![]()
ImageBased VRS RenderFeature
在URP中,ImageBased VRS 通过 RenderFeature【ImageBasedVRSRenderFeature】实现。
![]()
SRI configuration fields
Combiner Op 0: 用于设置 “pipeline shading rate” 和 “primitive shading rate” 之间的组合方式。默认为 “Keep”。
Combiner Op 1: 用于设置 “CombinerOp0”组合输出的结果和 “attachment shading rate” 之间的组合方式。默认为 “Replace”。
Inject Point: 用于设置 ImageBased VRS 在管线中生效的时刻。默认为Gbuffer 绘制之前(延迟渲染)或Deferred Lights之前(前向渲染)。
Reset Inject Point: 用于设置 ImageBased VRS 在管线中停止生效的时刻。默认为后处理之前。
Generation Mode: 用于设置着色频率图像附件的生成方式,共有三种。分别为根据感知亮度梯度的“Luminance”, 根据运动幅度的“Motion Only”,和结合二者的 “Luminance + Motion”
![]()
Luminance Thresholds
用于设置与感知亮度梯度比较的阈值。 X, Y 两个方向各自独立比较。
如果X, Y 方向上的计算得到的梯度小于 “Luminance Threshold 4 Pixel” ,则该方向使用4×。如果小于 “Luminance Threshold 2 Pixel” 而大于 “Luminance Threshold 4 Pixel”,则该方向使用2×。如果不小于任何一个阈值,则该方向使用1×, 进行全分辨率着色。
Motion Thresholds
用于设置与运动幅度比较的阈值。X、Y 两个方向各自独立比较。
如果X, Y 方向上的计算得到的速度(像素/帧)大于 “Motion Threshold 4 Pixel” ,则该方向使用4×。如果大于 “Motion Threshold 2 Pixel” 而小于 “Motion Threshold 4 Pixel”,则该方向使用2×。如果不大于任何一个阈值,则该方向使用1×, 进行全分辨率着色。
Show Debug SRI
用于将当前帧使用的着色频率图像附件中不同的着色频率映射为不同颜色,绘制在屏幕的右上区域,用于调试时实时参考。
![]()
Debug SRI 的实时绘制状况
![]()
着色频率与颜色的映射关系表
AlphaTest Separation
“Separate Alpha Test Pass” 用于决定是否针对位于AlphaTest 渲染队列的物体单独关闭ImageBased VRS的使用。当勾选时,渲染AlphaTest 渲染队列的物体时,ImageBased VRS将不生效,以保证渲染质量。
AlphaTest 在片元阶段根据Alpha值决定是否抛弃该片元,开启VRS后,可能导致部分片元被错误抛弃。
平台支持
DirectX 12(Windows 平台):支持 DX12 Ultimate 的设备。
DirectX 11(Windows 平台):搭载 NVIDIA Turing 架构或更新代际 GPU 的设备。
Vulkan(Windows / Android 平台):支持 Vulkan 扩展 VK_KHR_fragment_shading_rate 的设备。
OpenGL ES(Android 平台):支持 OpenGL ES 扩展 GL_EXT_fragment_shading_rate_attachment 的设备。
性能数据
使用URP Sample工程中提供的VRS测试场景 “OasisVRSSampleScene” ,分别在室外、水面和室内场景开启,关闭ImageBased VRS 功能进行测试。
性能对比:
![]()
GPU耗时的性能对比
效果对比:
室外场景

ImageBased VRS OFF

ImageBased VRS ON
水面场景

ImageBased VRS OFF

ImageBased VRS ON
室内场景

ImageBased VRS OFF

ImageBased VRS ON
快速入门
目前仅支持 URP 管线,ImageBased VRS 已在团结引擎 1.10.2 版本对应的 URP (14.1.6) 中提供。
1. 找到当前使用的 Universal Renderer Data。
2. 点击“Add Renderer Feature” 列出可添加的 RenderFeature 列表。
3. 选择RenderFeature “Image Based Variable Shading Rate” 进行添加。
4. 调整参数以达成渲染质量和渲染压力之间的平衡。
![]()
Unity 官方微信
第一时间了解 Unity 引擎动向,学习进阶开发技能
每一个“点赞”、“在看”,都是我们前进的动力
![]()
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.