]> git.tdb.fi Git - libs/gl.git/blobdiff - source/effects/shadowmap.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / effects / shadowmap.h
index cf2dec01bc69e90afda1255dd63918fd5b8d5ebc..da76062833c745a487549df4a2a88e265f70cf2c 100644 (file)
@@ -14,20 +14,77 @@ namespace GL {
 
 class DirectionalLight;
 class Light;
+class PointLight;
 
 /**
-Creates shadows on a renderable through a shadow map texture.  In the setup
-phase, the scene is rendered to a depth texture from the point of view of the
-lightsource.  This texture is then used in the rendering phase together with
-texture coordinate generation to determine whether each fragment is lit.
+Creates a depth texture which can be used to add shadows to a renderable.
+
+In the setup phase, the scene is rendered from the point of view of the light
+source and the depth values are recorded.  This texture can be used by shaders
+to determine if the light can reach a particular position.
+
+A shadow map can be created as an atlas, containing multiple lights in the same
+depth texture.  Each light is automatically allocated a region of the texture
+and region information is added to the uniform values.
+
+The shader fragment shadow.glsl provides interfaces to access the shadow map.
 */
 class ShadowMap: public Effect
 {
+public:
+       struct Template: Effect::Template
+       {
+               class Loader: public DataFile::DerivedObjectLoader<Template, Effect::Template::Loader>
+               {
+               private:
+                       static ActionMap shared_actions;
+
+               public:
+                       Loader(Template &, Collection &);
+               private:
+                       virtual void init_actions();
+
+                       void light(const std::string &);
+                       void size_square(unsigned);
+                       void target(float, float, float);
+               };
+
+               struct ShadowedLight
+               {
+                       class Loader: public DataFile::ObjectLoader<ShadowedLight>
+                       {
+                       private:
+                               static ActionMap shared_actions;
+
+                       public:
+                               Loader(ShadowedLight &);
+                       private:
+                               virtual void init_actions();
+                       };
+
+                       const Light *light = 0;
+                       unsigned size;
+                       std::string shadow_caster_name;
+               };
+
+               unsigned width = 2048;
+               unsigned height = 2048;
+               const Lighting *lighting = 0;
+               std::vector<ShadowedLight> lights;
+               Vector3 target;
+               float radius = 1.0f;
+               float depth_bias = 4.0f;
+               float darkness = 1.0f;
+
+               virtual ShadowMap *create(const std::map<std::string, Renderable *> &) const;
+       };
+
 private:
        enum ShadowType
        {
                NONE,
-               DIRECTIONAL
+               DIRECTIONAL,
+               TETRAHEDRON
        };
 
        struct ShadowedLight
@@ -45,6 +102,7 @@ private:
                unsigned light_index;
                unsigned face;
                Camera camera;
+               Matrix face_matrix;
        };
 
        unsigned width;
@@ -64,29 +122,40 @@ private:
        std::string debug_name;
 
        ShadowMap(unsigned, unsigned, Renderable &, const Lighting *);
+
 public:
-       ShadowMap(unsigned, Renderable &, const DirectionalLight &, Renderable &);
-       ShadowMap(unsigned, unsigned, Renderable &, const Lighting &);
+       /** Creates a shadow map for a single light. */
+       ShadowMap(unsigned size, Renderable &content, const DirectionalLight &, Renderable &caster);
+
+       /** Creates a shadow map atlas, to which multiple lights can be added. */
+       ShadowMap(unsigned width, unsigned height, Renderable &, const Lighting &);
+
+       /** Adds a directional light.  The shadow map is rendered using an
+       orthogonal projection. */
+       void add_light(const DirectionalLight &, unsigned size, Renderable &caster);
 
-       void add_light(const DirectionalLight &, unsigned, Renderable &);
+       /** Adds a point light.  The shadow map is rendered using a perspective
+       projection, with four views in a tetrahedral arrangement.  The shader must
+       clip vertices appropriately.  Occluder_thsm.glsl can be used for this. */
+       void add_light(const PointLight &, unsigned size, Renderable &caster);
 private:
        void add_light(const Light &, unsigned, ShadowType, Renderable &);
 
 public:
-       /** Sets the ShadowMap target point and radius.  The transformation matrix is
-       computed so that a sphere with the specified parameters will be completely
-       covered by the ShadowMap. */
+       /** Sets the shadow volume parameters.  For directional lights the shadow
+       camera will be positioned so that the spherical shadow volume fits entirely
+       in the view volume.  For point lights the shadow volume's radius will be
+       used as the view distance. */
        void set_target(const Vector3 &, float);
 
        /** Sets the darkness of shadows.  Must be in the range between 0.0 and 1.0,
-       inclusive.  Only usable with shaders, and provided through the
-       shadow_darkness uniform. */
+       inclusive.  Values other than 1.0 are not physically correct. */
        void set_darkness(float);
 
-       /** Sets a distance beyond objects from which the shadow starts.  Expressed
-       in pixel-sized units.  Must be positive; values less than 1.0 are not
-       recommended.  Larger values produce less depth artifacts, but may prevent
-       thin objects from casting shadows on nearby sufraces. */
+       /** Sets an offset for depth values to avoid surfaces incorrectly shadowing
+       themselves.  Must be positive; values less than 1.0 are not recommended.
+       Larger values produce less artifacts, but may cause shadows to become
+       disconnected from the objects casting them. */
        void set_depth_bias(float);
 
        const Texture2D &get_depth_texture() const { return depth_buf; }