From 166af9a53e16feaaab58e9616b83462b2b9b4e33 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 8 May 2026 20:11:03 +0200 Subject: [PATCH] phase(N.5) Task 5 fixup: shader doc + extension cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code quality review caught four issues: - Unnecessary GL_ARB_bindless_texture extension in mesh_modern.vert (vert doesn't use bindless types). Removed; only the frag needs it. - SSBO binding=1 (BatchBuffer) and UBO binding=1 (SceneLighting) are in distinct GL namespaces — added a comment in the vert documenting this so Task 10's bind site doesn't get confused. - Misleading "0=opaque, 1=transparent" comment expanded to spell out the full Decision 2 two-pass alpha-test logic and what each discard threshold protects against. - BatchData.flags field is reserved; documented that N.5's dispatcher owns all blend state, with a hook for future shader-side additive. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/Shaders/mesh_modern.frag | 8 +++++++- src/AcDream.App/Rendering/Shaders/mesh_modern.vert | 13 +++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/AcDream.App/Rendering/Shaders/mesh_modern.frag b/src/AcDream.App/Rendering/Shaders/mesh_modern.frag index fef4491..c5d9a02 100644 --- a/src/AcDream.App/Rendering/Shaders/mesh_modern.frag +++ b/src/AcDream.App/Rendering/Shaders/mesh_modern.frag @@ -7,7 +7,13 @@ in vec3 vWorldPos; in flat uvec2 vTextureHandle; in flat uint vTextureLayer; -// 0 = opaque (discard alpha<0.95), 1 = transparent (discard alpha>=0.95) +// uRenderPass values (Phase N.5 Decision 2 — two-pass alpha-test): +// 0 = opaque pass — discard fragments with alpha < 0.95 +// (lets the depth write succeed for solid pixels) +// 1 = translucent pass — covers AlphaBlend / Additive / InvAlpha; +// discard alpha >= 0.95 (already drawn opaque) and +// alpha < 0.05 (skip empty fragments — large +// transparent overdraw cost otherwise) uniform int uRenderPass; // SceneLighting UBO — IDENTICAL layout to mesh_instanced.frag binding=1. diff --git a/src/AcDream.App/Rendering/Shaders/mesh_modern.vert b/src/AcDream.App/Rendering/Shaders/mesh_modern.vert index 31dd6bb..02f46d9 100644 --- a/src/AcDream.App/Rendering/Shaders/mesh_modern.vert +++ b/src/AcDream.App/Rendering/Shaders/mesh_modern.vert @@ -1,5 +1,4 @@ #version 430 core -#extension GL_ARB_bindless_texture : require #extension GL_ARB_shader_draw_parameters : require layout(location = 0) in vec3 aPosition; @@ -17,13 +16,23 @@ struct InstanceData { struct BatchData { uvec2 textureHandle; // bindless handle for sampler2DArray uint textureLayer; // layer index (always 0 for per-instance composites) - uint flags; // reserved + uint flags; // reserved — N.5 dispatcher owns all blend state + // (glBlendFunc per pass). If a future phase wants + // shader-side per-batch additive flag (Decision 2 + // fallback), encode it here as bit 0. }; layout(std430, binding = 0) readonly buffer InstanceBuffer { InstanceData Instances[]; }; +// binding=1 here is the SSBO namespace — distinct from the UBO namespace. +// SceneLighting UBO also uses binding=1 in the fragment shader; GL keeps +// GL_SHADER_STORAGE_BUFFER and GL_UNIFORM_BUFFER binding tables separate. +// Task 10 dispatcher binds: +// glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, instanceSsbo) +// glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, batchSsbo) +// Existing SceneLightingUboBinding handles the UBO side. layout(std430, binding = 1) readonly buffer BatchBuffer { BatchData Batches[]; };