#version 450 const int MAX_TEXTURES = 512; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; layout(location = 1) out vec4 outAlbedo ; layout(location = 0) out vec4 outPos; layout(location = 2) out vec4 outNormal; layout(location = 3) out vec4 outPBR; struct Material { vec4 diffuseColor; uint hasTexture; uint textureIdx; uint hasNormalMap; uint normalMapIdx; uint hasRoughMap; uint roughMapIdx; float roughnessFactor; float metallicFactor; }; layout(set = 2, binding = 0) readonly buffer MaterialUniform { Material materials[]; } matUniform; layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES]; vec3 calcNormal(Material material, vec3 normal, vec2 textCoords, mat3 TBN) { vec3 newNormal = normal; if (material.hasNormalMap > 0) { newNormal = texture(textSampler[material.normalMapIdx], textCoords).rgb; newNormal = normalize(newNormal * 2.0 - 1.0); newNormal = normalize(TBN * newNormal); } return newNormal; } layout(push_constant) uniform pc { layout(offset = 64) uint materialIdx; } push_constants; void main() { outPos = inPos; Material material = matUniform.materials[push_constants.materialIdx]; if (material.hasTexture == 1) { outAlbedo = texture(textSampler[material.textureIdx], inTextCoords); } else { outAlbedo = material.diffuseColor; } if(outAlbedo.a < 0.5) discard; mat3 TBN = mat3(inTangent, inBitangent, inNormal); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); outNormal = vec4(newNormal, 1.0f); float ao = 0.5f; float roughnessFactor = 0.0f; float metallicFactor = 0.0f; if (material.hasRoughMap > 0) { vec4 metRoughValue = texture(textSampler[material.roughMapIdx], inTextCoords); roughnessFactor = metRoughValue.g; metallicFactor = metRoughValue.b; } else { roughnessFactor = material.roughnessFactor; metallicFactor = material.metallicFactor; } outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f); }