#version 450 layout(location = 0) out vec4 outPos; layout(location = 1) out vec3 outNormal; layout(location = 2) out vec3 outTangent; layout(location = 3) out vec3 outBitangent; layout(location = 4) out vec2 outTextCoords; layout(location = 5) out mat4 viewMatrix; layout(set = 0, binding = 0) uniform ProjUniform { mat4 matrix; } projUniform; layout(set = 1, binding = 0) uniform ViewUniform { mat4 matrix; } viewUniform; layout(set = 4, binding = 0) readonly buffer FaceBuffer { uint faces[]; }; layout(push_constant) uniform pc { vec4 ModelOffset; vec4 Padding0; vec4 Padding1; vec4 Padding2; } push_constants; const uint TRI_TO_CORNER[6] = uint[6](0u, 1u, 2u, 0u, 2u, 3u); const vec3 NORMALS[8] = vec3[8]( vec3( 0.0, 1.0, 0.0), // Face 0 (+Y) vec3( 0.0, -1.0, 0.0), // Face 1 (-Y) vec3( 1.0, 0.0, 0.0), // Face 2 (+X) vec3(-1.0, 0.0, 0.0), // Face 3 (-X) vec3( 0.0, 0.0, 1.0), // Face 4 (+Z) vec3( 0.0, 0.0, -1.0), // Face 5 (-Z) vec3(-0.7071, 0.0, 0.7071), // Face 6 vec3( 0.7071, 0.0, 0.7071) // Face 7 ); const vec3 TANGENTS[8] = vec3[8]( vec3( 1.0, 0.0, 0.0), // Face 0 vec3( 1.0, 0.0, 0.0), // Face 1 vec3( 0.0, 0.0, -1.0), // Face 2 vec3( 0.0, 0.0, 1.0), // Face 3 vec3( 1.0, 0.0, 0.0), // Face 4 vec3(-1.0, 0.0, 0.0), // Face 5 vec3( 0.7071, 0.0, 0.7071), // Face 6 vec3( 0.7071, 0.0,-0.7071) // Face 7 ); const vec3 BITANGENTS[8] = vec3[8]( vec3( 0.0, 0.0, 1.0), // Face 0 vec3( 0.0, 0.0, -1.0), // Face 1 vec3( 0.0, 1.0, 0.0), // Face 2 vec3( 0.0, 1.0, 0.0), // Face 3 vec3( 0.0, 1.0, 0.0), // Face 4 vec3( 0.0, 1.0, 0.0), // Face 5 vec3( 0.0, 1.0, 0.0), // Face 6 vec3( 0.0, 1.0, 0.0) // Face 7 ); const vec2 CORNER_UVS[5][4] = vec2[5][4]( vec2[4](vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)), vec2[4](vec2(0.0, 0.5), vec2(0.0, 1.0), vec2(0.5, 1.0), vec2(0.5, 0.5)), vec2[4](vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)), vec2[4](vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)), vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.5), vec2(0.5, 0.5), vec2(0.5, 1.0)) ); const vec2 CORNER_UVS_GRASS_BLOCK[8][4] = vec2[8][4]( vec2[4](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)), vec2[4](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)), vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0), vec2(0.0, 1.0)), vec2[4]( vec2(0.0, 1.0),vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0)), vec2[4]( vec2(0.0, 1.0),vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0)), vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0), vec2(0.0, 1.0)), vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 1.0)), vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 1.0)) ); const vec3 FACE_CORNERS[8][4] = vec3[8][4]( vec3[4](vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0)), // Face 0 (+Y) vec3[4](vec3(0.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0)), // Face 1 (-Y) vec3[4](vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0)), // Face 2 (+X) vec3[4](vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0), vec3(0.0, 1.0, 0.0)), // Face 3 (-X) vec3[4](vec3(0.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), vec3(1.0, 1.0, 1.0), vec3(0.0, 1.0, 1.0)), // Face 4 (+Z) vec3[4](vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)), // Face 5 (-Z) vec3[4](vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0)), // Face 6 (cross model pane 1) vec3[4](vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)) // Face 7 (cross model pane 2) ); void main() { viewMatrix = viewUniform.matrix; uint faceRecordIndex = uint(gl_VertexIndex) / 6u; uint triangleVertex = (uint(gl_VertexIndex))% 6u; uint cornerIndex = TRI_TO_CORNER[triangleVertex]; //uint faceRecordIndex = uint(gl_VertexIndex) / 6u; //uint triangleVertex = uint(gl_VertexIndex) % 6u; //uint cornerIndex = TRI_TO_CORNER[triangleVertex]; uint packedFace = faces[faceRecordIndex]; uint voxelX = packedFace & 0x1Fu; uint voxelY = (packedFace >> 5u) & 0x1Fu; uint voxelZ = (packedFace >> 10u) & 0x1Fu; uint faceId = (packedFace >> 15u) & 0x7u; uint matId = (packedFace >> 18u) & 0xFFu; uint texIdxX = (packedFace >> 26u) & 0x7u; uint texIdxY = (packedFace >> 29u) & 0x7u; vec2 texID = vec2((texIdxX)/4.0,(texIdxY)/4.0); vec2 scalar = vec2(1.0/4.0,1.0/4.0); faceId = min(faceId, 7u); matId = min(matId, 4u); vec3 localPos = vec3(voxelX, voxelY, voxelZ) + FACE_CORNERS[faceId][cornerIndex]; vec3 worldPos = localPos + push_constants.ModelOffset.xyz * 16.0; vec4 worldPosVec4 = vec4(worldPos, 1.0); gl_Position = projUniform.matrix * viewUniform.matrix * worldPosVec4; outPos = worldPosVec4; outNormal = NORMALS[faceId]; outTangent = TANGENTS[faceId]; outBitangent = BITANGENTS[faceId]; outTextCoords = CORNER_UVS_GRASS_BLOCK[faceId][cornerIndex] * scalar + texID; }