]> git.tdb.fi Git - libs/gl.git/blob - source/effects/shadowmap.h
Minor tweaks to MemoryAllocator
[libs/gl.git] / source / effects / shadowmap.h
1 #ifndef MSP_GL_SHADOWMAP_H_
2 #define MSP_GL_SHADOWMAP_H_
3
4 #include "camera.h"
5 #include "effect.h"
6 #include "framebuffer.h"
7 #include "programdata.h"
8 #include "rect.h"
9 #include "texture2d.h"
10 #include "vector.h"
11
12 namespace Msp {
13 namespace GL {
14
15 class DirectionalLight;
16 class Light;
17 class PointLight;
18
19 /**
20 Creates a depth texture which can be used to add shadows to a renderable.
21
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.
25
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.
29
30 The shader fragment shadow.glsl provides interfaces to access the shadow map.
31 */
32 class ShadowMap: public Effect
33 {
34 public:
35         struct Template: Effect::Template
36         {
37                 class Loader: public DataFile::DerivedObjectLoader<Template, Effect::Template::Loader>
38                 {
39                 private:
40                         static ActionMap shared_actions;
41
42                 public:
43                         Loader(Template &, Collection &);
44                 private:
45                         virtual void init_actions();
46
47                         void light(const std::string &);
48                         void size_square(unsigned);
49                         void target(float, float, float);
50                 };
51
52                 struct ShadowedLight
53                 {
54                         class Loader: public DataFile::ObjectLoader<ShadowedLight>
55                         {
56                         private:
57                                 static ActionMap shared_actions;
58
59                         public:
60                                 Loader(ShadowedLight &);
61                         private:
62                                 virtual void init_actions();
63                         };
64
65                         const Light *light = 0;
66                         unsigned size;
67                         std::string shadow_caster_name;
68                 };
69
70                 unsigned width = 2048;
71                 unsigned height = 2048;
72                 const Lighting *lighting = 0;
73                 std::vector<ShadowedLight> lights;
74                 Vector3 target;
75                 float radius = 1.0f;
76                 float depth_bias = 4.0f;
77                 float darkness = 1.0f;
78
79                 virtual ShadowMap *create(const std::map<std::string, Renderable *> &) const;
80         };
81
82 private:
83         enum ShadowType
84         {
85                 NONE,
86                 DIRECTIONAL,
87                 TETRAHEDRON
88         };
89
90         struct ShadowedLight
91         {
92                 const Light *light;
93                 unsigned index;
94                 Rect region;
95                 ShadowType type;
96                 unsigned view_index;
97                 Renderable *shadow_caster;
98         };
99
100         struct ShadowView
101         {
102                 unsigned light_index;
103                 unsigned face;
104                 Camera camera;
105                 Matrix face_matrix;
106         };
107
108         unsigned width;
109         unsigned height;
110         const Lighting *lighting;
111         std::vector<ShadowedLight> lights;
112         std::vector<ShadowView> views;
113         Framebuffer fbo;
114         Texture2D depth_buf;
115         const Sampler &sampler;
116         Vector3 target;
117         float radius = 1.0f;
118         float depth_bias = 4.0f;
119         float darkness = 1.0f;
120         ProgramData shdata;
121         bool rendered = false;
122         std::string debug_name;
123
124         ShadowMap(unsigned, unsigned, Renderable &, const Lighting *);
125
126 public:
127         /** Creates a shadow map for a single light. */
128         ShadowMap(unsigned size, Renderable &content, const DirectionalLight &, Renderable &caster);
129
130         /** Creates a shadow map atlas, to which multiple lights can be added. */
131         ShadowMap(unsigned width, unsigned height, Renderable &, const Lighting &);
132
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);
136
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);
141 private:
142         void add_light(const Light &, unsigned, ShadowType, Renderable &);
143
144 public:
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);
150
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);
154
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);
160
161         const Texture2D &get_depth_texture() const { return depth_buf; }
162
163         virtual void setup_frame(Renderer &);
164         virtual void finish_frame();
165
166         virtual void render(Renderer &, Tag = Tag()) const;
167
168         virtual void set_debug_name(const std::string &);
169 };
170
171 } // namespace GL
172 } // namespace Msp
173
174 #endif