acdream/src/AcDream.App/Rendering/Shaders/mesh_modern.vert
Erik 166af9a53e phase(N.5) Task 5 fixup: shader doc + extension cleanup
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) <noreply@anthropic.com>
2026-05-08 20:11:03 +02:00

62 lines
2.1 KiB
GLSL

#version 430 core
#extension GL_ARB_shader_draw_parameters : require
layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoord;
struct InstanceData {
mat4 transform;
// Reserved for Phase B.4 follow-up (selection-blink retail-faithful
// highlight): vec4 highlightColor; — extend stride here, increase the
// _instanceSsbo upload size in WbDrawDispatcher, add a flat varying out,
// and consume in mesh_modern.frag.
};
struct BatchData {
uvec2 textureHandle; // bindless handle for sampler2DArray
uint textureLayer; // layer index (always 0 for per-instance composites)
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[];
};
uniform mat4 uViewProjection;
out vec3 vNormal;
out vec2 vTexCoord;
out vec3 vWorldPos;
out flat uvec2 vTextureHandle;
out flat uint vTextureLayer;
void main() {
int instanceIndex = gl_BaseInstanceARB + gl_InstanceID;
mat4 model = Instances[instanceIndex].transform;
vec4 worldPos = model * vec4(aPosition, 1.0);
gl_Position = uViewProjection * worldPos;
vWorldPos = worldPos.xyz;
vNormal = normalize(mat3(model) * aNormal);
vTexCoord = aTexCoord;
BatchData b = Batches[gl_DrawIDARB];
vTextureHandle = b.textureHandle;
vTextureLayer = b.textureLayer;
}