Nori  24
photonmapper.cpp
1 /*
2  This file is part of Nori, a simple educational ray tracer
3 
4  Copyright (c) 2015 by Wenzel Jakob
5 
6  Nori 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  Nori 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 #include <nori/integrator.h>
20 #include <nori/sampler.h>
21 #include <nori/emitter.h>
22 #include <nori/bsdf.h>
23 #include <nori/scene.h>
24 #include <nori/photon.h>
25 
26 NORI_NAMESPACE_BEGIN
27 
28 class PhotonMapper : public Integrator {
29 public:
32 
33  PhotonMapper(const PropertyList &props) {
34  /* Lookup parameters */
35  m_photonCount = props.getInteger("photonCount", 1000000);
36  m_photonRadius = props.getFloat("photonRadius", 0.0f /* Default: automatic */);
37  }
38 
39  virtual void preprocess(const Scene *scene) override {
40  cout << "Gathering " << m_photonCount << " photons .. ";
41  cout.flush();
42 
43  /* Create a sample generator for the preprocess step */
44  Sampler *sampler = static_cast<Sampler *>(
46 
47  /* Allocate memory for the photon map */
48  m_photonMap = std::unique_ptr<PhotonMap>(new PhotonMap());
49  m_photonMap->reserve(m_photonCount);
50 
51  /* Estimate a default photon radius */
52  if (m_photonRadius == 0)
53  m_photonRadius = scene->getBoundingBox().getExtents().norm() / 500.0f;
54 
55 
56 
57  /* How to add a photon?
58  * m_photonMap->push_back(Photon(
59  * Point3f(0, 0, 0), // Position
60  * Vector3f(0, 0, 1), // Direction
61  * Color3f(1, 2, 3) // Power
62  * ));
63  */
64 
65  // put your code to trace photons here
66 
67  /* Build the photon map */
68  m_photonMap->build();
69  }
70 
71  virtual Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &_ray) const override {
72 
73  /* How to find photons?
74  * std::vector<uint32_t> results;
75  * m_photonMap->search(Point3f(0, 0, 0), // lookup position
76  * m_photonRadius, // search radius
77  * results);
78  *
79  * for (uint32_t i : results) {
80  * const Photon &photon = (*m_photonMap)[i];
81  * cout << "Found photon!" << endl;
82  * cout << " Position : " << photon.getPosition().toString() << endl;
83  * cout << " Power : " << photon.getPower().toString() << endl;
84  * cout << " Direction : " << photon.getDirection().toString() << endl;
85  * }
86  */
87 
88  // put your code for path tracing with photon gathering here
89 
90  return Color3f{};
91  }
92 
93  virtual std::string toString() const override {
94  return tfm::format(
95  "PhotonMapper[\n"
96  " photonCount = %i,\n"
97  " photonRadius = %f\n"
98  "]",
99  m_photonCount,
100  m_photonRadius
101  );
102  }
103 private:
104  /*
105  * Important: m_photonCount is the total number of photons deposited in the photon map,
106  * NOT the number of emitted photons. You will need to keep track of those yourself.
107  */
108  int m_photonCount;
109  float m_photonRadius;
110  std::unique_ptr<PhotonMap> m_photonMap;
111 };
112 
113 NORI_REGISTER_CLASS(PhotonMapper, "photonmapper");
114 NORI_NAMESPACE_END
Abstract integrator (i.e. a rendering technique)
Definition: integrator.h:35
static NoriObject * createInstance(const std::string &name, const PropertyList &propList)
Construct an instance from the class of the given name.
Definition: object.h:158
virtual std::string toString() const override
Return a brief string summary of the instance (for debugging purposes)
PointKDTree< Photon > PhotonMap
Photon map data structure.
virtual Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &_ray) const override
Sample the incident radiance along a ray.
virtual void preprocess(const Scene *scene) override
Perform an (optional) preprocess step.
Generic multi-dimensional kd-tree data structure for point data.
Definition: kdtree.h:124
This is an associative container used to supply the constructors of NoriObject subclasses with parame...
Definition: proplist.h:32
float getFloat(const std::string &name) const
Get a float property, and throw an exception if it does not exist.
int getInteger(const std::string &name) const
Get an integer property, and throw an exception if it does not exist.
Abstract sample generator.
Definition: sampler.h:63
Main scene data structure.
Definition: scene.h:34
const BoundingBox3f & getBoundingBox() const
Return an axis-aligned box that bounds the scene.
Definition: scene.h:116
Represents a linear RGB color value.
Definition: color.h:29
VectorType getExtents() const
Calculate the bounding box extents.
Definition: bbox.h:265