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