OpenVDB  4.0.1
RayTracer.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
44 
45 #ifndef OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
46 #define OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
47 
48 #include <openvdb/Types.h>
49 #include <openvdb/math/BBox.h>
50 #include <openvdb/math/Ray.h>
51 #include <openvdb/math/Math.h>
54 #include <boost/scoped_array.hpp>
55 #include <deque>
56 #include <fstream>
57 #include <memory>
58 #include <type_traits>
59 #include <vector>
60 
61 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
62 #include <OpenEXR/ImfPixelType.h>
63 #include <OpenEXR/ImfChannelList.h>
64 #include <OpenEXR/ImfOutputFile.h>
65 #include <OpenEXR/ImfHeader.h>
66 #include <OpenEXR/ImfFrameBuffer.h>
67 #endif
68 
69 namespace openvdb {
71 namespace OPENVDB_VERSION_NAME {
72 namespace tools {
73 
74 // Forward declarations
75 class BaseCamera;
76 class BaseShader;
77 
79 template<typename GridT>
80 inline void rayTrace(const GridT&,
81  const BaseShader&,
82  BaseCamera&,
83  size_t pixelSamples = 1,
84  unsigned int seed = 0,
85  bool threaded = true);
86 
88 template<typename GridT, typename IntersectorT>
89 inline void rayTrace(const GridT&,
90  const IntersectorT&,
91  const BaseShader&,
92  BaseCamera&,
93  size_t pixelSamples = 1,
94  unsigned int seed = 0,
95  bool threaded = true);
96 
97 
99 
102 template<typename GridT, typename IntersectorT = tools::LevelSetRayIntersector<GridT> >
104 {
105 public:
106  using GridType = GridT;
107  using Vec3Type = typename IntersectorT::Vec3Type;
108  using RayType = typename IntersectorT::RayType;
109 
111  LevelSetRayTracer(const GridT& grid,
112  const BaseShader& shader,
113  BaseCamera& camera,
114  size_t pixelSamples = 1,
115  unsigned int seed = 0);
116 
119  LevelSetRayTracer(const IntersectorT& inter,
120  const BaseShader& shader,
121  BaseCamera& camera,
122  size_t pixelSamples = 1,
123  unsigned int seed = 0);
124 
126  LevelSetRayTracer(const LevelSetRayTracer& other);
127 
130 
132  void setGrid(const GridT& grid);
133 
136  void setIntersector(const IntersectorT& inter);
137 
145  void setShader(const BaseShader& shader);
146 
148  void setCamera(BaseCamera& camera);
149 
154  void setPixelSamples(size_t pixelSamples, unsigned int seed = 0);
155 
157  void render(bool threaded = true) const;
158 
161  void operator()(const tbb::blocked_range<size_t>& range) const;
162 
163 private:
164  const bool mIsMaster;
165  double* mRand;
166  IntersectorT mInter;
167  std::unique_ptr<const BaseShader> mShader;
168  BaseCamera* mCamera;
169  size_t mSubPixels;
170 };// LevelSetRayTracer
171 
172 
174 
179 template <typename IntersectorT, typename SamplerT = tools::BoxSampler>
181 {
182 public:
183 
184  using GridType = typename IntersectorT::GridType;
185  using RayType = typename IntersectorT::RayType;
186  using ValueType = typename GridType::ValueType;
187  using AccessorType = typename GridType::ConstAccessor;
189  static_assert(std::is_floating_point<ValueType>::value,
190  "VolumeRender requires a floating-point-valued grid");
191 
193  VolumeRender(const IntersectorT& inter, BaseCamera& camera);
194 
196  VolumeRender(const VolumeRender& other);
197 
199  void render(bool threaded=true) const;
200 
202  void setCamera(BaseCamera& camera) { mCamera = &camera; }
203 
206  void setIntersector(const IntersectorT& inter);
207 
210  void setLightDir(Real x, Real y, Real z) { mLightDir = Vec3R(x,y,z).unit(); }
211 
213  void setLightColor(Real r, Real g, Real b) { mLightColor = Vec3R(r,g,b); }
214 
216  void setPrimaryStep(Real primaryStep) { mPrimaryStep = primaryStep; }
217 
219  void setShadowStep(Real shadowStep) { mShadowStep = shadowStep; }
220 
222  void setScattering(Real x, Real y, Real z) { mScattering = Vec3R(x,y,z); }
223 
225  void setAbsorption(Real x, Real y, Real z) { mAbsorption = Vec3R(x,y,z); }
226 
229  void setLightGain(Real gain) { mLightGain = gain; }
230 
232  void setCutOff(Real cutOff) { mCutOff = cutOff; }
233 
238  void print(std::ostream& os = std::cout, int verboseLevel = 1);
239 
242  void operator()(const tbb::blocked_range<size_t>& range) const;
243 
244 private:
245 
246  AccessorType mAccessor;
247  BaseCamera* mCamera;
248  std::unique_ptr<IntersectorT> mPrimary, mShadow;
249  Real mPrimaryStep, mShadowStep, mCutOff, mLightGain;
250  Vec3R mLightDir, mLightColor, mAbsorption, mScattering;
251 };//VolumeRender
252 
254 
257 class Film
258 {
259 public:
262  struct RGBA
263  {
264  using ValueT = float;
265 
266  RGBA() : r(0), g(0), b(0), a(1) {}
267  explicit RGBA(ValueT intensity) : r(intensity), g(intensity), b(intensity), a(1) {}
268  RGBA(ValueT _r, ValueT _g, ValueT _b, ValueT _a = static_cast<ValueT>(1.0)):
269  r(_r), g(_g), b(_b), a(_a)
270  {}
271  RGBA(double _r, double _g, double _b, double _a = 1.0)
272  : r(static_cast<ValueT>(_r))
273  , g(static_cast<ValueT>(_g))
274  , b(static_cast<ValueT>(_b))
275  , a(static_cast<ValueT>(_a))
276  {}
277 
278  RGBA operator* (ValueT scale) const { return RGBA(r*scale, g*scale, b*scale);}
279  RGBA operator+ (const RGBA& rhs) const { return RGBA(r+rhs.r, g+rhs.g, b+rhs.b);}
280  RGBA operator* (const RGBA& rhs) const { return RGBA(r*rhs.r, g*rhs.g, b*rhs.b);}
281  RGBA& operator+=(const RGBA& rhs) { r+=rhs.r; g+=rhs.g; b+=rhs.b, a+=rhs.a; return *this;}
282 
283  void over(const RGBA& rhs)
284  {
285  const float s = rhs.a*(1.0f-a);
286  r = a*r+s*rhs.r;
287  g = a*g+s*rhs.g;
288  b = a*b+s*rhs.b;
289  a = a + s;
290  }
291 
292  ValueT r, g, b, a;
293  };
294 
295 
296  Film(size_t width, size_t height)
297  : mWidth(width), mHeight(height), mSize(width*height), mPixels(new RGBA[mSize])
298  {
299  }
300  Film(size_t width, size_t height, const RGBA& bg)
301  : mWidth(width), mHeight(height), mSize(width*height), mPixels(new RGBA[mSize])
302  {
303  this->fill(bg);
304  }
305 
306  const RGBA& pixel(size_t w, size_t h) const
307  {
308  assert(w < mWidth);
309  assert(h < mHeight);
310  return mPixels[w + h*mWidth];
311  }
312 
313  RGBA& pixel(size_t w, size_t h)
314  {
315  assert(w < mWidth);
316  assert(h < mHeight);
317  return mPixels[w + h*mWidth];
318  }
319 
320  void fill(const RGBA& rgb=RGBA(0)) { for (size_t i=0; i<mSize; ++i) mPixels[i] = rgb; }
321  void checkerboard(const RGBA& c1=RGBA(0.3f), const RGBA& c2=RGBA(0.6f), size_t size=32)
322  {
323  RGBA *p = mPixels.get();
324  for (size_t j = 0; j < mHeight; ++j) {
325  for (size_t i = 0; i < mWidth; ++i, ++p) {
326  *p = ((i & size) ^ (j & size)) ? c1 : c2;
327  }
328  }
329  }
330 
331  void savePPM(const std::string& fileName)
332  {
333  std::string name(fileName);
334  if (name.find_last_of(".") == std::string::npos) name.append(".ppm");
335 
336  boost::scoped_array<unsigned char> buffer(new unsigned char[3*mSize]);
337  unsigned char *tmp = buffer.get(), *q = tmp;
338  RGBA* p = mPixels.get();
339  size_t n = mSize;
340  while (n--) {
341  *q++ = static_cast<unsigned char>(255.0f*(*p ).r);
342  *q++ = static_cast<unsigned char>(255.0f*(*p ).g);
343  *q++ = static_cast<unsigned char>(255.0f*(*p++).b);
344  }
345 
346  std::ofstream os(name.c_str(), std::ios_base::binary);
347  if (!os.is_open()) {
348  std::cerr << "Error opening PPM file \"" << name << "\"" << std::endl;
349  return;
350  }
351 
352  os << "P6\n" << mWidth << " " << mHeight << "\n255\n";
353  os.write(reinterpret_cast<const char*>(&(*tmp)), 3 * mSize * sizeof(unsigned char));
354  }
355 
356 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
357  void saveEXR(const std::string& fileName, size_t compression = 2, size_t threads = 8)
358  {
359  std::string name(fileName);
360  if (name.find_last_of(".") == std::string::npos) name.append(".exr");
361 
362  if (threads>0) Imf::setGlobalThreadCount(threads);
363  Imf::Header header(mWidth, mHeight);
364  if (compression==0) header.compression() = Imf::NO_COMPRESSION;
365  if (compression==1) header.compression() = Imf::RLE_COMPRESSION;
366  if (compression>=2) header.compression() = Imf::ZIP_COMPRESSION;
367  header.channels().insert("R", Imf::Channel(Imf::FLOAT));
368  header.channels().insert("G", Imf::Channel(Imf::FLOAT));
369  header.channels().insert("B", Imf::Channel(Imf::FLOAT));
370  header.channels().insert("A", Imf::Channel(Imf::FLOAT));
371 
372  Imf::FrameBuffer framebuffer;
373  framebuffer.insert("R", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].r),
374  sizeof (RGBA), sizeof (RGBA) * mWidth));
375  framebuffer.insert("G", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].g),
376  sizeof (RGBA), sizeof (RGBA) * mWidth));
377  framebuffer.insert("B", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].b),
378  sizeof (RGBA), sizeof (RGBA) * mWidth));
379  framebuffer.insert("A", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].a),
380  sizeof (RGBA), sizeof (RGBA) * mWidth));
381 
382  Imf::OutputFile file(name.c_str(), header);
383  file.setFrameBuffer(framebuffer);
384  file.writePixels(mHeight);
385  }
386 #endif
387 
388  size_t width() const { return mWidth; }
389  size_t height() const { return mHeight; }
390  size_t numPixels() const { return mSize; }
391  const RGBA* pixels() const { return mPixels.get(); }
392 
393 private:
394  size_t mWidth, mHeight, mSize;
395  boost::scoped_array<RGBA> mPixels;
396 };// Film
397 
398 
400 
403 {
404 public:
405  BaseCamera(Film& film, const Vec3R& rotation, const Vec3R& translation,
406  double frameWidth, double nearPlane, double farPlane)
407  : mFilm(&film)
408  , mScaleWidth(frameWidth)
409  , mScaleHeight(frameWidth * double(film.height()) / double(film.width()))
410  {
411  assert(nearPlane > 0 && farPlane > nearPlane);
412  mScreenToWorld.accumPostRotation(math::X_AXIS, rotation[0] * M_PI / 180.0);
413  mScreenToWorld.accumPostRotation(math::Y_AXIS, rotation[1] * M_PI / 180.0);
414  mScreenToWorld.accumPostRotation(math::Z_AXIS, rotation[2] * M_PI / 180.0);
415  mScreenToWorld.accumPostTranslation(translation);
416  this->initRay(nearPlane, farPlane);
417  }
418 
419  virtual ~BaseCamera() {}
420 
421  Film::RGBA& pixel(size_t i, size_t j) { return mFilm->pixel(i, j); }
422 
423  size_t width() const { return mFilm->width(); }
424  size_t height() const { return mFilm->height(); }
425 
430  void lookAt(const Vec3R& xyz, const Vec3R& up = Vec3R(0.0, 1.0, 0.0))
431  {
432  const Vec3R orig = mScreenToWorld.applyMap(Vec3R(0.0));
433  const Vec3R dir = orig - xyz;
434  try {
435  Mat4d xform = math::aim<Mat4d>(dir, up);
436  xform.postTranslate(orig);
437  mScreenToWorld = math::AffineMap(xform);
438  this->initRay(mRay.t0(), mRay.t1());
439  } catch (...) {}
440  }
441 
442  Vec3R rasterToScreen(double i, double j, double z) const
443  {
444  return Vec3R( (2 * i / double(mFilm->width()) - 1) * mScaleWidth,
445  (1 - 2 * j / double(mFilm->height())) * mScaleHeight, z );
446  }
447 
451  virtual math::Ray<double> getRay(
452  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const = 0;
453 
454 protected:
455  void initRay(double t0, double t1)
456  {
457  mRay.setTimes(t0, t1);
458  mRay.setEye(mScreenToWorld.applyMap(Vec3R(0.0)));
459  mRay.setDir(mScreenToWorld.applyJacobian(Vec3R(0.0, 0.0, -1.0)));
460  }
461 
463  double mScaleWidth, mScaleHeight;
466 };// BaseCamera
467 
468 
470 {
471  public:
488  const Vec3R& rotation = Vec3R(0.0),
489  const Vec3R& translation = Vec3R(0.0),
490  double focalLength = 50.0,
491  double aperture = 41.2136,
492  double nearPlane = 1e-3,
493  double farPlane = std::numeric_limits<double>::max())
494  : BaseCamera(film, rotation, translation, 0.5*aperture/focalLength, nearPlane, farPlane)
495  {
496  }
497 
498  ~PerspectiveCamera() override = default;
499 
504  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const override
505  {
506  math::Ray<double> ray(mRay);
507  Vec3R dir = BaseCamera::rasterToScreen(Real(i) + iOffset, Real(j) + jOffset, -1.0);
508  dir = BaseCamera::mScreenToWorld.applyJacobian(dir);
509  dir.normalize();
510  ray.scaleTimes(1.0/dir.dot(ray.dir()));
511  ray.setDir(dir);
512  return ray;
513  }
514 
517  static double focalLengthToFieldOfView(double length, double aperture)
518  {
519  return 360.0 / M_PI * atan(aperture/(2.0*length));
520  }
523  static double fieldOfViewToFocalLength(double fov, double aperture)
524  {
525  return aperture/(2.0*(tan(fov * M_PI / 360.0)));
526  }
527 };// PerspectiveCamera
528 
529 
531 {
532 public:
546  const Vec3R& rotation = Vec3R(0.0),
547  const Vec3R& translation = Vec3R(0.0),
548  double frameWidth = 1.0,
549  double nearPlane = 1e-3,
550  double farPlane = std::numeric_limits<double>::max())
551  : BaseCamera(film, rotation, translation, 0.5*frameWidth, nearPlane, farPlane)
552  {
553  }
554  ~OrthographicCamera() override = default;
555 
557  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const override
558  {
559  math::Ray<double> ray(mRay);
560  Vec3R eye = BaseCamera::rasterToScreen(Real(i) + iOffset, Real(j) + jOffset, 0.0);
561  ray.setEye(BaseCamera::mScreenToWorld.applyMap(eye));
562  return ray;
563  }
564 };// OrthographicCamera
565 
566 
568 
569 
572 {
573 public:
576  BaseShader(const BaseShader&) = default;
577  virtual ~BaseShader() = default;
582  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R& nml, const Vec3R& dir) const = 0;
583  virtual BaseShader* copy() const = 0;
584 };
585 
586 
593 template<typename GridT = Film::RGBA,
594  typename SamplerType = tools::PointSampler>
595 class MatteShader: public BaseShader
596 {
597 public:
598  MatteShader(const GridT& grid) : mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
599  MatteShader(const MatteShader&) = default;
600  ~MatteShader() override = default;
601  Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override
602  {
603  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
604  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
605  return Film::RGBA(v[0], v[1], v[2]);
606  }
607  BaseShader* copy() const override { return new MatteShader<GridT, SamplerType>(*this); }
608 
609 private:
610  typename GridT::ConstAccessor mAcc;
611  const math::Transform* mXform;
612 };
613 
614 // Template specialization using a constant color of the material.
615 template<typename SamplerType>
616 class MatteShader<Film::RGBA, SamplerType>: public BaseShader
617 {
618 public:
619  MatteShader(const Film::RGBA& c = Film::RGBA(1.0f)): mRGBA(c) {}
620  MatteShader(const MatteShader&) = default;
621  ~MatteShader() override = default;
622  Film::RGBA operator()(const Vec3R&, const Vec3R&, const Vec3R&) const override
623  {
624  return mRGBA;
625  }
626  BaseShader* copy() const override { return new MatteShader<Film::RGBA, SamplerType>(*this); }
627 
628 private:
629  const Film::RGBA mRGBA;
630 };
631 
632 
640 template<typename GridT = Film::RGBA,
641  typename SamplerType = tools::PointSampler>
643 {
644 public:
645  NormalShader(const GridT& grid) : mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
646  NormalShader(const NormalShader&) = default;
647  ~NormalShader() override = default;
648  Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R&) const override
649  {
650  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
651  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
652  return Film::RGBA(v[0]*(normal[0]+1.0), v[1]*(normal[1]+1.0), v[2]*(normal[2]+1.0));
653  }
654  BaseShader* copy() const override { return new NormalShader<GridT, SamplerType>(*this); }
655 
656 private:
657  typename GridT::ConstAccessor mAcc;
658  const math::Transform* mXform;
659 };
660 
661 // Template specialization using a constant color of the material.
662 template<typename SamplerType>
663 class NormalShader<Film::RGBA, SamplerType>: public BaseShader
664 {
665 public:
666  NormalShader(const Film::RGBA& c = Film::RGBA(1.0f)) : mRGBA(c*0.5f) {}
667  NormalShader(const NormalShader&) = default;
668  ~NormalShader() override = default;
669  Film::RGBA operator()(const Vec3R&, const Vec3R& normal, const Vec3R&) const override
670  {
671  return mRGBA * Film::RGBA(normal[0] + 1.0, normal[1] + 1.0, normal[2] + 1.0);
672  }
673  BaseShader* copy() const override { return new NormalShader<Film::RGBA, SamplerType>(*this); }
674 
675 private:
676  const Film::RGBA mRGBA;
677 };
678 
679 
687 template<typename GridT = Film::RGBA,
688  typename SamplerType = tools::PointSampler>
690 {
691 public:
692  PositionShader(const math::BBox<Vec3R>& bbox, const GridT& grid)
693  : mMin(bbox.min())
694  , mInvDim(1.0/bbox.extents())
695  , mAcc(grid.getAccessor())
696  , mXform(&grid.transform())
697  {
698  }
699  PositionShader(const PositionShader&) = default;
700  ~PositionShader() override = default;
701  Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override
702  {
703  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
704  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
705  const Vec3R rgb = (xyz - mMin) * mInvDim;
706  return Film::RGBA(v[0],v[1],v[2]) * Film::RGBA(rgb[0], rgb[1], rgb[2]);
707  }
708  BaseShader* copy() const override { return new PositionShader<GridT, SamplerType>(*this); }
709 
710 private:
711  const Vec3R mMin, mInvDim;
712  typename GridT::ConstAccessor mAcc;
713  const math::Transform* mXform;
714 };
715 
716 // Template specialization using a constant color of the material.
717 template<typename SamplerType>
718 class PositionShader<Film::RGBA, SamplerType>: public BaseShader
719 {
720 public:
721  PositionShader(const math::BBox<Vec3R>& bbox, const Film::RGBA& c = Film::RGBA(1.0f))
722  : mMin(bbox.min()), mInvDim(1.0/bbox.extents()), mRGBA(c) {}
723  PositionShader(const PositionShader&) = default;
724  ~PositionShader() override = default;
725  Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override
726  {
727  const Vec3R rgb = (xyz - mMin)*mInvDim;
728  return mRGBA*Film::RGBA(rgb[0], rgb[1], rgb[2]);
729  }
730  BaseShader* copy() const override { return new PositionShader<Film::RGBA, SamplerType>(*this); }
731 
732 private:
733  const Vec3R mMin, mInvDim;
734  const Film::RGBA mRGBA;
735 };
736 
737 
747 template<typename GridT = Film::RGBA,
748  typename SamplerType = tools::PointSampler>
750 {
751 public:
752  DiffuseShader(const GridT& grid): mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
753  DiffuseShader(const DiffuseShader&) = default;
754  ~DiffuseShader() override = default;
755  Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R& rayDir) const override
756  {
757  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
758  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
759  // We take the abs of the dot product corresponding to having
760  // light sources at +/- rayDir, i.e., two-sided shading.
761  return Film::RGBA(v[0],v[1],v[2])
762  * static_cast<Film::RGBA::ValueT>(math::Abs(normal.dot(rayDir)));
763  }
764  BaseShader* copy() const override { return new DiffuseShader<GridT, SamplerType>(*this); }
765 
766 private:
767  typename GridT::ConstAccessor mAcc;
768  const math::Transform* mXform;
769 };
770 
771 // Template specialization using a constant color of the material.
772 template <typename SamplerType>
773 class DiffuseShader<Film::RGBA, SamplerType>: public BaseShader
774 {
775 public:
776  DiffuseShader(const Film::RGBA& d = Film::RGBA(1.0f)): mRGBA(d) {}
777  DiffuseShader(const DiffuseShader&) = default;
778  ~DiffuseShader() override = default;
779  Film::RGBA operator()(const Vec3R&, const Vec3R& normal, const Vec3R& rayDir) const override
780  {
781  // We assume a single directional light source at the camera,
782  // so the cosine of the angle between the surface normal and the
783  // direction of the light source becomes the dot product of the
784  // surface normal and inverse direction of the ray. We also ignore
785  // negative dot products, corresponding to strict one-sided shading.
786  //return mRGBA * math::Max(0.0, normal.dot(-rayDir));
787 
788  // We take the abs of the dot product corresponding to having
789  // light sources at +/- rayDir, i.e., two-sided shading.
790  return mRGBA * static_cast<Film::RGBA::ValueT>(math::Abs(normal.dot(rayDir)));
791  }
792  BaseShader* copy() const override { return new DiffuseShader<Film::RGBA, SamplerType>(*this); }
793 
794 private:
795  const Film::RGBA mRGBA;
796 };
797 
798 
800 
801 template<typename GridT>
802 inline void rayTrace(const GridT& grid,
803  const BaseShader& shader,
804  BaseCamera& camera,
805  size_t pixelSamples,
806  unsigned int seed,
807  bool threaded)
808 {
810  tracer(grid, shader, camera, pixelSamples, seed);
811  tracer.render(threaded);
812 }
813 
814 
815 template<typename GridT, typename IntersectorT>
816 inline void rayTrace(const GridT&,
817  const IntersectorT& inter,
818  const BaseShader& shader,
819  BaseCamera& camera,
820  size_t pixelSamples,
821  unsigned int seed,
822  bool threaded)
823 {
824  LevelSetRayTracer<GridT, IntersectorT> tracer(inter, shader, camera, pixelSamples, seed);
825  tracer.render(threaded);
826 }
827 
828 
830 
831 
832 template<typename GridT, typename IntersectorT>
834 LevelSetRayTracer(const GridT& grid,
835  const BaseShader& shader,
836  BaseCamera& camera,
837  size_t pixelSamples,
838  unsigned int seed)
839  : mIsMaster(true),
840  mRand(nullptr),
841  mInter(grid),
842  mShader(shader.copy()),
843  mCamera(&camera)
844 {
845  this->setPixelSamples(pixelSamples, seed);
846 }
847 
848 template<typename GridT, typename IntersectorT>
850 LevelSetRayTracer(const IntersectorT& inter,
851  const BaseShader& shader,
852  BaseCamera& camera,
853  size_t pixelSamples,
854  unsigned int seed)
855  : mIsMaster(true),
856  mRand(nullptr),
857  mInter(inter),
858  mShader(shader.copy()),
859  mCamera(&camera)
860 {
861  this->setPixelSamples(pixelSamples, seed);
862 }
863 
864 template<typename GridT, typename IntersectorT>
867  mIsMaster(false),
868  mRand(other.mRand),
869  mInter(other.mInter),
870  mShader(other.mShader->copy()),
871  mCamera(other.mCamera),
872  mSubPixels(other.mSubPixels)
873 {
874 }
875 
876 template<typename GridT, typename IntersectorT>
879 {
880  if (mIsMaster) delete [] mRand;
881 }
882 
883 template<typename GridT, typename IntersectorT>
885 setGrid(const GridT& grid)
886 {
887  assert(mIsMaster);
888  mInter = IntersectorT(grid);
889 }
890 
891 template<typename GridT, typename IntersectorT>
893 setIntersector(const IntersectorT& inter)
894 {
895  assert(mIsMaster);
896  mInter = inter;
897 }
898 
899 template<typename GridT, typename IntersectorT>
901 setShader(const BaseShader& shader)
902 {
903  assert(mIsMaster);
904  mShader.reset(shader.copy());
905 }
906 
907 template<typename GridT, typename IntersectorT>
910 {
911  assert(mIsMaster);
912  mCamera = &camera;
913 }
914 
915 template<typename GridT, typename IntersectorT>
917 setPixelSamples(size_t pixelSamples, unsigned int seed)
918 {
919  assert(mIsMaster);
920  if (pixelSamples == 0) {
921  OPENVDB_THROW(ValueError, "pixelSamples must be larger than zero!");
922  }
923  mSubPixels = pixelSamples - 1;
924  delete [] mRand;
925  if (mSubPixels > 0) {
926  mRand = new double[16];
927  math::Rand01<double> rand(seed);//offsets for anti-aliaing by jittered super-sampling
928  for (size_t i=0; i<16; ++i) mRand[i] = rand();
929  } else {
930  mRand = nullptr;
931  }
932 }
933 
934 template<typename GridT, typename IntersectorT>
936 render(bool threaded) const
937 {
938  tbb::blocked_range<size_t> range(0, mCamera->height());
939  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
940 }
941 
942 template<typename GridT, typename IntersectorT>
944 operator()(const tbb::blocked_range<size_t>& range) const
945 {
946  const BaseShader& shader = *mShader;
947  Vec3Type xyz, nml;
948  const float frac = 1.0f / (1.0f + mSubPixels);
949  for (size_t j=range.begin(), n=0, je = range.end(); j<je; ++j) {
950  for (size_t i=0, ie = mCamera->width(); i<ie; ++i) {
951  Film::RGBA& bg = mCamera->pixel(i,j);
952  RayType ray = mCamera->getRay(i, j);//primary ray
953  Film::RGBA c = mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
954  for (size_t k=0; k<mSubPixels; ++k, n +=2 ) {
955  ray = mCamera->getRay(i, j, mRand[n & 15], mRand[(n+1) & 15]);
956  c += mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
957  }//loop over sub-pixels
958  bg = c*frac;
959  }//loop over image height
960  }//loop over image width
961 }
962 
964 
965 template<typename IntersectorT, typename SampleT>
967 VolumeRender(const IntersectorT& inter, BaseCamera& camera)
968  : mAccessor(inter.grid().getConstAccessor())
969  , mCamera(&camera)
970  , mPrimary(new IntersectorT(inter))
971  , mShadow(new IntersectorT(inter))
972  , mPrimaryStep(1.0)
973  , mShadowStep(3.0)
974  , mCutOff(0.005)
975  , mLightGain(0.2)
976  , mLightDir(Vec3R(0.3, 0.3, 0).unit())
977  , mLightColor(0.7, 0.7, 0.7)
978  , mAbsorption(0.1)
979  , mScattering(1.5)
980 {
981 }
982 
983 template<typename IntersectorT, typename SampleT>
986  : mAccessor(other.mAccessor)
987  , mCamera(other.mCamera)
988  , mPrimary(new IntersectorT(*(other.mPrimary)))
989  , mShadow(new IntersectorT(*(other.mShadow)))
990  , mPrimaryStep(other.mPrimaryStep)
991  , mShadowStep(other.mShadowStep)
992  , mCutOff(other.mCutOff)
993  , mLightGain(other.mLightGain)
994  , mLightDir(other.mLightDir)
995  , mLightColor(other.mLightColor)
996  , mAbsorption(other.mAbsorption)
997  , mScattering(other.mScattering)
998 {
999 }
1000 
1001 template<typename IntersectorT, typename SampleT>
1003 print(std::ostream& os, int verboseLevel)
1004 {
1005  if (verboseLevel>0) {
1006  os << "\nPrimary step: " << mPrimaryStep
1007  << "\nShadow step: " << mShadowStep
1008  << "\nCutoff: " << mCutOff
1009  << "\nLightGain: " << mLightGain
1010  << "\nLightDir: " << mLightDir
1011  << "\nLightColor: " << mLightColor
1012  << "\nAbsorption: " << mAbsorption
1013  << "\nScattering: " << mScattering << std::endl;
1014  }
1015  mPrimary->print(os, verboseLevel);
1016 }
1017 
1018 template<typename IntersectorT, typename SampleT>
1020 setIntersector(const IntersectorT& inter)
1021 {
1022  mPrimary.reset(new IntersectorT(inter));
1023  mShadow.reset( new IntersectorT(inter));
1024 }
1025 
1026 template<typename IntersectorT, typename SampleT>
1028 render(bool threaded) const
1029 {
1030  tbb::blocked_range<size_t> range(0, mCamera->height());
1031  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
1032 }
1033 
1034 template<typename IntersectorT, typename SampleT>
1036 operator()(const tbb::blocked_range<size_t>& range) const
1037 {
1038  SamplerType sampler(mAccessor, mShadow->grid().transform());//light-weight wrapper
1039 
1040  // Any variable prefixed with p (or s) means it's associated with a primary (or shadow) ray
1041  const Vec3R extinction = -mScattering-mAbsorption, One(1.0);
1042  const Vec3R albedo = mLightColor*mScattering/(mScattering+mAbsorption);//single scattering
1043  const Real sGain = mLightGain;//in-scattering along shadow ray
1044  const Real pStep = mPrimaryStep;//Integration step along primary ray in voxel units
1045  const Real sStep = mShadowStep;//Integration step along shadow ray in voxel units
1046  const Real cutoff = mCutOff;//Cutoff for density and transmittance
1047 
1048  // For the sake of completeness we show how to use two different
1049  // methods (hits/march) in VolumeRayIntersector that produce
1050  // segments along the ray that intersects active values. Comment out
1051  // the line below to use VolumeRayIntersector::march instead of
1052  // VolumeRayIntersector::hits.
1053 #define USE_HITS
1054 #ifdef USE_HITS
1055  std::vector<typename RayType::TimeSpan> pTS, sTS;
1056  //std::deque<typename RayType::TimeSpan> pTS, sTS;
1057 #endif
1058 
1059  RayType sRay(Vec3R(0), mLightDir);//Shadow ray
1060  for (size_t j=range.begin(), je = range.end(); j<je; ++j) {
1061  for (size_t i=0, ie = mCamera->width(); i<ie; ++i) {
1062  Film::RGBA& bg = mCamera->pixel(i, j);
1063  bg.a = bg.r = bg.g = bg.b = 0;
1064  RayType pRay = mCamera->getRay(i, j);// Primary ray
1065  if( !mPrimary->setWorldRay(pRay)) continue;
1066  Vec3R pTrans(1.0), pLumi(0.0);
1067 #ifndef USE_HITS
1068  Real pT0, pT1;
1069  while (mPrimary->march(pT0, pT1)) {
1070  for (Real pT = pStep*ceil(pT0/pStep); pT <= pT1; pT += pStep) {
1071 #else
1072  mPrimary->hits(pTS);
1073  for (size_t k=0; k<pTS.size(); ++k) {
1074  Real pT = pStep*ceil(pTS[k].t0/pStep), pT1=pTS[k].t1;
1075  for (; pT <= pT1; pT += pStep) {
1076 #endif
1077  Vec3R pPos = mPrimary->getWorldPos(pT);
1078  const Real density = sampler.wsSample(pPos);
1079  if (density < cutoff) continue;
1080  const Vec3R dT = math::Exp(extinction * density * pStep);
1081  Vec3R sTrans(1.0);
1082  sRay.setEye(pPos);
1083  if( !mShadow->setWorldRay(sRay)) continue;
1084 #ifndef USE_HITS
1085  Real sT0, sT1;
1086  while (mShadow->march(sT0, sT1)) {
1087  for (Real sT = sStep*ceil(sT0/sStep); sT <= sT1; sT+= sStep) {
1088 #else
1089  mShadow->hits(sTS);
1090  for (size_t l=0; l<sTS.size(); ++l) {
1091  Real sT = sStep*ceil(sTS[l].t0/sStep), sT1=sTS[l].t1;
1092  for (; sT <= sT1; sT+= sStep) {
1093 #endif
1094  const Real d = sampler.wsSample(mShadow->getWorldPos(sT));
1095  if (d < cutoff) continue;
1096  sTrans *= math::Exp(extinction * d * sStep/(1.0+sT*sGain));
1097  if (sTrans.lengthSqr()<cutoff) goto Luminance;//Terminate sRay
1098  }//Integration over shadow segment
1099  }// Shadow ray march
1100  Luminance:
1101  pLumi += albedo * sTrans * pTrans * (One-dT);
1102  pTrans *= dT;
1103  if (pTrans.lengthSqr()<cutoff) goto Pixel; // Terminate Ray
1104  }//Integration over primary segment
1105  }// Primary ray march
1106  Pixel:
1107  bg.r = static_cast<Film::RGBA::ValueT>(pLumi[0]);
1108  bg.g = static_cast<Film::RGBA::ValueT>(pLumi[1]);
1109  bg.b = static_cast<Film::RGBA::ValueT>(pLumi[2]);
1110  bg.a = static_cast<Film::RGBA::ValueT>(1.0f - pTrans.sum()/3.0f);
1111  }//Horizontal pixel scan
1112  }//Vertical pixel scan
1113 }
1114 
1115 } // namespace tools
1116 } // namespace OPENVDB_VERSION_NAME
1117 } // namespace openvdb
1118 
1119 #endif // OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
1120 
1121 // Copyright (c) 2012-2017 DreamWorks Animation LLC
1122 // All rights reserved. This software is distributed under the
1123 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
RGBA(ValueT _r, ValueT _g, ValueT _b, ValueT _a=static_cast< ValueT >(1.0))
Definition: RayTracer.h:268
BaseShader * copy() const override
Definition: RayTracer.h:708
Film::RGBA operator()(const Vec3R &, const Vec3R &, const Vec3R &) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:622
A simple class that allows for concurrent writes to pixels in an image, background initialization of ...
Definition: RayTracer.h:257
double mScaleWidth
Definition: RayTracer.h:463
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:768
void operator()(const tbb::blocked_range< size_t > &range) const
Public method required by tbb::parallel_for.
Definition: RayTracer.h:944
Calculate an axis-aligned bounding box in index space from a bounding sphere in world space...
Definition: Transform.h:66
Class that provides the interface for continuous sampling of values in a tree.
Definition: Interpolation.h:310
MatteShader(const GridT &grid)
Definition: RayTracer.h:598
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
RGBA & pixel(size_t w, size_t h)
Definition: RayTracer.h:313
Coord Abs(const Coord &xyz)
Definition: Coord.h:254
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:324
double Real
Definition: Types.h:63
BaseCamera(Film &film, const Vec3R &rotation, const Vec3R &translation, double frameWidth, double nearPlane, double farPlane)
Definition: RayTracer.h:405
BaseShader * copy() const override
Definition: RayTracer.h:792
void setCamera(BaseCamera &camera)
Set the camera derived from the abstract BaseCamera class.
Definition: RayTracer.h:202
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:143
void setIntersector(const IntersectorT &inter)
Set the intersector that performs the actual intersection of the rays against the volume...
Definition: RayTracer.h:1020
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:654
GridT GridType
Definition: RayTracer.h:106
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
size_t width() const
Definition: RayTracer.h:388
void setShader(const BaseShader &shader)
Set the shader derived from the abstract BaseShader class.
Definition: RayTracer.h:901
MatType rotation(const Quat< typename MatType::value_type > &q, typename MatType::value_type eps=static_cast< typename MatType::value_type >(1.0e-8))
Return the rotation matrix specified by the given quaternion.
Definition: Mat.h:169
VolumeRender(const IntersectorT &inter, BaseCamera &camera)
Constructor taking an intersector and a base camera.
Definition: RayTracer.h:967
Film(size_t width, size_t height, const RGBA &bg)
Definition: RayTracer.h:300
BaseShader * copy() const override
Definition: RayTracer.h:764
Axis-aligned bounding box.
Definition: BBox.h:47
math::Ray< double > getRay(size_t i, size_t j, double iOffset=0.5, double jOffset=0.5) const override
Return a Ray in world space given the pixel indices and optional offsets in the range [0...
Definition: RayTracer.h:503
void setScattering(Real x, Real y, Real z)
Set Scattering coefficients.
Definition: RayTracer.h:222
DiffuseShader(const GridT &grid)
Definition: RayTracer.h:752
Floating-point RGBA components in the range [0, 1].
Definition: RayTracer.h:262
virtual BaseShader * copy() const =0
math::Ray< double > getRay(size_t i, size_t j, double iOffset=0.5, double jOffset=0.5) const override
Return a Ray in world space given the pixel indices and optional offsets in the range [0...
Definition: RayTracer.h:556
float ValueT
Definition: RayTracer.h:264
Definition: Math.h:859
RGBA(ValueT intensity)
Definition: RayTracer.h:267
Film(size_t width, size_t height)
Definition: RayTracer.h:296
void over(const RGBA &rhs)
Definition: RayTracer.h:283
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:610
const Vec3T & dir() const
Definition: Ray.h:121
void setPixelSamples(size_t pixelSamples, unsigned int seed=0)
Set the number of pixel samples and the seed for jittered sub-rays. A value larger than one implies a...
Definition: RayTracer.h:917
MatType unit(const MatType &mat, typename MatType::value_type eps=1.0e-8)
Return a copy of the given matrix with its upper 3x3 rows normalized.
Definition: Mat.h:643
void setEye(const Vec3Type &eye)
Definition: Ray.h:88
RGBA()
Definition: RayTracer.h:266
void lookAt(const Vec3R &xyz, const Vec3R &up=Vec3R(0.0, 1.0, 0.0))
Definition: RayTracer.h:430
typename GridType::ValueType ValueType
Definition: RayTracer.h:186
virtual math::Ray< double > getRay(size_t i, size_t j, double iOffset=0.5, double jOffset=0.5) const =0
Return a Ray in world space given the pixel indices and optional offsets in the range [0...
void scaleTimes(RealT scale)
Definition: Ray.h:107
void setLightDir(Real x, Real y, Real z)
Set the vector components of a directional light source.
Definition: RayTracer.h:210
typename IntersectorT::RayType RayType
Definition: RayTracer.h:185
Definition: Interpolation.h:123
size_t height() const
Definition: RayTracer.h:424
Vec3R rasterToScreen(double i, double j, double z) const
Definition: RayTracer.h:442
Film::RGBA operator()(const Vec3R &xyz, const Vec3R &, const Vec3R &) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:701
Accelerated intersection of a ray with a narrow-band level set or a generic (e.g. density) volume...
A (very) simple multithreaded ray tracer specifically for narrow-band level sets. ...
Definition: RayTracer.h:103
BaseShader * copy() const override
Definition: RayTracer.h:673
Vec3< T > unit(T eps=0) const
return normalized this, throws if null vector
Definition: Vec3.h:388
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Film::RGBA operator()(const Vec3R &, const Vec3R &normal, const Vec3R &) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:669
void checkerboard(const RGBA &c1=RGBA(0.3f), const RGBA &c2=RGBA(0.6f), size_t size=32)
Definition: RayTracer.h:321
void savePPM(const std::string &fileName)
Definition: RayTracer.h:331
BaseShader * copy() const override
Definition: RayTracer.h:730
LevelSetRayTracer(const GridT &grid, const BaseShader &shader, BaseCamera &camera, size_t pixelSamples=1, unsigned int seed=0)
Constructor based on an instance of the grid to be rendered.
Definition: RayTracer.h:834
Abstract base class for the shaders.
Definition: RayTracer.h:571
Simple diffuse Lambertian surface shader.
Definition: RayTracer.h:749
NormalShader(const GridT &grid)
Definition: RayTracer.h:645
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:215
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:376
Vec3< typename promote< T, typename Coord::ValueType >::type > operator+(const Vec3< T > &v0, const Coord &v1)
Allow a Coord to be added to or subtracted from a Vec3.
Definition: Coord.h:501
void setCutOff(Real cutOff)
Set the cut-off value for density and transmittance.
Definition: RayTracer.h:232
Definition: Exceptions.h:39
void setCamera(BaseCamera &camera)
Set the camera derived from the abstract BaseCamera class.
Definition: RayTracer.h:909
ValueT r
Definition: RayTracer.h:292
RGBA(double _r, double _g, double _b, double _a=1.0)
Definition: RayTracer.h:271
BaseShader * copy() const override
Definition: RayTracer.h:607
MatteShader(const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:619
OrthographicCamera(Film &film, const Vec3R &rotation=Vec3R(0.0), const Vec3R &translation=Vec3R(0.0), double frameWidth=1.0, double nearPlane=1e-3, double farPlane=std::numeric_limits< double >::max())
Constructor.
Definition: RayTracer.h:545
typename IntersectorT::GridType GridType
Definition: RayTracer.h:184
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
void setIntersector(const IntersectorT &inter)
Set the intersector that performs the actual intersection of the rays against the narrow-band level s...
Definition: RayTracer.h:893
void setShadowStep(Real shadowStep)
Set the integration step-size in voxel units for the primay ray.
Definition: RayTracer.h:219
static double focalLengthToFieldOfView(double length, double aperture)
Return the horizontal field of view in degrees given a focal lenth in mm and the specified aperture i...
Definition: RayTracer.h:517
ValueT b
Definition: RayTracer.h:292
BaseShader * copy() const override
Definition: RayTracer.h:654
math::AffineMap mScreenToWorld
Definition: RayTracer.h:465
void setDir(const Vec3Type &dir)
Definition: Ray.h:90
NormalShader(const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:666
static double fieldOfViewToFocalLength(double fov, double aperture)
Return the focal length in mm given a horizontal field of view in degrees and the specified aperture ...
Definition: RayTracer.h:523
void render(bool threaded=true) const
Perform the actual (potentially multithreaded) ray-tracing.
Definition: RayTracer.h:936
Film::RGBA & pixel(size_t i, size_t j)
Definition: RayTracer.h:421
void fill(const RGBA &rgb=RGBA(0))
Definition: RayTracer.h:320
void setGrid(const GridT &grid)
Set the level set grid to be ray-traced.
Definition: RayTracer.h:885
const RGBA & pixel(size_t w, size_t h) const
Definition: RayTracer.h:306
Abstract base class for the perspective and orthographic cameras.
Definition: RayTracer.h:402
Definition: Exceptions.h:92
void setPrimaryStep(Real primaryStep)
Set the integration step-size in voxel units for the primay ray.
Definition: RayTracer.h:216
~LevelSetRayTracer()
Destructor.
Definition: RayTracer.h:878
math::Vec3< Real > Vec3R
Definition: Types.h:75
Definition: Math.h:858
PerspectiveCamera(Film &film, const Vec3R &rotation=Vec3R(0.0), const Vec3R &translation=Vec3R(0.0), double focalLength=50.0, double aperture=41.2136, double nearPlane=1e-3, double farPlane=std::numeric_limits< double >::max())
Constructor.
Definition: RayTracer.h:487
DiffuseShader(const Film::RGBA &d=Film::RGBA(1.0f))
Definition: RayTracer.h:776
size_t width() const
Definition: RayTracer.h:423
typename IntersectorT::RayType RayType
Definition: RayTracer.h:108
void initRay(double t0, double t1)
Definition: RayTracer.h:455
void setLightGain(Real gain)
Set parameter that imitates multi-scattering. A value of zero implies no multi-scattering.
Definition: RayTracer.h:229
Film::RGBA operator()(const Vec3R &, const Vec3R &normal, const Vec3R &rayDir) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:779
virtual ~BaseCamera()
Definition: RayTracer.h:419
size_t height() const
Definition: RayTracer.h:389
ValueT g
Definition: RayTracer.h:292
typename GridType::ConstAccessor AccessorType
Definition: RayTracer.h:187
Film::RGBA operator()(const Vec3R &xyz, const Vec3R &normal, const Vec3R &rayDir) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:755
RGBA & operator+=(const RGBA &rhs)
Definition: RayTracer.h:281
Color shader that treats position (x, y, z) as an RGB color in a cube defined from an axis-aligned bo...
Definition: RayTracer.h:689
Film::RGBA operator()(const Vec3R &xyz, const Vec3R &, const Vec3R &) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:601
void rayTrace(const GridT &, const IntersectorT &, const BaseShader &, BaseCamera &, size_t pixelSamples=1, unsigned int seed=0, bool threaded=true)
Ray-trace a volume using a given ray intersector.
Definition: RayTracer.h:816
Film::RGBA operator()(const Vec3R &xyz, const Vec3R &normal, const Vec3R &) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:648
void render(bool threaded=true) const
Perform the actual (potentially multithreaded) volume rendering.
Definition: RayTracer.h:1028
void operator()(const tbb::blocked_range< size_t > &range) const
Public method required by tbb::parallel_for.
Definition: RayTracer.h:1036
Type Exp(const Type &x)
Return .
Definition: Math.h:676
Color shader that treats the surface normal (x, y, z) as an RGB color.
Definition: RayTracer.h:642
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Shader that produces a simple matte.
Definition: RayTracer.h:595
void setAbsorption(Real x, Real y, Real z)
Set absorption coefficients.
Definition: RayTracer.h:225
PositionShader(const math::BBox< Vec3R > &bbox, const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:721
PositionShader(const math::BBox< Vec3R > &bbox, const GridT &grid)
Definition: RayTracer.h:692
void print(std::ostream &os=std::cout, int verboseLevel=1)
Print parameters, statistics, memory usage and other information.
Definition: RayTracer.h:1003
typename IntersectorT::Vec3Type Vec3Type
Definition: RayTracer.h:107
ValueT a
Definition: RayTracer.h:292
A Ray class.
BaseShader()
Definition: RayTracer.h:575
T lengthSqr() const
Definition: Vec3.h:235
BaseShader * copy() const override
Definition: RayTracer.h:626
void setLightColor(Real r, Real g, Real b)
Set the color of the directional light source.
Definition: RayTracer.h:213
A (very) simple multithreaded volume render specifically for scalar density.
Definition: RayTracer.h:180
math::Ray< double > mRay
Definition: RayTracer.h:464
Film::RGBA operator()(const Vec3R &xyz, const Vec3R &, const Vec3R &) const override
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:725
const RGBA * pixels() const
Definition: RayTracer.h:391
size_t numPixels() const
Definition: RayTracer.h:390
Film * mFilm
Definition: RayTracer.h:462
Definition: Math.h:857