Forward Rendering与Forward+
全库目录221
本文目录6
材质着色时逐盏灯计算很直接,灯一多,每个片元遍历的无关光源也变多。Forward+把筛灯提前,材质仍在前向阶段计算。先检查列表保守性和资源可见性,再看提交、像素和列表构建的总成本,才能判断这一步是否改善整帧。
Forward Rendering
Forward 在绘制物体时直接计算光照并输出最终颜色。
简化流程:
Object → Vertex Shader → Rasterization → Material + Lights → Color优点:
- 流程直接;
- 透明和自定义材质容易接入;
- MSAA 相对自然;
- 中间缓冲少,适合带宽敏感平台。
问题是要先决定每个物体受哪些灯影响。传统 Multi-pass Forward 可能对额外灯重复绘制物体;Single-pass Forward 会把灯列表传给着色器,但列表长度和分支受限。
不能简单说 Forward 的复杂度是 。实际成本取决于可见对象、每个对象重叠灯数、屏幕覆盖、Pass 和剔除策略。
Forward+
Forward+ 保留 Forward 材质阶段,但先用 Tiled/Clustered Culling 建立灯列表。像素着色器只遍历当前区域的灯。
它结合了:
- Forward 对透明、MSAA 和复杂材质的适应;
- 屏幕分区对大量灯的筛选能力。
代价是需要构建灯列表,且不透明和透明阶段可能使用不同列表或深度信息。
本页读取的区域索引来自 Tiled与Clustered光源剔除。例如同一屏幕块里近处墙面与远处透明玻璃深度相差很大,只用不透明深度的最小最大值建表,会把玻璃附近的灯提前剔掉。透明阶段可使用覆盖完整视锥深度的簇表,或维护独立列表;选择改变的是候选集合,不改变材质 BRDF。
局部灯列表着色
以下为 HLSL 函数轮廓。输入片元位置、法线和对应区域索引,区域表记录灯索引缓冲的起点和数量。真实 BRDF、阴影和距离衰减由 EvaluateLight 提供。
float3 ShadeLocalLights(float3 positionWS, float3 normalWS, uint region)
{
uint2 range = LightRanges[region];
float3 lighting = 0.0;
for (uint localIndex = 0; localIndex < range.y; ++localIndex)
{
uint lightIndex = LightIndices[range.x + localIndex];
lighting += EvaluateLight(Lights[lightIndex], positionWS, normalWS);
}
return lighting;
}例如区域表为(5,2),该区域只读取索引缓冲第5、6项,假设其值为3、9,就分别评价灯3和灯9。第5项是索引地址,不是灯ID。把range.x误当lightIndex会评价灯5并漏掉灯3;逐项显示索引链可以区分建表与消费错误。
读取前要保证构建列表的计算写入对图形着色可见。区域索引、数组容量与灯数据寿命必须匹配。用遍历全部光源的参考着色验证局部列表,结果差异提示漏灯、范围或阴影数据错误。
验证方法
- 记录材质绘制与灯光循环,确认列表只影响候选灯。
- 增加灯光和透明对象,对比普通前向与 Forward+ 的整帧耗时。
- 检查溢出列表、深度范围及透明路径使用的光源集合。
相关主题
示例与验证范围:代码按文中前提解释机制,完整类型、资源和项目状态需由接入工程补齐。完整目标引擎运行与GPU性能为UNVERIFIED;正文给出的机制与实际实验范围分别记录。
参考资料
- AMD:ForwardPlus11:官方样例 README:计算着色器构造局部灯列表、前向像素着色消费;本文未构建该旧版 D3D11 样例。