Files
HelloVulkan/shaders/simple_shader.vert
T
atdunbg 7fca721a24 feat: GPUDriven 实例化渲染——draw 数与实体数解耦
- UniformBuffer ring 支持 eStorageBuffer usage(GPUDriven 实例矩阵
  per-frame-slot,正确性保证与 UBO 一致:fence 等待后写入)
- DescriptorManager 加 UpdateStorageBuffer;池补 STORAGE_BUFFER 类型
- Set0 新增 binding1 = 实例矩阵 SSBO(vertex 读取,std430)
- Forward pass 重写:每帧从 ECS 收集实例矩阵(按 mesh 聚合 batch,
  两趟遍历保证 batch 区间连续),同 mesh 的 N 个实体合并为
  一次 drawIndexed(instanceCount=N),firstInstance 指向 batch 起点;
  vertex shader 经 gl_InstanceIndex 取模型矩阵,forward 不再用 push
- draw 数 = 唯一 mesh 数,与实体数量解耦(4096 实例上限,
  超出截断告警;聚合改哈希为后续 TODO)

验证:8 pass 全活,validation 0 error 0 warning,GPU Timings 面板
实测各 pass 毫秒,场景渲染与阴影正确
2026-09-22 19:46:17 +08:00

48 lines
1.4 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#version 450
const int MAX_LIGHTS = 4;
struct Light {
vec4 direction;
vec4 color;
};
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(location = 0) out vec2 fragUV;
layout(location = 1) out vec3 fragNormal;
layout(location = 2) out vec3 fragWorldPos;
layout(location = 3) out vec3 fragLightSpacePos;
// GPUDriven:模型矩阵从实例缓冲按实例索引取。
// 同一 mesh 的 N 个实体 = 1 次 drawIndexed(instanceCount=N),
// draw 侧用 firstInstance 指向该 batch 在实例数组中的起始下标。
layout(std430, set = 0, binding = 1) readonly buffer ObjectBuffer {
mat4 models[]; // 连续 mat4 数组(16B 对齐,std430/std140 布局一致)
} objects;
layout(set = 0, binding = 0) uniform UniformBufferObject {
mat4 view;
mat4 proj;
mat4 lightSpace;
vec4 ambientColor;
Light lights[MAX_LIGHTS];
} ubo;
void main() {
mat4 model = objects.models[gl_InstanceIndex];
vec4 worldPos = model * vec4(inPosition, 1.0);
gl_Position = ubo.proj * ubo.view * worldPos;
fragWorldPos = worldPos.xyz;
// 光空间坐标(含 Vulkan [0,1] 深度重映射,与 shadow pass 写入端共用同一矩阵)
fragLightSpacePos = (ubo.lightSpace * worldPos).xyz;
mat3 normalMatrix = mat3(transpose(inverse(model)));
fragNormal = normalize(normalMatrix * inNormal);
fragUV = inUV;
}