#ifndef MSP_GL_ENVIRONMENTMAP_H_
#define MSP_GL_ENVIRONMENTMAP_H_
+#include <vector>
#include "camera.h"
#include "effect.h"
#include "framebuffer.h"
-#include "matrix.h"
#include "programdata.h"
-#include "renderbuffer.h"
+#include "texture2d.h"
#include "texturecube.h"
-#include "vector.h"
namespace Msp {
namespace GL {
+class Mesh;
+class Sampler;
+
/**
-Creates a cube map texture of the surroundings of the renderable. This texture
-can then be used to implement effects such as reflections or refractions.
+Creates a cube map texture of the surroundings of the content renderable, for
+use in image-based lighting. Also called a light probe.
+
+The cube map can optionally be prefiltered for varying amounts of roughness.
+An irradiance map for diffuse lighting is also created.
+
+The EnvironmentMap won't be rendered inside its own environment. This avoids
+artifacts if one is used to create reflections on a complex object.
-If the EnvironmentMap is used in a Sequence, it's worth noting that the cube
-map will be prepared outside of any rendering pass. It's recommended to use
-another Sequence to define which passes should be used to render the
-environment.
+The shader fragment common.glsl provides interfaces to access the environment
+data.
*/
class EnvironmentMap: public Effect
{
-private:
+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 fixed_position(float, float, float);
+ };
+
+ unsigned size = 512;
+ PixelFormat format = RGB16F;
+ std::string environment_name;
+ unsigned roughness_levels = 5;
+ Vector3 fixed_position;
+ bool use_fixed_position = false;
+ float near_clip = 0.1f;
+ float far_clip = 100.0f;
+
+ virtual EnvironmentMap *create(const std::map<std::string, Renderable *> &) const;
+ };
+
+protected:
struct Face
{
Framebuffer fbo;
unsigned size;
Renderable &environment;
TextureCube env_tex;
- Renderbuffer depth_buf;
+ Texture2D depth_buf;
Face faces[6];
+ Vector3 fixed_position;
+ bool use_fixed_pos = false;
+
+ TextureCube irradiance;
+ const Program &irradiance_shprog;
+ Framebuffer irradiance_fbo;
+ const Program &specular_shprog;
+ std::vector<Framebuffer> specular_fbos;
+ ProgramData prefilter_shdata;
+ const Mesh &fullscreen_mesh;
+
const Sampler &sampler;
+ const Sampler &mip_sampler;
ProgramData shdata;
- bool rendered;
- unsigned update_interval;
- unsigned update_delay;
+ bool rendered = false;
+ bool in_setup_frame = false;
+ unsigned update_interval = 1;
+ unsigned update_delay = 0;
public:
- EnvironmentMap(unsigned size, Renderable &rend, Renderable &env);
- EnvironmentMap(unsigned size, PixelFormat, Renderable &rend, Renderable &env);
-private:
- void init(unsigned, PixelFormat);
+ EnvironmentMap(unsigned size, PixelFormat, Renderable &content, Renderable &env);
+
+ /** Creates an EnvironmentMap with prefiltering for varying amounts of
+ roughness. Levels specifies the number of prefilter mipmap levels and must
+ be valid for the size. */
+ EnvironmentMap(unsigned size, PixelFormat, unsigned levels, Renderable &content, Renderable &env);
+
+ /** Sets a fixed position to render the environment map from. This can be
+ useful if the content renderable does not have a model matrix. */
+ void set_fixed_position(const Vector3 &);
-public:
void set_depth_clip(float, float);
/** Sets the interval in frames between environment map updates. A value of
virtual void finish_frame();
virtual void render(Renderer &, Tag = Tag()) const;
+
+ virtual void set_debug_name(const std::string &);
};
} // namespace GL