From cdedbb34eff07f188c536167592958e315d53a9b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 11 Oct 2021 15:40:22 +0300 Subject: [PATCH] Suppoer per-light shadow casters in ShadowMap Different types of lights may require different shaders for rendering shadow maps, or it may be desirable to use different occluder geometry for far away lights than close ones. --- source/effects/shadowmap.cpp | 19 ++++++++++--------- source/effects/shadowmap.h | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/source/effects/shadowmap.cpp b/source/effects/shadowmap.cpp index bfb05342..74dad5e7 100644 --- a/source/effects/shadowmap.cpp +++ b/source/effects/shadowmap.cpp @@ -11,12 +11,11 @@ using namespace std; namespace Msp { namespace GL { -ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting *l, Renderable &c): +ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting *l): Effect(r), width(w), height(h), lighting(l), - shadow_caster(c), sampler(Resources::get_global().get("_linear_clamp_shadow.samp")) { depth_buf.storage(DEPTH_COMPONENT32F, width, height, 1); @@ -35,16 +34,16 @@ ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting *l, R } ShadowMap::ShadowMap(unsigned s, Renderable &r, const DirectionalLight &l, Renderable &c): - ShadowMap(s, s, r, 0, c) + ShadowMap(s, s, r, 0) { - add_light(l, s); + add_light(l, s, c); } -ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting &l, Renderable &c): - ShadowMap(w, h, r, &l, c) +ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting &l): + ShadowMap(w, h, r, &l) { } -void ShadowMap::add_light(const DirectionalLight &light, unsigned s) +void ShadowMap::add_light(const DirectionalLight &light, unsigned s, Renderable &c) { if(!lighting && !lights.empty()) throw invalid_operation("ShadowMap::add_light"); @@ -90,6 +89,7 @@ void ShadowMap::add_light(const DirectionalLight &light, unsigned s) sl.light = &light; sl.index = index; sl.region = region; + sl.shadow_caster = &c; string base = format("shadows[%d]", index); shdata.uniform(base+".enabled", 1); @@ -138,7 +138,8 @@ void ShadowMap::setup_frame(Renderer &renderer) rendered = true; renderable.setup_frame(renderer); - shadow_caster.setup_frame(renderer); + for(const ShadowedLight &l: lights) + l.shadow_caster->setup_frame(renderer); for(ShadowedLight &l: lights) { @@ -163,7 +164,7 @@ void ShadowMap::setup_frame(Renderer &renderer) renderer.set_scissor(&l.region); renderer.set_camera(l.shadow_camera); - renderer.render(shadow_caster); + renderer.render(*light.shadow_caster); } } diff --git a/source/effects/shadowmap.h b/source/effects/shadowmap.h index 611f56f5..6c4e1e50 100644 --- a/source/effects/shadowmap.h +++ b/source/effects/shadowmap.h @@ -30,13 +30,13 @@ private: unsigned index; Rect region; Camera shadow_camera; + Renderable *shadow_caster; }; unsigned width; unsigned height; const Lighting *lighting; std::vector lights; - Renderable &shadow_caster; Framebuffer fbo; Texture2D depth_buf; const Sampler &sampler; @@ -48,12 +48,12 @@ private: bool rendered = false; std::string debug_name; - ShadowMap(unsigned, unsigned, Renderable &, const Lighting *, Renderable &); + ShadowMap(unsigned, unsigned, Renderable &, const Lighting *); public: ShadowMap(unsigned, Renderable &, const DirectionalLight &, Renderable &); - ShadowMap(unsigned, unsigned, Renderable &, const Lighting &, Renderable &); + ShadowMap(unsigned, unsigned, Renderable &, const Lighting &); - void add_light(const DirectionalLight &, unsigned); + void add_light(const DirectionalLight &, unsigned, Renderable &); /** Sets the ShadowMap target point and radius. The transformation matrix is computed so that a sphere with the specified parameters will be completely -- 2.43.0