透明分层屏幕空间折射 + 透明排序修正 + 默认清屏色归零

默认 ClearColor 0.1 → 0(策划阶段结束,无用)。

透明分层折射(玻璃见玻璃):透明段原来单个 ForwardTrans pass,折射
采样源 SceneColor 副本只在不透明段后快照一次(不含任何透明体)→ 前
玻璃折射不出后玻璃。改为按绘制单位远→近拆成至多 kTransparentLayers
层,每层绘制前刷新 SceneColor 副本,使层 L 玻璃采样含所有更远透明体。
RenderGraph pass 编译期定序,故层数固定;超出并入末层。深度 storeOp
改 eStore(多层需 Load 承接有效深度内容)。shader 不改。

透明排序修正:排序键由"相机到实例的欧氏距离"改为视图空间深度
(-(view·p).z)——欧氏距离把侧向偏移计入距离,偏侧物体被误判为更远
(正方体右上的甜甜圈在特定视角被排到后方)。并让透明队列逐实例成批
(不合并):透明本就是每层一个绘制单位,合并成多实例 batch 会让排序
只能用批平均深度、批内实例无法各自定序。零额外 draw 代价。
This commit is contained in:
2026-10-18 17:09:42 +08:00
parent f107854236
commit 2df6e57b61
11 changed files with 261 additions and 154 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ namespace Engine::ECS {
// 环境类设置已迁为环境实体组件(SkyboxComponent/SkyLightComponent,
// UE Skybox/SkyLight Actor 语义);仅保留渲Target清屏色
struct Settings {
glm::vec4 ClearColor = {0.1, 0.1, 0.1, 1.0};
glm::vec4 ClearColor = {0.0, 0.0, 0.0, 1.0};
};
Settings& GetSettings() { return m_Settings; }
const Settings& GetSettings() const { return m_Settings; } // 序列化只读
@@ -37,6 +37,15 @@ namespace Engine::Passes {
void RecordSharedState(const RG::RenderGraphContext& ctx,
vk::CommandBuffer cmd, bool translucent) const;
// 透明队列绘制单位总数(= 各批实例数之和;排序后扁平单位序)
u32 TransparentUnitCount() const;
// 绘制透明单位区间 [start,end)(批次内连续实例合并为一次 draw):
// 透明渲染实例 + 预乘 alpha 混合 + 只测不写深度的全部状态
void DrawTransparentRange(const RG::RenderGraphContext& ctx,
vk::CommandBuffer cmd,
u32 start, u32 end) const;
SceneGpu& m_Gpu;
FrameSceneData& m_Frame;
RG::TextureHandle m_HDRColor;
@@ -5,7 +5,7 @@
// "HitProxy" —— 拾取请求帧把不透明 + 透明 batch 用 id 管线画进
// R32Uint 目标(片元值 = 实体位模式)。深度自测自写
// (重清主深度):遮挡语义 = 可见表面胜出;运行在
// Forward/ForwardTrans/PhysicsDebug 之后的 WAW 链尾,
// Forward/ForwardTransL*/PhysicsDebug 之后的 WAW 链尾,
// 主链下游无人再读深度,下帧 Forward 照常重新 Clear
// "HitProxyCopy" —— 请求像素 1×1 CopyImageToBuffer 进 host-visible
// 暂存。TransferSrc use 让 RG 自动完成
@@ -150,7 +150,8 @@ namespace Engine {
std::vector<u32> instanceNext; // 与 instances 平行:同 batch 下一实例
// 每 batch 实例链头(与 result.batches 平行;kNoInstance = 空)
std::vector<u32> batchHead;
// 每 batch 实例距离累加(透明排序用:平均距离降序 = 远→近)
// 每 batch 实例视图深度累加(透明排序用:平均深度降序 = 远→近;
// 透明队列逐实例成批故 count=1,等价逐实例深度)
std::vector<f32> batchDistSum;
// batch 查找:数组寻址(下标 = Mesh::GetSlot(),值 = 每 LOD 的
// batchIdx+1,0 = 未用)——逐实例 hash 在大场景是毫秒级开销
+1 -1
View File
@@ -190,7 +190,7 @@ namespace Engine {
f32 cameraFarZ = 10000.0f;
bool cameraOrtho = false;
glm::vec4 ClearColor{0.1, 0.1, 0.1, 1.0};
glm::vec4 ClearColor{0.0, 0.0, 0.0, 1.0};
bool DrawSkybox = true;
// 本帧生效的环境贴图资产路径(来自第一个 active 的
// SkyboxComponent;空 = 无环境 → Renderer 回中性兜底 cubemap)。