1 #ifndef MSP_GL_SHADOWMAP_H_
2 #define MSP_GL_SHADOWMAP_H_
6 #include "framebuffer.h"
7 #include "programdata.h"
15 class DirectionalLight;
20 Creates a depth texture which can be used to add shadows to a renderable.
22 In the setup phase, the scene is rendered from the point of view of the light
23 source and the depth values are recorded. This texture can be used by shaders
24 to determine if the light can reach a particular position.
26 A shadow map can be created as an atlas, containing multiple lights in the same
27 depth texture. Each light is automatically allocated a region of the texture
28 and region information is added to the uniform values.
30 The shader fragment shadow.glsl provides interfaces to access the shadow map.
32 class ShadowMap: public Effect
35 struct Template: Effect::Template
37 class Loader: public DataFile::DerivedObjectLoader<Template, Effect::Template::Loader>
40 static ActionMap shared_actions;
43 Loader(Template &, Collection &);
45 virtual void init_actions();
47 void light(const std::string &);
48 void size_square(unsigned);
49 void target(float, float, float);
54 class Loader: public DataFile::ObjectLoader<ShadowedLight>
57 static ActionMap shared_actions;
60 Loader(ShadowedLight &);
62 virtual void init_actions();
65 const Light *light = 0;
67 std::string shadow_caster_name;
70 unsigned width = 2048;
71 unsigned height = 2048;
72 const Lighting *lighting = 0;
73 std::vector<ShadowedLight> lights;
76 float depth_bias = 4.0f;
77 float darkness = 1.0f;
79 virtual ShadowMap *create(const std::map<std::string, Renderable *> &) const;
97 Renderable *shadow_caster;
102 unsigned light_index;
110 const Lighting *lighting;
111 std::vector<ShadowedLight> lights;
112 std::vector<ShadowView> views;
115 const Sampler &sampler;
118 float depth_bias = 4.0f;
119 float darkness = 1.0f;
121 bool rendered = false;
122 std::string debug_name;
124 ShadowMap(unsigned, unsigned, Renderable &, const Lighting *);
127 /** Creates a shadow map for a single light. */
128 ShadowMap(unsigned size, Renderable &content, const DirectionalLight &, Renderable &caster);
130 /** Creates a shadow map atlas, to which multiple lights can be added. */
131 ShadowMap(unsigned width, unsigned height, Renderable &, const Lighting &);
133 /** Adds a directional light. The shadow map is rendered using an
134 orthogonal projection. */
135 void add_light(const DirectionalLight &, unsigned size, Renderable &caster);
137 /** Adds a point light. The shadow map is rendered using a perspective
138 projection, with four views in a tetrahedral arrangement. The shader must
139 clip vertices appropriately. Occluder_thsm.glsl can be used for this. */
140 void add_light(const PointLight &, unsigned size, Renderable &caster);
142 void add_light(const Light &, unsigned, ShadowType, Renderable &);
145 /** Sets the shadow volume parameters. For directional lights the shadow
146 camera will be positioned so that the spherical shadow volume fits entirely
147 in the view volume. For point lights the shadow volume's radius will be
148 used as the view distance. */
149 void set_target(const Vector3 &, float);
151 /** Sets the darkness of shadows. Must be in the range between 0.0 and 1.0,
152 inclusive. Values other than 1.0 are not physically correct. */
153 void set_darkness(float);
155 /** Sets an offset for depth values to avoid surfaces incorrectly shadowing
156 themselves. Must be positive; values less than 1.0 are not recommended.
157 Larger values produce less artifacts, but may cause shadows to become
158 disconnected from the objects casting them. */
159 void set_depth_bias(float);
161 const Texture2D &get_depth_texture() const { return depth_buf; }
163 virtual void setup_frame(Renderer &);
164 virtual void finish_frame();
166 virtual void render(Renderer &, Tag = Tag()) const;
168 virtual void set_debug_name(const std::string &);