parent
ad10bda37e
commit
68d9fd2138
@ -11,6 +11,7 @@ uniform float split1;
|
||||
uniform float split2;
|
||||
uniform float splitmax;
|
||||
uniform float shadow_res;
|
||||
uniform float overlap_proportion;
|
||||
|
||||
uniform vec3 sundirection;
|
||||
uniform vec3 sun_color;
|
||||
@ -30,25 +31,56 @@ out vec4 Spec;
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
#stk_include "utils/SunMRP.frag"
|
||||
|
||||
float getShadowFactor(vec3 pos, int index)
|
||||
// https://web.archive.org/web/20230210095515/http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1
|
||||
float getShadowFactor(vec3 pos, int index, float bias)
|
||||
{
|
||||
vec4 shadowcoord = (u_shadow_projection_view_matrices[index] * u_inverse_view_matrix * vec4(pos, 1.0));
|
||||
shadowcoord.xy /= shadowcoord.w;
|
||||
vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5;
|
||||
//float d = .5 * shadowcoord.z + .5;
|
||||
float d = .5 * shadowcoord.z + .5 - 1. / (shadow_res * 5.);
|
||||
float d = .5 * shadowcoord.z + .5 - bias;
|
||||
|
||||
float result = 0.;
|
||||
vec2 uv = shadowtexcoord * shadow_res;
|
||||
vec2 base_uv = floor(uv + 0.5);
|
||||
float s = (uv.x + 0.5 - base_uv.x);
|
||||
float t = (uv.y + 0.5 - base_uv.y);
|
||||
base_uv -= 0.5;
|
||||
base_uv /= shadow_res;
|
||||
|
||||
for (float i = -1.; i <= 1.; i += 1.)
|
||||
{
|
||||
for (float j = -1.; j <= 1.; j += 1.)
|
||||
{
|
||||
result += texture(shadowtex, vec4(shadowtexcoord + vec2(i,j) / shadow_res, float(index), d));
|
||||
}
|
||||
}
|
||||
float uw0 = (4.0 - 3.0 * s);
|
||||
float uw1 = 7.0;
|
||||
float uw2 = (1.0 + 3.0 * s);
|
||||
|
||||
return result / 9.;
|
||||
float u0 = (3.0 - 2.0 * s) / uw0 - 2.0;
|
||||
float u1 = (3.0 + s) / uw1;
|
||||
float u2 = s / uw2 + 2.0;
|
||||
|
||||
float vw0 = (4.0 - 3.0 * t);
|
||||
float vw1 = 7.0;
|
||||
float vw2 = (1.0 + 3.0 * t);
|
||||
|
||||
float v0 = (3.0 - 2.0 * t) / vw0 - 2.0;
|
||||
float v1 = (3.0 + t) / vw1;
|
||||
float v2 = t / vw2 + 2.0;
|
||||
|
||||
float sum = 0.0;
|
||||
|
||||
sum += uw0 * vw0 * texture(shadowtex, vec4(base_uv + (vec2(u0, v0) / shadow_res), float(index), d));
|
||||
sum += uw1 * vw0 * texture(shadowtex, vec4(base_uv + (vec2(u1, v0) / shadow_res), float(index), d));
|
||||
sum += uw2 * vw0 * texture(shadowtex, vec4(base_uv + (vec2(u2, v0) / shadow_res), float(index), d));
|
||||
|
||||
sum += uw0 * vw1 * texture(shadowtex, vec4(base_uv + (vec2(u0, v1) / shadow_res), float(index), d));
|
||||
sum += uw1 * vw1 * texture(shadowtex, vec4(base_uv + (vec2(u1, v1) / shadow_res), float(index), d));
|
||||
sum += uw2 * vw1 * texture(shadowtex, vec4(base_uv + (vec2(u2, v1) / shadow_res), float(index), d));
|
||||
|
||||
sum += uw0 * vw2 * texture(shadowtex, vec4(base_uv + (vec2(u0, v2) / shadow_res), float(index), d));
|
||||
sum += uw1 * vw2 * texture(shadowtex, vec4(base_uv + (vec2(u1, v2) / shadow_res), float(index), d));
|
||||
sum += uw2 * vw2 * texture(shadowtex, vec4(base_uv + (vec2(u2, v2) / shadow_res), float(index), d));
|
||||
|
||||
return sum / 144.0;
|
||||
}
|
||||
|
||||
float blend_start(float x) {
|
||||
return x * (1.0 - overlap_proportion);
|
||||
}
|
||||
|
||||
void main() {
|
||||
@ -68,16 +100,30 @@ void main() {
|
||||
|
||||
// Shadows
|
||||
float factor;
|
||||
if (xpos.z < split0)
|
||||
factor = getShadowFactor(xpos.xyz, 0);
|
||||
else if (xpos.z < split1)
|
||||
factor = getShadowFactor(xpos.xyz, 1);
|
||||
else if (xpos.z < split2)
|
||||
factor = getShadowFactor(xpos.xyz, 2);
|
||||
else if (xpos.z < splitmax)
|
||||
factor = getShadowFactor(xpos.xyz, 3);
|
||||
else
|
||||
float bias = max(1.0 - NdotL, .2) / shadow_res;
|
||||
if (xpos.z < split0) {
|
||||
factor = getShadowFactor(xpos.xyz, 0, bias);
|
||||
if (xpos.z > blend_start(split0)) {
|
||||
factor = mix(factor, getShadowFactor(xpos.xyz, 1, bias), (xpos.z - blend_start(split0)) / split0 / overlap_proportion);
|
||||
}
|
||||
} else if (xpos.z < split1) {
|
||||
factor = getShadowFactor(xpos.xyz, 1, bias);
|
||||
if (xpos.z > blend_start(split1)) {
|
||||
factor = mix(factor, getShadowFactor(xpos.xyz, 2, bias), (xpos.z - blend_start(split1)) / split1 / overlap_proportion);
|
||||
}
|
||||
} else if (xpos.z < split2) {
|
||||
factor = getShadowFactor(xpos.xyz, 2, bias);
|
||||
if (xpos.z > blend_start(split2)) {
|
||||
factor = mix(factor, getShadowFactor(xpos.xyz, 3, bias), (xpos.z - blend_start(split2)) / split2 / overlap_proportion);
|
||||
}
|
||||
} else if (xpos.z < splitmax) {
|
||||
factor = getShadowFactor(xpos.xyz, 3, bias);
|
||||
if (xpos.z > blend_start(splitmax)) {
|
||||
factor = mix(factor, 1.0, (xpos.z - blend_start(splitmax)) / splitmax / overlap_proportion);
|
||||
}
|
||||
} else {
|
||||
factor = 1.;
|
||||
}
|
||||
|
||||
Diff = vec4(factor * NdotL * Diffuse * sun_color, 1.);
|
||||
Spec = vec4(factor * NdotL * Specular * sun_color, 1.);
|
||||
|
@ -201,7 +201,7 @@ public:
|
||||
// ============================================================================
|
||||
class ShadowedSunLightShaderPCF : public TextureShader<ShadowedSunLightShaderPCF,
|
||||
3, float, float, float,
|
||||
float, float,
|
||||
float, float, float,
|
||||
core::vector3df, video::SColorf>
|
||||
{
|
||||
public:
|
||||
@ -215,7 +215,7 @@ public:
|
||||
1, "dtex", ST_NEAREST_FILTERED,
|
||||
8, "shadowtex", ST_SHADOW_SAMPLER);
|
||||
assignUniforms("split0", "split1", "split2", "splitmax", "shadow_res",
|
||||
"sundirection", "sun_color");
|
||||
"overlap_proportion", "sundirection", "sun_color");
|
||||
} // ShadowedSunLightShaderPCF
|
||||
// ------------------------------------------------------------------------
|
||||
void render(GLuint normal_depth_texture,
|
||||
@ -232,6 +232,7 @@ public:
|
||||
ShadowMatrices::m_shadow_split[3],
|
||||
ShadowMatrices::m_shadow_split[4],
|
||||
float(UserConfigParams::m_shadows_resolution),
|
||||
ShadowMatrices::m_shadow_overlap_proportion,
|
||||
direction, col);
|
||||
|
||||
} // render
|
||||
|
@ -77,26 +77,6 @@ public:
|
||||
} // render
|
||||
}; // Gaussian3HBlurShader
|
||||
|
||||
// ============================================================================
|
||||
class ComputeShadowBlurVShader : public TextureShader<ComputeShadowBlurVShader, 1,
|
||||
core::vector2df,
|
||||
std::vector<float> >
|
||||
{
|
||||
public:
|
||||
GLuint m_dest_tu;
|
||||
ComputeShadowBlurVShader()
|
||||
{
|
||||
#if !defined(USE_GLES2)
|
||||
loadProgram(OBJECT, GL_COMPUTE_SHADER, "blurshadowV.comp");
|
||||
m_dest_tu = 1;
|
||||
assignUniforms("pixel", "weights");
|
||||
assignSamplerNames(0, "source", ST_NEARED_CLAMPED_FILTERED);
|
||||
assignTextureUnit(m_dest_tu, "dest");
|
||||
#endif
|
||||
} // ComputeShadowBlurVShader
|
||||
|
||||
}; // ComputeShadowBlurVShader
|
||||
|
||||
// ============================================================================
|
||||
class Gaussian6VBlurShader : public TextureShader<Gaussian6VBlurShader, 1,
|
||||
core::vector2df, float>
|
||||
@ -174,23 +154,6 @@ public:
|
||||
assignTextureUnit(m_dest_tu, "dest");
|
||||
} // ComputeGaussian6HBlurShader
|
||||
}; // ComputeGaussian6HBlurShader
|
||||
|
||||
// ============================================================================
|
||||
class ComputeShadowBlurHShader : public TextureShader<ComputeShadowBlurHShader, 1,
|
||||
core::vector2df,
|
||||
std::vector<float> >
|
||||
{
|
||||
public:
|
||||
GLuint m_dest_tu;
|
||||
ComputeShadowBlurHShader()
|
||||
{
|
||||
loadProgram(OBJECT, GL_COMPUTE_SHADER, "blurshadowH.comp");
|
||||
m_dest_tu = 1;
|
||||
assignUniforms("pixel", "weights");
|
||||
assignSamplerNames(0, "source", ST_NEARED_CLAMPED_FILTERED);
|
||||
assignTextureUnit(m_dest_tu, "dest");
|
||||
} // ComputeShadowBlurHShader
|
||||
}; // ComputeShadowBlurHShader
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
||||
|
@ -39,7 +39,8 @@
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
float ShadowMatrices:: m_shadow_split[5] = { 1., 5., 20., 50., 150 };
|
||||
float ShadowMatrices:: m_shadow_split[5] = { 1., 5., 20., 60., 150 };
|
||||
float ShadowMatrices:: m_shadow_overlap_proportion = 0.2;
|
||||
|
||||
// ============================================================================
|
||||
class ViewFrustrumShader : public Shader<ViewFrustrumShader, video::SColor, int>
|
||||
@ -236,9 +237,9 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca
|
||||
float NearValues[] =
|
||||
{
|
||||
ShadowMatrices::m_shadow_split[0],
|
||||
ShadowMatrices::m_shadow_split[1],
|
||||
ShadowMatrices::m_shadow_split[2],
|
||||
ShadowMatrices::m_shadow_split[3]
|
||||
ShadowMatrices::m_shadow_split[1] * (1.0f - m_shadow_overlap_proportion),
|
||||
ShadowMatrices::m_shadow_split[2] * (1.0f - m_shadow_overlap_proportion),
|
||||
ShadowMatrices::m_shadow_split[3] * (1.0f - m_shadow_overlap_proportion)
|
||||
};
|
||||
|
||||
// Shadow Matrixes and cameras
|
||||
|
@ -40,6 +40,7 @@ class ShadowMatrices
|
||||
{
|
||||
public:
|
||||
static float m_shadow_split[5];
|
||||
static float m_shadow_overlap_proportion;
|
||||
|
||||
private:
|
||||
std::vector<core::matrix4> m_sun_ortho_matrices;
|
||||
|
Loading…
Reference in New Issue
Block a user