#version 330 core #extension GL_ARB_shading_language_420pack: require #define float2 vec2 #define float3 vec3 #define float4 vec4 #define int2 ivec2 #define int3 ivec3 #define int4 ivec4 #define uint2 uvec2 #define uint3 uvec3 #define uint4 uvec4 #define float3x3 mat3 #define float4x4 mat4 out gl_PerVertex { vec4 gl_Position; }; layout(std140) uniform; mat4 UNPACK_MAT4( samplerBuffer matrixBuf, uint pixelIdx ) { vec4 row0 = texelFetch( matrixBuf, int((pixelIdx) << 2u) ); vec4 row1 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 1u) ); vec4 row2 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 2u) ); vec4 row3 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 3u) ); return mat4( row0, row1, row2, row3 ); } mat3x4 UNPACK_MAT3x4( samplerBuffer matrixBuf, uint pixelIdx ) { vec4 row0 = texelFetch( matrixBuf, int((pixelIdx) << 2u) ); vec4 row1 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 1u) ); vec4 row2 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 2u) ); return mat3x4( row0, row1, row2 ); } in vec4 vertex; in vec4 qtangent; in vec2 uv0; in uint drawId; out block { flat uint drawId; vec3 pos; vec3 normal; vec2 uv0; vec4 posL0; vec4 posL1; float depth; } outVs; // START UNIFORM DECLARATION struct ShadowReceiverData { mat4 texViewProj; vec2 shadowDepthRange; vec4 invShadowMapSize; }; struct Light { vec3 position; vec3 diffuse; vec3 specular; vec3 attenuation; vec3 spotDirection; vec3 spotParams; }; //Uniforms that change per pass layout(binding = 0) uniform PassBuffer { //Vertex shader (common to both receiver and casters) mat4 viewProj; //Vertex shader mat4 view; ShadowReceiverData shadowRcv[2]; //------------------------------------------------------------------------- //Pixel shader mat3 invViewMatCubemap; float pssmSplitPoints0; float pssmSplitPoints1; Light lights[1]; } pass; layout(binding = 0) uniform samplerBuffer worldMatBuf; // END UNIFORM DECLARATION vec3 xAxis( vec4 qQuat ) { float fTy = 2.0 * qQuat.y; float fTz = 2.0 * qQuat.z; float fTwy = fTy * qQuat.w; float fTwz = fTz * qQuat.w; float fTxy = fTy * qQuat.x; float fTxz = fTz * qQuat.x; float fTyy = fTy * qQuat.y; float fTzz = fTz * qQuat.z; return vec3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); } //SkeletonTransform // !hlms_skeleton void main() { mat3x4 worldMat = UNPACK_MAT3x4( worldMatBuf, drawId << 1u); mat4 worldView = UNPACK_MAT4( worldMatBuf, (drawId << 1u) + 1u ); vec4 worldPos = vec4( (vertex * worldMat).xyz, 1.0f ); //Decode qTangent to TBN with reflection vec3 normal = xAxis( normalize( qtangent ) ); //Lighting is in view space outVs.pos = (vertex * worldView).xyz; outVs.normal = normal * mat3(worldView); gl_Position = worldPos * pass.viewProj; outVs.posL0 = vec4(worldPos.xyz, 1.0f) * pass.shadowRcv[0].texViewProj; outVs.posL1 = vec4(worldPos.xyz, 1.0f) * pass.shadowRcv[1].texViewProj; outVs.posL0.z = outVs.posL0.z * pass.shadowRcv[0].shadowDepthRange.y; outVs.posL0.z = (outVs.posL0.z * 0.5) + 0.5; outVs.posL1.z = outVs.posL1.z * pass.shadowRcv[1].shadowDepthRange.y; outVs.posL1.z = (outVs.posL1.z * 0.5) + 0.5; outVs.depth = gl_Position.z; /// hlms_uv_count will be 0 on shadow caster passes w/out alpha test outVs.uv0 = uv0; outVs.drawId = drawId; }