#version 460 core #pragma shader_stage(vertex) #extension GL_EXT_nonuniform_qualifier : enable layout(location = 0) out vec2 outUV; struct Position { float position[4]; }; struct Normal { float normal[4]; }; struct UV { float uv[2]; }; struct MaterialData { float m_AlbedoFactor[4]; float m_EmissionFactor[3]; float m_MetalFactor; float m_RoughFactor; uint m_AlbedoTex; uint m_NormalTex; uint m_MetalRoughTex; uint m_OcclusionTex; uint m_EmissionTex; }; #define INVALID_HANDLE 0xFFFFFFFF layout(std430, set = 0, binding = 0) readonly buffer Vertices { Position data[]; } vertexBuffer[]; layout(std430, set = 0, binding = 0) readonly buffer Normals { Normal data[]; } normalBuffer[]; layout(std430, set = 0, binding = 0) readonly buffer TexCoord0 { UV data[]; } uvBuffer[]; layout(std430, set = 0, binding = 0) readonly buffer Materials { MaterialData data[]; } materialsBuffer[]; vec3 GetPosition(uint bufferId, uint vertexIdx) { return vec3( vertexBuffer[bufferId].data[vertexIdx].position[0], vertexBuffer[bufferId].data[vertexIdx].position[1], vertexBuffer[bufferId].data[vertexIdx].position[2] ); } vec2 GetUV(uint bufferId, uint vertexIdx) { if (bufferId == INVALID_HANDLE) { return vec2(0.0f, 0.0f); } else { return vec2( uvBuffer[bufferId].data[vertexIdx].uv[0], uvBuffer[bufferId].data[vertexIdx].uv[1] ); } } layout(set = 1, binding = 0) uniform Camera { mat4 model; mat4 view; mat4 proj; } ubo; layout(push_constant) uniform Block { uint vertexBufferHandle; uint uvBufferHandle; uint materialBufferHandle; uint m_VertexOffset; int m_NormalOffset; // <0 for invalid int m_TexCoord0Offset; // <0 for invalid uint m_FirstIndex; uint m_IndexCount; int m_MaterialIdx; // <0 for invalid } pcb; void main() { outUV = GetUV(pcb.uvBufferHandle, gl_VertexIndex); gl_Position = ubo.proj * ubo.view * ubo.model * vec4(GetPosition(pcb.vertexBufferHandle, gl_VertexIndex), 1.0f); }