Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vpl.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_HW_VPL_H_)
21 #define __MITSUBA_HW_VPL_H_
22 
23 #include <mitsuba/render/vpl.h>
24 #include <mitsuba/hw/shadow.h>
25 #include <mitsuba/hw/gpugeometry.h>
26 
28 
29 /**
30  * \brief This class is responsible for the on-demand creation of
31  * GPU shaders to render shapes that are illuminated by virtual
32  * point light sources.
33  *
34  * This is used to drive the \c vpl integrator as well as the
35  * interactive preview in the Mitsuba GUI.
36  *
37  * For each encountered BSDF-VPL pair, a custom piece of code
38  * describing the characteristic light transport between them is
39  * created and cached. The implementation carefully looks at
40  * the tree of shader dependencies and creates code that can be
41  * shared with other materials that have a similar configuration.
42  * This is necessary to avoid generating a potentially huge O(N^2)
43  * number of very similar programs and brings it down to O(n^2)
44  * where n << N.
45  *
46  * \ingroup libhw
47  */
49 public:
50  /// Create a new shader manager
51  VPLShaderManager(Renderer *renderer);
52 
53  /// Upload requisite shaders to the GPU. To be called once
54  void init();
55 
56  /// Issue a final cleanup (before destroying the shader manager)
57  void cleanup();
58 
59  /**
60  * \brief Associate the shader manager with a new scene
61  *
62  * This function uploads all relevant triangle geometry
63  * to the GPU, and releases any resources held for the
64  * previous scene. It is valid to call the function with
65  * a \c NULL argument.
66  */
67  void setScene(const Scene *scene);
68 
69  /// Return the currently bound scene
70  inline const Scene *getScene() const { return m_scene.get(); }
71 
72  /**
73  * \brief Prepare the shader manager for rendering
74  * with a new VPL
75  *
76  * Must be called after \ref setScene() and before
77  * \ref bind(). This function creates a suitable
78  * shadow map for the VPL.
79  */
80  void setVPL(const VPL &vpl);
81 
82  /**
83  * \brief Bind a shader for rendering a certain
84  * VPL/BSDF/Emitter triplet
85  *
86  * \param vpl
87  * Record describing the virtual point light source
88  *
89  * \param bsdf
90  * Material of the object to be rendered
91  *
92  * \param sensor
93  * Sensor from which it is viewed
94  *
95  * \param instanceTransform
96  * An additional object-to-world transformation that
97  * is applied to the rendered geometry. Used for instancing.
98  *
99  * \param faceNormals
100  * When set to \c true, a special shader is used to
101  * create face normals for the geometry
102  */
103  void bind(const VPL &vpl, const BSDF *bsdf,
104  const Sensor *sensor, const Emitter *emitter,
105  const Matrix4x4 &instanceTransform, bool faceNormals);
106 
107  /**
108  * \brief Release the currently bound shader and
109  * any resources (textures,..) that it references
110  */
111  void unbind();
112 
113  /**
114  * \brief Convenience function for rendering all geometry
115  * for a given VPL
116  *
117  * This function issues the necessary calls to \ref bind()
118  * \ref unbind(), etc., and schedules draw calls for all
119  * of the scene geometry.
120  */
121  void drawAllGeometryForVPL(const VPL &vpl, const Sensor *sensor);
122 
123  /// Draw the background if there is an environment emitter
124  void drawBackground(const Sensor *sensor,
125  const Transform &projectionTransform, Float scaleFactor);
126 
127  /// Set the clamping distance
128  inline void setClamping(Float clamping) { m_clamping = clamping; }
129 
130  /// Return the clamping distance
131  inline Float getClamping() const { return m_clamping; }
132 
133  /// Set the current shadow map resolution
134  inline void setShadowMapResolution(int resolution) { m_shadowMapResolution = resolution; }
135 
136  /// Return the current shadow map resolution
137  inline int getShadowMapResolution() const { return m_shadowMapResolution; }
138 
139  /// Set whether or not non-diffuse VPLs are used
140  inline void setDiffuseSources(bool diffuseSources) { m_diffuseSources = diffuseSources; }
141 
142  /// Return whether or not non-diffuse VPLs are used
143  inline bool getDiffuseSources() const { return m_diffuseSources; }
144 
145  /// Set whether or not surfaces are drawn assumed to be diffuse
146  inline void setDiffuseReceivers(bool diffuseReceivers) { m_diffuseReceivers = diffuseReceivers; }
147 
148  /// Return whether or not surfaces are assumed to be diffuse
149  inline bool getDiffuseReceivers() const { return m_diffuseReceivers; }
150 
151  /// Reset the VPL counter
152  inline void resetCounter() { m_vplIndex = 0; }
153 protected:
154  /// Virtual destructor
155  virtual ~VPLShaderManager();
156 
157  /**
158  * \brief This helper class stores a reference to a \ref Shader and all
159  * sub-shaders that are part of its evaluation
160  *
161  * It also allows to generate GLSL code for the entire chain, and to
162  * bind any uniform parameters to the target parameters
163  */
164  struct DependencyNode {
165  const Shader *shader;
166  std::vector<DependencyNode> children;
167  std::vector<int> parameterIDs;
168 
169  /// Create from a \ref Shader object
170  inline DependencyNode(Shader *shader = NULL) : shader(shader) {
171  if (!shader)
172  return;
173  std::vector<Shader *> deps;
174  shader->putDependencies(deps);
175  for (std::vector<Shader *>::iterator it = deps.begin();
176  it != deps.end(); ++it)
177  children.push_back(DependencyNode(*it));
178  }
179 
180  /// Copy constructor
181  inline DependencyNode(const DependencyNode &node)
182  : shader(node.shader), children(node.children),
183  parameterIDs(node.parameterIDs) { }
184 
185  /// Generate GLSL code for the entire shader chain
186  inline std::string generateCode(std::ostringstream &oss, int &id) const {
187  std::vector<std::string> depNames;
188  for (size_t i=0; i<children.size(); ++i)
189  depNames.push_back(children[i].generateCode(oss, id));
190  std::string evalName = formatString("shader_%i", id++);
191  shader->generateCode(oss, evalName, depNames);
192  oss << endl;
193  return evalName;
194  }
195 
196  /// Resolve all parameters of the shader chain
197  inline void resolve(GPUProgram *program, int &id) {
198  std::vector<std::string> depNames;
199  for (size_t i=0; i<children.size(); ++i)
200  children[i].resolve(program, id);
201 
202  std::string evalName = formatString("shader_%i", id++);
203  shader->resolve(program, evalName, parameterIDs);
204  }
205 
206  /// Bind all referenced resources (textures etc)
207  inline void bind(GPUProgram *program, const DependencyNode &targetNode, int &textureUnitOffset) {
208  if (!shader)
209  return;
210  for (size_t i=0; i<children.size(); ++i)
211  children[i].bind(program, targetNode.children[i], textureUnitOffset);
212  shader->bind(program, targetNode.parameterIDs, textureUnitOffset);
213  }
214 
215  /// Release resources that were bound by \ref bind()
216  inline void unbind() {
217  if (!shader)
218  return;
219  shader->unbind();
220  for (size_t i=0; i<children.size(); ++i)
221  children[i].unbind();
222  }
223 
224  /// Generate a textual summary of the entire shader chain
225  inline void toString(std::ostringstream &oss) const {
226  if (!shader)
227  return;
228  oss << shader->getClass()->getName();
229  if (children.size() > 0) {
230  oss << '[';
231  for (size_t i=0; i<children.size(); ++i) {
232  children[i].toString(oss);
233  if (i+1<children.size())
234  oss << ", ";
235  }
236  oss << "]";
237  }
238  }
239 
240  inline std::string toString() const {
241  std::ostringstream oss;
242  toString(oss);
243  return oss.str();
244  }
245  };
246 
247  /**
248  * \brief Describes the configuration of a (vpl, bsdf, emitter)
249  * shader chain triplet
250  */
252  DependencyNode vpl, bsdf, emitter;
255 
256  /* GLSL program paramter IDs */
257  int param_instanceTransform, param_vplTransform;
258  int param_vplPosition, param_vplDirection;
259  int param_camPosition, param_camDirection;
260  int param_shadowMap, param_depthRange;
261  int param_emitterScale, param_vplPower;
262  int param_vplFrame, param_vplUV, param_vplWi;
264 
265  /// Dummy constructor
266  inline VPLConfiguration() : program(NULL) { }
267 
268  /// Create a new configuration for the given (vpl, bsdf, emitter) triplet
269  inline VPLConfiguration(Shader *vpl, Shader *bsdf, Shader *emitter, bool faceNormals)
270  : vpl(vpl), bsdf(bsdf), emitter(emitter), faceNormals(faceNormals), program(NULL) { }
271 
272  /// Generate GLSL code for the entire shader chain
273  inline void generateCode(std::ostringstream &oss, std::string &vplEvalName,
274  std::string &bsdfEvalName, std::string &emitterEvalName) const {
275  int id = 0;
276  vplEvalName = vpl.generateCode(oss, id);
277  bsdfEvalName = bsdf.generateCode(oss, id);
278  if (emitter.shader)
279  emitterEvalName = emitter.generateCode(oss, id);
280  }
281 
282  /// Resolve all parameters of the shader chain
283  inline void resolve(GPUProgram *program) {
284  int id = 0;
285  vpl.resolve(program, id);
286  bsdf.resolve(program, id);
287  if (emitter.shader)
288  emitter.resolve(program, id);
289  }
290 
291  /// Bind all referenced resources (textures etc)
292  inline void bind(const VPLConfiguration &targetConf, int textureUnitOffset) {
293  vpl.bind(targetConf.program, targetConf.vpl, textureUnitOffset);
294  bsdf.bind(targetConf.program, targetConf.bsdf, textureUnitOffset);
295  if (emitter.shader)
296  emitter.bind(targetConf.program, targetConf.emitter, textureUnitOffset);
297  }
298 
299  /// Release resources that were bound by \ref bind()
300  inline void unbind() {
301  vpl.unbind();
302  bsdf.unbind();
303  if (emitter.shader)
304  emitter.unbind();
305  }
306 
307  /// Generate a textual summary of the entire shader chain
308  inline std::string toString() const {
309  std::ostringstream oss;
310  oss << "vpl=";
311  vpl.toString(oss);
312  oss << ", bsdf=";
313  bsdf.toString(oss);
314  if (emitter.shader) {
315  oss << ", emitter=";
316  emitter.toString(oss);
317  }
318  if (faceNormals)
319  oss << ", faceNormals";
320  return oss.str();
321  }
322  };
323 
324  /**
325  * \brief Order materials so that they can be drawn with the least
326  * number of GPU pipeline flushes. Draw transparent objects last.
327  */
328  struct MaterialOrder {
329  const std::vector<Renderer::TransformedGPUGeometry> &geo;
330 
331  MaterialOrder(const std::vector<Renderer::TransformedGPUGeometry> &geo)
332  : geo(geo) { }
333 
334  inline bool operator()(size_t idx1, size_t idx2) const {
335  const Shader *shader1 = geo[idx1].first->getShader();
336  const Shader *shader2 = geo[idx2].first->getShader();
337 
338  if (shader1 && (shader1->getFlags() & Shader::ETransparent))
339  shader1 = NULL;
340  if (shader2 && (shader2->getFlags() & Shader::ETransparent))
341  shader2 = NULL;
342 
343  return shader1 < shader2;
344  }
345  };
346 
347  /// Helper data structure to keep track of shapes that are undergoing keyframe animations
350  ssize_t geometryIndex;
352 
354  ssize_t geometryIndex, ssize_t opaqueGeometryIndex) :
355  trafo(trafo), geometryIndex(geometryIndex),
356  opaqueGeometryIndex(opaqueGeometryIndex) { }
357  };
358 
360 private:
361  ref<Renderer> m_renderer;
362  ref<const Scene> m_scene;
363 
364  /* On-GPU geometry references */
365  std::vector<Renderer::TransformedGPUGeometry> m_geometry;
366  std::vector<Renderer::TransformedGPUGeometry> m_opaqueGeometry;
367  std::vector<AnimatedGeometryRecord> m_animatedGeometry;
368 
369  /* Shader & dependency management */
370  std::map<std::string, VPLConfiguration> m_configurations;
371  VPLConfiguration m_targetConfiguration;
372  VPLConfiguration m_currentProgram;
373 
374  /* Background rendering - related */
375  ref<GPUProgram> m_backgroundProgram;
376  DependencyNode m_backgroundDependencies;
377  int m_backgroundParam_camPosition;
378  int m_backgroundParam_camDirection;
379  int m_backgroundParam_clipToWorld;
380  int m_backgroundParam_emitterScale;
381 
382  /* Shadow map - related */
383  ShadowMapGenerator::EShadowMapType m_shadowMapType;
384  ref<ShadowMapGenerator> m_shadowGen;
385  ref<GPUTexture> m_shadowMapCube;
386  ref<GPUTexture> m_shadowMap2D;
387  GPUTexture *m_shadowMap;
388  Transform m_shadowMapTransform;
389  Float m_nearClip, m_farClip;
390 
391  /* Other rendering parameters */
392  bool m_diffuseSources, m_diffuseReceivers;
393  int m_shadowMapResolution;
394  uint32_t m_vplIndex;
395  Float m_clamping, m_alpha;
396 };
397 
399 
400 #endif /* __MITSUBA_HW_VPL_H_ */
void unbind()
Release resources that were bound by bind()
Definition: vpl.h:216
MTS_EXPORT_CORE std::string formatString(const char *pFmt,...)
Wrapped snprintf.
VPLConfiguration(Shader *vpl, Shader *bsdf, Shader *emitter, bool faceNormals)
Create a new configuration for the given (vpl, bsdf, emitter) triplet.
Definition: vpl.h:269
Float getClamping() const
Return the clamping distance.
Definition: vpl.h:131
const AnimatedTransform * trafo
Definition: vpl.h:349
AnimatedGeometryRecord(const AnimatedTransform *trafo, ssize_t geometryIndex, ssize_t opaqueGeometryIndex)
Definition: vpl.h:353
ssize_t opaqueGeometryIndex
Definition: vpl.h:351
void resolve(GPUProgram *program, int &id)
Resolve all parameters of the shader chain.
Definition: vpl.h:197
Abstract radiance emitter interface.
Definition: emitter.h:443
void setClamping(Float clamping)
Set the clamping distance.
Definition: vpl.h:128
std::string generateCode(std::ostringstream &oss, int &id) const
Generate GLSL code for the entire shader chain.
Definition: vpl.h:186
Shader base class for use with a VPL-style renderer.
Definition: shader.h:54
Utility class for creating different kinds of shadow maps (cube, directional, and paraboloid shadow m...
Definition: shadow.h:32
DependencyNode(const DependencyNode &node)
Copy constructor.
Definition: vpl.h:181
MaterialOrder(const std::vector< Renderer::TransformedGPUGeometry > &geo)
Definition: vpl.h:331
#define MTS_EXPORT_HW
Definition: platform.h:114
This class is responsible for the on-demand creation of GPU shaders to render shapes that are illumin...
Definition: vpl.h:48
bool operator()(size_t idx1, size_t idx2) const
Definition: vpl.h:334
std::vector< int > parameterIDs
Definition: vpl.h:167
void generateCode(std::ostringstream &oss, std::string &vplEvalName, std::string &bsdfEvalName, std::string &emitterEvalName) const
Generate GLSL code for the entire shader chain.
Definition: vpl.h:273
Principal scene data structure.
Definition: scene.h:49
Describes the configuration of a (vpl, bsdf, emitter) shader chain triplet.
Definition: vpl.h:251
Abstract sensor interface.
Definition: sensor.h:66
int param_camPosition
Definition: vpl.h:259
DependencyNode(Shader *shader=NULL)
Create from a Shader object.
Definition: vpl.h:170
uint32_t getFlags() const
Return a list of flags.
Definition: shader.h:70
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
GPUProgram * program
Definition: vpl.h:254
Abstract shader program (for fragment/vertex shading)
Definition: gpuprogram.h:30
VPLConfiguration()
Dummy constructor.
Definition: vpl.h:266
void unbind()
Release resources that were bound by bind()
Definition: vpl.h:300
const std::vector< Renderer::TransformedGPUGeometry > & geo
Definition: vpl.h:329
bool getDiffuseSources() const
Return whether or not non-diffuse VPLs are used.
Definition: vpl.h:143
Order materials so that they can be drawn with the least number of GPU pipeline flushes. Draw transparent objects last.
Definition: vpl.h:328
int param_minDistSqr
Definition: vpl.h:263
void bind(const VPLConfiguration &targetConf, int textureUnitOffset)
Bind all referenced resources (textures etc)
Definition: vpl.h:292
void resetCounter()
Reset the VPL counter.
Definition: vpl.h:152
int param_shadowMap
Definition: vpl.h:260
const Scene * getScene() const
Return the currently bound scene.
Definition: vpl.h:70
int getShadowMapResolution() const
Return the current shadow map resolution.
Definition: vpl.h:137
void setDiffuseSources(bool diffuseSources)
Set whether or not non-diffuse VPLs are used.
Definition: vpl.h:140
Helper data structure to keep track of shapes that are undergoing keyframe animations.
Definition: vpl.h:348
#define MTS_DECLARE_CLASS()
This macro must be used in the initial definition in classes that derive from Object.
Definition: class.h:158
int param_vplPosition
Definition: vpl.h:258
Reference counting helper.
Definition: ref.h:40
void setShadowMapResolution(int resolution)
Set the current shadow map resolution.
Definition: vpl.h:134
void resolve(GPUProgram *program)
Resolve all parameters of the shader chain.
Definition: vpl.h:283
Encapsulates a 4x4 linear transformation and its inverse.
Definition: transform.h:33
Abstract BSDF base-class.
Definition: bsdf.h:215
DependencyNode vpl
Definition: vpl.h:252
Abstract renderer implementation.
Definition: renderer.h:79
std::string toString() const
Definition: vpl.h:240
A data structure for 1/2/3D and cube texture mapping. Also has optional render-to-texture functionali...
Definition: gputexture.h:32
This helper class stores a reference to a Shader and all sub-shaders that are part of its evaluation...
Definition: vpl.h:164
void bind(GPUProgram *program, const DependencyNode &targetNode, int &textureUnitOffset)
Bind all referenced resources (textures etc)
Definition: vpl.h:207
Basic 4x4 matrix data type.
Definition: matrix.h:656
void setDiffuseReceivers(bool diffuseReceivers)
Set whether or not surfaces are drawn assumed to be diffuse.
Definition: vpl.h:146
const Shader * shader
Definition: vpl.h:165
std::vector< DependencyNode > children
Definition: vpl.h:166
void toString(std::ostringstream &oss) const
Generate a textual summary of the entire shader chain.
Definition: vpl.h:225
Animated transformation with an underlying keyframe representation.
Definition: track.h:335
bool getDiffuseReceivers() const
Return whether or not surfaces are assumed to be diffuse.
Definition: vpl.h:149
std::string toString() const
Generate a textual summary of the entire shader chain.
Definition: vpl.h:308
Parent of all Mitsuba classes.
Definition: object.h:38
Definition: vpl.h:38
DependencyNode bsdf
Definition: vpl.h:252
int param_vplTransform
Definition: vpl.h:257
DependencyNode emitter
Definition: vpl.h:252
#define MTS_NAMESPACE_END
Definition: platform.h:138