mirror of https://github.com/bkaradzic/bgfx
135 lines
4.6 KiB
Scala
135 lines
4.6 KiB
Scala
$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;
|
|
}
|