1$input v_texcoord0 2 3/* 4 * Copyright 2016 Joseph Cherlin. All rights reserved. 5 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 6 */ 7 8#include "../common/common.sh" 9 10SAMPLER2D(s_normal, 0); 11SAMPLER2D(s_color, 1); 12SAMPLER2D(s_light, 2); 13SAMPLER2D(s_depth, 3); 14SAMPLER2DSHADOW(s_shadowMap, 4); 15 16// Single directional light for entire scene 17uniform vec4 u_lightDir; 18uniform mat4 u_invMvp; 19uniform mat4 u_lightMtx; 20uniform vec4 u_shadowDimsInv; 21uniform vec4 u_rsmAmount; 22 23float hardShadow(sampler2DShadow _sampler, vec4 _shadowCoord, float _bias) 24{ 25 vec2 texCoord = _shadowCoord.xy; 26 return shadow2D(_sampler, vec3(texCoord.xy, _shadowCoord.z-_bias) ); 27} 28 29float PCF(sampler2DShadow _sampler, vec4 _shadowCoord, float _bias, vec2 _texelSize) 30{ 31 vec2 texCoord = _shadowCoord.xy; 32 33 bool outside = any(greaterThan(texCoord, vec2_splat(1.0))) 34 || any(lessThan (texCoord, vec2_splat(0.0))) 35 ; 36 37 if (outside) 38 { 39 return 1.0; 40 } 41 42 float result = 0.0; 43 vec2 offset = _texelSize * _shadowCoord.w; 44 45 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, -1.5) * offset, 0.0, 0.0), _bias); 46 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, -0.5) * offset, 0.0, 0.0), _bias); 47 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, 0.5) * offset, 0.0, 0.0), _bias); 48 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, 1.5) * offset, 0.0, 0.0), _bias); 49 50 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, -1.5) * offset, 0.0, 0.0), _bias); 51 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, -0.5) * offset, 0.0, 0.0), _bias); 52 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, 0.5) * offset, 0.0, 0.0), _bias); 53 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, 1.5) * offset, 0.0, 0.0), _bias); 54 55 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, -1.5) * offset, 0.0, 0.0), _bias); 56 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, -0.5) * offset, 0.0, 0.0), _bias); 57 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, 0.5) * offset, 0.0, 0.0), _bias); 58 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, 1.5) * offset, 0.0, 0.0), _bias); 59 60 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, -1.5) * offset, 0.0, 0.0), _bias); 61 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, -0.5) * offset, 0.0, 0.0), _bias); 62 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, 0.5) * offset, 0.0, 0.0), _bias); 63 result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, 1.5) * offset, 0.0, 0.0), _bias); 64 65 return result / 16.0; 66} 67 68 69float toClipSpaceDepth(float _depthTextureZ) 70{ 71#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL 72 return _depthTextureZ; 73#else 74 return _depthTextureZ * 2.0 - 1.0; 75#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL 76} 77 78vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) 79{ 80 vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); 81 return wpos.xyz / wpos.w; 82} 83 84void main() 85{ 86 vec3 n = texture2D(s_normal, v_texcoord0).xyz; 87 // Expand out normal 88 n = n*2.0+-1.0; 89 vec3 l = u_lightDir.xyz;//normalize(vec3(-0.8,0.75,-1.0)); 90 float dirLightIntensity = 1.0; 91 float dirLight = max(0.0,dot(n,l)) * dirLightIntensity; 92 93 // Apply shadow map 94 95 // Get world position so we can transform it into light space, to look into shadow map 96 vec2 texCoord = v_texcoord0.xy; 97 float deviceDepth = texture2D(s_depth, texCoord).x; 98 float depth = toClipSpaceDepth(deviceDepth); 99 vec3 clip = vec3(texCoord * 2.0 - 1.0, depth); 100#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL 101 clip.y = -clip.y; 102#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL 103 vec3 wpos = clipToWorld(u_invMvp, clip); 104 105 const float shadowMapOffset = 0.003; 106 vec3 posOffset = wpos + n.xyz * shadowMapOffset; 107 vec4 shadowCoord = mul(u_lightMtx, vec4(posOffset, 1.0) ); 108 109#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL 110 shadowCoord.y *= -1.0; 111#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL 112 113 float shadowMapBias = 0.001; 114 vec2 texelSize = vec2_splat(u_shadowDimsInv.x); 115 116 shadowCoord.xy /= shadowCoord.w; 117 shadowCoord.xy = shadowCoord.xy*0.5 + 0.5; 118 119#if BGFX_SHADER_LANGUAGE_GLSL 120 shadowCoord.z = shadowCoord.z*0.5 + 0.5; 121#endif // BGFX_SHADER_LANGUAGE_GLSL 122 123 float visibility = PCF(s_shadowMap, shadowCoord, shadowMapBias, texelSize); 124 125 dirLight *= visibility; 126 127 // Light from light buffer 128 vec3 albedo = texture2D(s_color, v_texcoord0).xyz; 129 vec3 lightBuffer = texture2D(s_light, v_texcoord0).xyz; 130 131 gl_FragColor.xyz = mix(dirLight * albedo, lightBuffer * albedo, u_rsmAmount.x); 132 133 gl_FragColor.w = 1.0; 134} 135