diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-06-02 21:50:04 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-06-03 01:54:01 +0300 |
commit | 0d52f8daea3b6603db83f41aa97fb137b4c97bcc (patch) | |
tree | e67899497e222d332e7fd96eea8dccfb1496ac32 | |
parent | 4bd2de2030f5c655256c9108eef53b536768d9be (diff) |
Eevee: Polishing of Exponential Shadow mapping
Added exponent parameter to tweak light bleeding.
Added depth bias to the shadow test.
Added better blurring using 32 samples.
12 files changed, 86 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 69a2067f4e6..bf4b1b6a680 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -69,6 +69,7 @@ void BKE_lamp_init(Lamp *la) la->bufsize = 512; la->clipsta = 0.5f; la->clipend = 40.0f; + la->bleedexp = 120.0f; la->samp = 3; la->bias = 1.0f; la->soft = 3.0f; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index fa03725fa6f..8ff156d381c 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -31,6 +31,7 @@ #include "DNA_object_types.h" #include "DNA_camera_types.h" #include "DNA_gpu_types.h" +#include "DNA_lamp_types.h" #include "DNA_layer_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -351,6 +352,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) } if (!MAIN_VERSION_ATLEAST(main, 280, 1)) { + if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "bleedexp")) { + for (Lamp *la = main->lamp.first; la; la = la->id.next) { + la->bleedexp = 120.0f; + } + } + if (!DNA_struct_elem_find(fd->filesdna, "GPUDOFSettings", "float", "ratio")) { for (Camera *ca = main->camera.first; ca; ca = ca->id.next) { ca->gpu_dof.ratio = 1.0f; diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 9dd87cc11f3..fc43700bb8c 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -382,6 +382,7 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La evsh->bias = 0.05f * la->bias; evsh->near = la->clipsta; evsh->far = la->clipend; + evsh->exp = la->bleedexp; evli->shadowid = (float)(evsmp->shadow_id); } @@ -732,12 +733,14 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl) /* Render each shadow to one layer of the array */ for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) { EEVEE_LampEngineData *led = eevee_get_lamp_engine_data(ob); + Lamp *la = (Lamp *)ob->data; if (led->need_update) { EEVEE_ShadowCubeData *evscd = (EEVEE_ShadowCubeData *)led->storage; EEVEE_ShadowRender *srd = &linfo->shadow_render_data; srd->layer = i; + srd->exponent = la->bleedexp; copy_v3_v3(srd->position, ob->obmat[3]); for (int j = 0; j < 6; ++j) { copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 454e0925d58..2f7beead1af 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -114,7 +114,7 @@ typedef struct EEVEE_Light { } EEVEE_Light; typedef struct EEVEE_ShadowCube { - float near, far, bias, pad; + float near, far, bias, exp; } EEVEE_ShadowCube; typedef struct EEVEE_ShadowMap { @@ -133,6 +133,7 @@ typedef struct EEVEE_ShadowRender { float position[3]; float pad; int layer; + float exponent; } EEVEE_ShadowRender; /* ************ LIGHT DATA ************* */ diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index a9be6ca5478..8963ad2b93e 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -36,13 +36,14 @@ struct LightData { struct ShadowCubeData { - vec4 near_far_bias; + vec4 near_far_bias_exp; }; /* convenience aliases */ -#define sh_cube_near near_far_bias.x -#define sh_cube_far near_far_bias.y -#define sh_cube_bias near_far_bias.z +#define sh_cube_near near_far_bias_exp.x +#define sh_cube_far near_far_bias_exp.y +#define sh_cube_bias near_far_bias_exp.z +#define sh_cube_exp near_far_bias_exp.w struct ShadowMapData { diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 92069dc37e4..953b087bcd7 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -176,11 +176,11 @@ void light_visibility(LightData ld, ShadingData sd, out float vis) ShadowCubeData scd = shadows_cube_data[int(shid)]; vec3 cubevec = sd.W - ld.l_position; - float dist = length(cubevec); + float dist = length(cubevec) - scd.sh_cube_bias; float z = texture_octahedron(shadowCubes, vec4(cubevec, shid)).r; - float esm_test = min(1.0, exp(-5.0 * dist) * z); + float esm_test = saturate(exp(scd.sh_cube_exp * (z - dist))); float sh_test = step(0, z - dist); vis *= esm_test; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl index 7a8b06e3430..3fc3c146c66 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl @@ -3,6 +3,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; vec4 lampPosition; int layer; + float exponent; }; in vec3 worldPosition; @@ -11,5 +12,5 @@ out vec4 FragColor; void main() { float dist = distance(lampPosition.xyz, worldPosition.xyz); - FragColor = vec4(exp(5.0 * dist), 0.0, 0.0, 1.0); + FragColor = vec4(dist, 0.0, 0.0, 1.0); } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl index 4bd2999787b..afc78c4a8f8 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl @@ -3,6 +3,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; vec4 lampPosition; int layer; + float exponent; }; layout(triangles) in; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl index 67bee97fade..40b980b3904 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl @@ -1,4 +1,11 @@ +layout(std140) uniform shadow_render_block { + mat4 ShadowMatrix[6]; + vec4 lampPosition; + int layer; + float exponent; +}; + uniform samplerCube shadowCube; out vec4 FragColor; @@ -24,6 +31,35 @@ void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) B = cross(N, T); } +#define NUM_SAMPLE 32 +vec2 poisson_disc[32] = vec2[32]( + vec2( 0.476, 0.854), vec2(-0.659, -0.670), + vec2( 0.905, -0.270), vec2( 0.215, -0.133), + vec2(-0.595, 0.242), vec2(-0.146, 0.519), + vec2( 0.108, -0.930), vec2( 0.807, 0.449), + + vec2(-0.476, -0.854), vec2( 0.659, 0.670), + vec2(-0.905, 0.270), vec2(-0.215, 0.133), + vec2( 0.595, -0.242), vec2( 0.146, -0.519), + vec2(-0.108, 0.930), vec2(-0.807, -0.449), + + vec2(-0.854, 0.476), vec2( 0.670, -0.659), + vec2( 0.270, 0.905), vec2( 0.133, 0.215), + vec2(-0.242, -0.595), vec2(-0.519, -0.146), + vec2( 0.930, 0.108), vec2(-0.449, 0.807), + + vec2( 0.854, -0.476), vec2(-0.670, 0.659), + vec2(-0.270, -0.905), vec2(-0.133, -0.215), + vec2( 0.242, 0.595), vec2( 0.519, 0.146), + vec2(-0.930, -0.108), vec2( 0.449, -0.807) +); + +/* Marco Salvi's GDC 2008 presentation about shadow maps pre-filtering techniques slide 24 */ +float ln_space_prefilter(float w0, float x, float w1, float y) +{ + return x + log(w0 + w1 * exp(y - x)); +} + void main() { const vec2 texelSize = vec2(1.0 / 512.0); @@ -52,13 +88,25 @@ void main() { vec3 T, B; make_orthonormal_basis(cubevec, T, B); - vec2 offsetvec = texelSize.xy * vec2(-1.0, 1.0); /* Totally arbitrary */ - /* get cubemap shadow value */ - FragColor = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.x * B).rrrr; - FragColor += texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).rrrr; - FragColor += texture(shadowCube, cubevec + offsetvec.y * T + offsetvec.x * B).rrrr; - FragColor += texture(shadowCube, cubevec + offsetvec.y * T + offsetvec.y * B).rrrr; + const float blur_radius = 5.0 / 512.0; /* Totally arbitrary */ + const float weight = 1.0 / float(NUM_SAMPLE); + float accum = 0.0; + + /* Poisson disc blur in log space. */ + vec2 offsetvec = poisson_disc[0].xy * blur_radius; + float depth1 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r; + + offsetvec = poisson_disc[1].xy * blur_radius; + float depth2 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r; + + accum = ln_space_prefilter(weight, depth1, weight, depth2); + + for (int i = 2; i < NUM_SAMPLE; ++i) { + vec2 offsetvec = poisson_disc[i].xy * blur_radius; + depth1 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r; + accum = ln_space_prefilter(1.0, accum, weight, depth1); + } - FragColor /= 4.0; + FragColor = vec4(accum, accum, accum, 1.0); }
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl index f14354ad4cd..1d456095e02 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl @@ -3,6 +3,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; vec4 lampPosition; int layer; + float exponent; }; layout(triangles) in; diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index a2e39f93875..cb5b44f3268 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -67,7 +67,7 @@ typedef struct Lamp { short pad2; float clipsta, clipend; - float bias, soft, compressthresh, bleedbias, pad5; + float bias, soft, compressthresh, bleedbias, bleedexp; short bufsize, samp, buffers, filtertype; char bufflag, buftype; diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 86edd68784c..83c373d151d 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -596,6 +596,12 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) RNA_def_property_ui_text(prop, "Shadow Buffer Bleed Bias", "Bias for reducing light-bleed on variance shadow maps"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); + prop = RNA_def_property(srna, "shadow_buffer_exp", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "bleedexp"); + RNA_def_property_range(prop, 1.0f, 9999.0f); + RNA_def_property_ui_text(prop, "Shadow Buffer Exponent", "Bias for reducing light-bleed on exponential shadow maps"); + RNA_def_property_update(prop, 0, "rna_Lamp_update"); + prop = RNA_def_property(srna, "shadow_buffer_soft", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "soft"); RNA_def_property_range(prop, 0.0f, 100.0f); |