OpenVDB  6.1.0
RayTracer.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2019 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 <deque>
55 #include <iostream>
56 #include <fstream>
57 #include <limits>
58 #include <memory>
59 #include <string>
60 #include <type_traits>
61 #include <vector>
62 
63 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
64 #include <OpenEXR/ImfPixelType.h>
65 #include <OpenEXR/ImfChannelList.h>
66 #include <OpenEXR/ImfOutputFile.h>
67 #include <OpenEXR/ImfHeader.h>
68 #include <OpenEXR/ImfFrameBuffer.h>
69 #endif
70 
71 namespace openvdb {
73 namespace OPENVDB_VERSION_NAME {
74 namespace tools {
75 
76 // Forward declarations
77 class BaseCamera;
78 class BaseShader;
79 
81 template<typename GridT>
82 inline void rayTrace(const GridT&,
83  const BaseShader&,
84  BaseCamera&,
85  size_t pixelSamples = 1,
86  unsigned int seed = 0,
87  bool threaded = true);
88 
90 template<typename GridT, typename IntersectorT>
91 inline void rayTrace(const GridT&,
92  const IntersectorT&,
93  const BaseShader&,
94  BaseCamera&,
95  size_t pixelSamples = 1,
96  unsigned int seed = 0,
97  bool threaded = true);
98 
99 
101 
104 template<typename GridT, typename IntersectorT = tools::LevelSetRayIntersector<GridT> >
106 {
107 public:
108  using GridType = GridT;
109  using Vec3Type = typename IntersectorT::Vec3Type;
110  using RayType = typename IntersectorT::RayType;
111 
113  LevelSetRayTracer(const GridT& grid,
114  const BaseShader& shader,
115  BaseCamera& camera,
116  size_t pixelSamples = 1,
117  unsigned int seed = 0);
118 
121  LevelSetRayTracer(const IntersectorT& inter,
122  const BaseShader& shader,
123  BaseCamera& camera,
124  size_t pixelSamples = 1,
125  unsigned int seed = 0);
126 
128  LevelSetRayTracer(const LevelSetRayTracer& other);
129 
132 
134  void setGrid(const GridT& grid);
135 
138  void setIntersector(const IntersectorT& inter);
139 
147  void setShader(const BaseShader& shader);
148 
150  void setCamera(BaseCamera& camera);
151 
156  void setPixelSamples(size_t pixelSamples, unsigned int seed = 0);
157 
159  void render(bool threaded = true) const;
160 
163  void operator()(const tbb::blocked_range<size_t>& range) const;
164 
165 private:
166  const bool mIsMaster;
167  double* mRand;
168  IntersectorT mInter;
169  std::unique_ptr<const BaseShader> mShader;
170  BaseCamera* mCamera;
171  size_t mSubPixels;
172 };// LevelSetRayTracer
173 
174 
176 
181 template <typename IntersectorT, typename SamplerT = tools::BoxSampler>
183 {
184 public:
185 
186  using GridType = typename IntersectorT::GridType;
187  using RayType = typename IntersectorT::RayType;
188  using ValueType = typename GridType::ValueType;
189  using AccessorType = typename GridType::ConstAccessor;
191  static_assert(std::is_floating_point<ValueType>::value,
192  "VolumeRender requires a floating-point-valued grid");
193 
195  VolumeRender(const IntersectorT& inter, BaseCamera& camera);
196 
198  VolumeRender(const VolumeRender& other);
199 
201  void render(bool threaded=true) const;
202 
204  void setCamera(BaseCamera& camera) { mCamera = &camera; }
205 
208  void setIntersector(const IntersectorT& inter);
209 
212  void setLightDir(Real x, Real y, Real z) { mLightDir = Vec3R(x,y,z).unit(); }
213 
215  void setLightColor(Real r, Real g, Real b) { mLightColor = Vec3R(r,g,b); }
216 
218  void setPrimaryStep(Real primaryStep) { mPrimaryStep = primaryStep; }
219 
221  void setShadowStep(Real shadowStep) { mShadowStep = shadowStep; }
222 
224  void setScattering(Real x, Real y, Real z) { mScattering = Vec3R(x,y,z); }
225 
227  void setAbsorption(Real x, Real y, Real z) { mAbsorption = Vec3R(x,y,z); }
228 
231  void setLightGain(Real gain) { mLightGain = gain; }
232 
234  void setCutOff(Real cutOff) { mCutOff = cutOff; }
235 
240  void print(std::ostream& os = std::cout, int verboseLevel = 1);
241 
244  void operator()(const tbb::blocked_range<size_t>& range) const;
245 
246 private:
247 
248  AccessorType mAccessor;
249  BaseCamera* mCamera;
250  std::unique_ptr<IntersectorT> mPrimary, mShadow;
251  Real mPrimaryStep, mShadowStep, mCutOff, mLightGain;
252  Vec3R mLightDir, mLightColor, mAbsorption, mScattering;
253 };//VolumeRender
254 
256 
259 class Film
260 {
261 public:
264  struct RGBA
265  {
266  using ValueT = float;
267 
268  RGBA() : r(0), g(0), b(0), a(1) {}
269  explicit RGBA(ValueT intensity) : r(intensity), g(intensity), b(intensity), a(1) {}
270  RGBA(ValueT _r, ValueT _g, ValueT _b, ValueT _a = static_cast<ValueT>(1.0)):
271  r(_r), g(_g), b(_b), a(_a)
272  {}
273  RGBA(double _r, double _g, double _b, double _a = 1.0)
274  : r(static_cast<ValueT>(_r))
275  , g(static_cast<ValueT>(_g))
276  , b(static_cast<ValueT>(_b))
277  , a(static_cast<ValueT>(_a))
278  {}
279 
280  RGBA operator* (ValueT scale) const { return RGBA(r*scale, g*scale, b*scale);}
281  RGBA operator+ (const RGBA& rhs) const { return RGBA(r+rhs.r, g+rhs.g, b+rhs.b);}
282  RGBA operator* (const RGBA& rhs) const { return RGBA(r*rhs.r, g*rhs.g, b*rhs.b);}
283  RGBA& operator+=(const RGBA& rhs) { r+=rhs.r; g+=rhs.g; b+=rhs.b; a+=rhs.a; return *this;}
284 
285  void over(const RGBA& rhs)
286  {
287  const float s = rhs.a*(1.0f-a);
288  r = a*r+s*rhs.r;
289  g = a*g+s*rhs.g;
290  b = a*b+s*rhs.b;
291  a = a + s;
292  }
293 
294  ValueT r, g, b, a;
295  };
296 
297 
298  Film(size_t width, size_t height)
299  : mWidth(width), mHeight(height), mSize(width*height), mPixels(new RGBA[mSize])
300  {
301  }
302  Film(size_t width, size_t height, const RGBA& bg)
303  : mWidth(width), mHeight(height), mSize(width*height), mPixels(new RGBA[mSize])
304  {
305  this->fill(bg);
306  }
307 
308  const RGBA& pixel(size_t w, size_t h) const
309  {
310  assert(w < mWidth);
311  assert(h < mHeight);
312  return mPixels[w + h*mWidth];
313  }
314 
315  RGBA& pixel(size_t w, size_t h)
316  {
317  assert(w < mWidth);
318  assert(h < mHeight);
319  return mPixels[w + h*mWidth];
320  }
321 
322  void fill(const RGBA& rgb=RGBA(0)) { for (size_t i=0; i<mSize; ++i) mPixels[i] = rgb; }
323  void checkerboard(const RGBA& c1=RGBA(0.3f), const RGBA& c2=RGBA(0.6f), size_t size=32)
324  {
325  RGBA *p = mPixels.get();
326  for (size_t j = 0; j < mHeight; ++j) {
327  for (size_t i = 0; i < mWidth; ++i, ++p) {
328  *p = ((i & size) ^ (j & size)) ? c1 : c2;
329  }
330  }
331  }
332 
333  void savePPM(const std::string& fileName)
334  {
335  std::string name(fileName);
336  if (name.find_last_of(".") == std::string::npos) name.append(".ppm");
337 
338  std::unique_ptr<unsigned char[]> buffer(new unsigned char[3*mSize]);
339  unsigned char *tmp = buffer.get(), *q = tmp;
340  RGBA* p = mPixels.get();
341  size_t n = mSize;
342  while (n--) {
343  *q++ = static_cast<unsigned char>(255.0f*(*p ).r);
344  *q++ = static_cast<unsigned char>(255.0f*(*p ).g);
345  *q++ = static_cast<unsigned char>(255.0f*(*p++).b);
346  }
347 
348  std::ofstream os(name.c_str(), std::ios_base::binary);
349  if (!os.is_open()) {
350  std::cerr << "Error opening PPM file \"" << name << "\"" << std::endl;
351  return;
352  }
353 
354  os << "P6\n" << mWidth << " " << mHeight << "\n255\n";
355  os.write(reinterpret_cast<const char*>(&(*tmp)), 3 * mSize * sizeof(unsigned char));
356  }
357 
358 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
359  void saveEXR(const std::string& fileName, size_t compression = 2, size_t threads = 8)
360  {
361  std::string name(fileName);
362  if (name.find_last_of(".") == std::string::npos) name.append(".exr");
363 
364  if (threads>0) Imf::setGlobalThreadCount(threads);
365  Imf::Header header(mWidth, mHeight);
366  if (compression==0) header.compression() = Imf::NO_COMPRESSION;
367  if (compression==1) header.compression() = Imf::RLE_COMPRESSION;
368  if (compression>=2) header.compression() = Imf::ZIP_COMPRESSION;
369  header.channels().insert("R", Imf::Channel(Imf::FLOAT));
370  header.channels().insert("G", Imf::Channel(Imf::FLOAT));
371  header.channels().insert("B", Imf::Channel(Imf::FLOAT));
372  header.channels().insert("A", Imf::Channel(Imf::FLOAT));
373 
374  Imf::FrameBuffer framebuffer;
375  framebuffer.insert("R", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].r),
376  sizeof (RGBA), sizeof (RGBA) * mWidth));
377  framebuffer.insert("G", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].g),
378  sizeof (RGBA), sizeof (RGBA) * mWidth));
379  framebuffer.insert("B", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].b),
380  sizeof (RGBA), sizeof (RGBA) * mWidth));
381  framebuffer.insert("A", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].a),
382  sizeof (RGBA), sizeof (RGBA) * mWidth));
383 
384  Imf::OutputFile file(name.c_str(), header);
385  file.setFrameBuffer(framebuffer);
386  file.writePixels(mHeight);
387  }
388 #endif
389 
390  size_t width() const { return mWidth; }
391  size_t height() const { return mHeight; }
392  size_t numPixels() const { return mSize; }
393  const RGBA* pixels() const { return mPixels.get(); }
394 
395 private:
396  size_t mWidth, mHeight, mSize;
397  std::unique_ptr<RGBA[]> mPixels;
398 };// Film
399 
400 
402 
405 {
406 public:
407  BaseCamera(Film& film, const Vec3R& rotation, const Vec3R& translation,
408  double frameWidth, double nearPlane, double farPlane)
409  : mFilm(&film)
410  , mScaleWidth(frameWidth)
411  , mScaleHeight(frameWidth * double(film.height()) / double(film.width()))
412  {
413  assert(nearPlane > 0 && farPlane > nearPlane);
414  mScreenToWorld.accumPostRotation(math::X_AXIS, rotation[0] * M_PI / 180.0);
415  mScreenToWorld.accumPostRotation(math::Y_AXIS, rotation[1] * M_PI / 180.0);
416  mScreenToWorld.accumPostRotation(math::Z_AXIS, rotation[2] * M_PI / 180.0);
417  mScreenToWorld.accumPostTranslation(translation);
418  this->initRay(nearPlane, farPlane);
419  }
420 
421  virtual ~BaseCamera() {}
422 
423  Film::RGBA& pixel(size_t i, size_t j) { return mFilm->pixel(i, j); }
424 
425  size_t width() const { return mFilm->width(); }
426  size_t height() const { return mFilm->height(); }
427 
432  void lookAt(const Vec3R& xyz, const Vec3R& up = Vec3R(0.0, 1.0, 0.0))
433  {
434  const Vec3R orig = mScreenToWorld.applyMap(Vec3R(0.0));
435  const Vec3R dir = orig - xyz;
436  try {
437  Mat4d xform = math::aim<Mat4d>(dir, up);
438  xform.postTranslate(orig);
439  mScreenToWorld = math::AffineMap(xform);
440  this->initRay(mRay.t0(), mRay.t1());
441  } catch (...) {}
442  }
443 
444  Vec3R rasterToScreen(double i, double j, double z) const
445  {
446  return Vec3R( (2 * i / double(mFilm->width()) - 1) * mScaleWidth,
447  (1 - 2 * j / double(mFilm->height())) * mScaleHeight, z );
448  }
449 
453  virtual math::Ray<double> getRay(
454  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const = 0;
455 
456 protected:
457  void initRay(double t0, double t1)
458  {
459  mRay.setTimes(t0, t1);
460  mRay.setEye(mScreenToWorld.applyMap(Vec3R(0.0)));
461  mRay.setDir(mScreenToWorld.applyJacobian(Vec3R(0.0, 0.0, -1.0)));
462  }
463 
465  double mScaleWidth, mScaleHeight;
468 };// BaseCamera
469 
470 
472 {
473  public:
490  const Vec3R& rotation = Vec3R(0.0),
491  const Vec3R& translation = Vec3R(0.0),
492  double focalLength = 50.0,
493  double aperture = 41.2136,
494  double nearPlane = 1e-3,
495  double farPlane = std::numeric_limits<double>::max())
496  : BaseCamera(film, rotation, translation, 0.5*aperture/focalLength, nearPlane, farPlane)
497  {
498  }
499 
500  ~PerspectiveCamera() override = default;
501 
506  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const override
507  {
508  math::Ray<double> ray(mRay);
509  Vec3R dir = BaseCamera::rasterToScreen(Real(i) + iOffset, Real(j) + jOffset, -1.0);
510  dir = BaseCamera::mScreenToWorld.applyJacobian(dir);
511  dir.normalize();
512  ray.scaleTimes(1.0/dir.dot(ray.dir()));
513  ray.setDir(dir);
514  return ray;
515  }
516 
519  static double focalLengthToFieldOfView(double length, double aperture)
520  {
521  return 360.0 / M_PI * atan(aperture/(2.0*length));
522  }
525  static double fieldOfViewToFocalLength(double fov, double aperture)
526  {
527  return aperture/(2.0*(tan(fov * M_PI / 360.0)));
528  }
529 };// PerspectiveCamera
530 
531 
533 {
534 public:
548  const Vec3R& rotation = Vec3R(0.0),
549  const Vec3R& translation = Vec3R(0.0),
550  double frameWidth = 1.0,
551  double nearPlane = 1e-3,
552  double farPlane = std::numeric_limits<double>::max())
553  : BaseCamera(film, rotation, translation, 0.5*frameWidth, nearPlane, farPlane)
554  {
555  }
556  ~OrthographicCamera() override = default;
557 
559  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const override
560  {
561  math::Ray<double> ray(mRay);
562  Vec3R eye = BaseCamera::rasterToScreen(Real(i) + iOffset, Real(j) + jOffset, 0.0);
563  ray.setEye(BaseCamera::mScreenToWorld.applyMap(eye));
564  return ray;
565  }
566 };// OrthographicCamera
567 
568 
570 
571 
574 {
575 public:
578  BaseShader(const BaseShader&) = default;
579  virtual ~BaseShader() = default;
584  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R& nml, const Vec3R& dir) const = 0;
585  virtual BaseShader* copy() const = 0;
586 };
587 
588 
595 template<typename GridT = Film::RGBA,
596  typename SamplerType = tools::PointSampler>
597 class MatteShader: public BaseShader
598 {
599 public:
600  MatteShader(const GridT& grid) : mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
601  MatteShader(const MatteShader&) = default;
602  ~MatteShader() override = default;
603  Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override
604  {
605  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
606  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
607  return Film::RGBA(v[0], v[1], v[2]);
608  }
609  BaseShader* copy() const override { return new MatteShader<GridT, SamplerType>(*this); }
610 
611 private:
612  typename GridT::ConstAccessor mAcc;
613  const math::Transform* mXform;
614 };
615 
616 // Template specialization using a constant color of the material.
617 template<typename SamplerType>
618 class MatteShader<Film::RGBA, SamplerType>: public BaseShader
619 {
620 public:
621  MatteShader(const Film::RGBA& c = Film::RGBA(1.0f)): mRGBA(c) {}
622  MatteShader(const MatteShader&) = default;
623  ~MatteShader() override = default;
624  Film::RGBA operator()(const Vec3R&, const Vec3R&, const Vec3R&) const override
625  {
626  return mRGBA;
627  }
628  BaseShader* copy() const override { return new MatteShader<Film::RGBA, SamplerType>(*this); }
629 
630 private:
631  const Film::RGBA mRGBA;
632 };
633 
634 
642 template<typename GridT = Film::RGBA,
643  typename SamplerType = tools::PointSampler>
645 {
646 public:
647  NormalShader(const GridT& grid) : mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
648  NormalShader(const NormalShader&) = default;
649  ~NormalShader() override = default;
650  Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R&) const override
651  {
652  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
653  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
654  return Film::RGBA(v[0]*(normal[0]+1.0), v[1]*(normal[1]+1.0), v[2]*(normal[2]+1.0));
655  }
656  BaseShader* copy() const override { return new NormalShader<GridT, SamplerType>(*this); }
657 
658 private:
659  typename GridT::ConstAccessor mAcc;
660  const math::Transform* mXform;
661 };
662 
663 // Template specialization using a constant color of the material.
664 template<typename SamplerType>
665 class NormalShader<Film::RGBA, SamplerType>: public BaseShader
666 {
667 public:
668  NormalShader(const Film::RGBA& c = Film::RGBA(1.0f)) : mRGBA(c*0.5f) {}
669  NormalShader(const NormalShader&) = default;
670  ~NormalShader() override = default;
671  Film::RGBA operator()(const Vec3R&, const Vec3R& normal, const Vec3R&) const override
672  {
673  return mRGBA * Film::RGBA(normal[0] + 1.0, normal[1] + 1.0, normal[2] + 1.0);
674  }
675  BaseShader* copy() const override { return new NormalShader<Film::RGBA, SamplerType>(*this); }
676 
677 private:
678  const Film::RGBA mRGBA;
679 };
680 
681 
689 template<typename GridT = Film::RGBA,
690  typename SamplerType = tools::PointSampler>
692 {
693 public:
694  PositionShader(const math::BBox<Vec3R>& bbox, const GridT& grid)
695  : mMin(bbox.min())
696  , mInvDim(1.0/bbox.extents())
697  , mAcc(grid.getAccessor())
698  , mXform(&grid.transform())
699  {
700  }
701  PositionShader(const PositionShader&) = default;
702  ~PositionShader() override = default;
703  Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override
704  {
705  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
706  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
707  const Vec3R rgb = (xyz - mMin) * mInvDim;
708  return Film::RGBA(v[0],v[1],v[2]) * Film::RGBA(rgb[0], rgb[1], rgb[2]);
709  }
710  BaseShader* copy() const override { return new PositionShader<GridT, SamplerType>(*this); }
711 
712 private:
713  const Vec3R mMin, mInvDim;
714  typename GridT::ConstAccessor mAcc;
715  const math::Transform* mXform;
716 };
717 
718 // Template specialization using a constant color of the material.
719 template<typename SamplerType>
720 class PositionShader<Film::RGBA, SamplerType>: public BaseShader
721 {
722 public:
723  PositionShader(const math::BBox<Vec3R>& bbox, const Film::RGBA& c = Film::RGBA(1.0f))
724  : mMin(bbox.min()), mInvDim(1.0/bbox.extents()), mRGBA(c) {}
725  PositionShader(const PositionShader&) = default;
726  ~PositionShader() override = default;
727  Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const override
728  {
729  const Vec3R rgb = (xyz - mMin)*mInvDim;
730  return mRGBA*Film::RGBA(rgb[0], rgb[1], rgb[2]);
731  }
732  BaseShader* copy() const override { return new PositionShader<Film::RGBA, SamplerType>(*this); }
733 
734 private:
735  const Vec3R mMin, mInvDim;
736  const Film::RGBA mRGBA;
737 };
738 
739 
749 template<typename GridT = Film::RGBA,
750  typename SamplerType = tools::PointSampler>
752 {
753 public:
754  DiffuseShader(const GridT& grid): mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
755  DiffuseShader(const DiffuseShader&) = default;
756  ~DiffuseShader() override = default;
757  Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R& rayDir) const override
758  {
759  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
760  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
761  // We take the abs of the dot product corresponding to having
762  // light sources at +/- rayDir, i.e., two-sided shading.
763  return Film::RGBA(v[0],v[1],v[2])
764  * static_cast<Film::RGBA::ValueT>(math::Abs(normal.dot(rayDir)));
765  }
766  BaseShader* copy() const override { return new DiffuseShader<GridT, SamplerType>(*this); }
767 
768 private:
769  typename GridT::ConstAccessor mAcc;
770  const math::Transform* mXform;
771 };
772 
773 // Template specialization using a constant color of the material.
774 template <typename SamplerType>
775 class DiffuseShader<Film::RGBA, SamplerType>: public BaseShader
776 {
777 public:
778  DiffuseShader(const Film::RGBA& d = Film::RGBA(1.0f)): mRGBA(d) {}
779  DiffuseShader(const DiffuseShader&) = default;
780  ~DiffuseShader() override = default;
781  Film::RGBA operator()(const Vec3R&, const Vec3R& normal, const Vec3R& rayDir) const override
782  {
783  // We assume a single directional light source at the camera,
784  // so the cosine of the angle between the surface normal and the
785  // direction of the light source becomes the dot product of the
786  // surface normal and inverse direction of the ray. We also ignore
787  // negative dot products, corresponding to strict one-sided shading.
788  //return mRGBA * math::Max(0.0, normal.dot(-rayDir));
789 
790  // We take the abs of the dot product corresponding to having
791  // light sources at +/- rayDir, i.e., two-sided shading.
792  return mRGBA * static_cast<Film::RGBA::ValueT>(math::Abs(normal.dot(rayDir)));
793  }
794  BaseShader* copy() const override { return new DiffuseShader<Film::RGBA, SamplerType>(*this); }
795 
796 private:
797  const Film::RGBA mRGBA;
798 };
799 
800 
802 
803 template<typename GridT>
804 inline void rayTrace(const GridT& grid,
805  const BaseShader& shader,
806  BaseCamera& camera,
807  size_t pixelSamples,
808  unsigned int seed,
809  bool threaded)
810 {
812  tracer(grid, shader, camera, pixelSamples, seed);
813  tracer.render(threaded);
814 }
815 
816 
817 template<typename GridT, typename IntersectorT>
818 inline void rayTrace(const GridT&,
819  const IntersectorT& inter,
820  const BaseShader& shader,
821  BaseCamera& camera,
822  size_t pixelSamples,
823  unsigned int seed,
824  bool threaded)
825 {
826  LevelSetRayTracer<GridT, IntersectorT> tracer(inter, shader, camera, pixelSamples, seed);
827  tracer.render(threaded);
828 }
829 
830 
832 
833 
834 template<typename GridT, typename IntersectorT>
836 LevelSetRayTracer(const GridT& grid,
837  const BaseShader& shader,
838  BaseCamera& camera,
839  size_t pixelSamples,
840  unsigned int seed)
841  : mIsMaster(true),
842  mRand(nullptr),
843  mInter(grid),
844  mShader(shader.copy()),
845  mCamera(&camera)
846 {
847  this->setPixelSamples(pixelSamples, seed);
848 }
849 
850 template<typename GridT, typename IntersectorT>
852 LevelSetRayTracer(const IntersectorT& inter,
853  const BaseShader& shader,
854  BaseCamera& camera,
855  size_t pixelSamples,
856  unsigned int seed)
857  : mIsMaster(true),
858  mRand(nullptr),
859  mInter(inter),
860  mShader(shader.copy()),
861  mCamera(&camera)
862 {
863  this->setPixelSamples(pixelSamples, seed);
864 }
865 
866 template<typename GridT, typename IntersectorT>
869  mIsMaster(false),
870  mRand(other.mRand),
871  mInter(other.mInter),
872  mShader(other.mShader->copy()),
873  mCamera(other.mCamera),
874  mSubPixels(other.mSubPixels)
875 {
876 }
877 
878 template<typename GridT, typename IntersectorT>
881 {
882  if (mIsMaster) delete [] mRand;
883 }
884 
885 template<typename GridT, typename IntersectorT>
887 setGrid(const GridT& grid)
888 {
889  assert(mIsMaster);
890  mInter = IntersectorT(grid);
891 }
892 
893 template<typename GridT, typename IntersectorT>
895 setIntersector(const IntersectorT& inter)
896 {
897  assert(mIsMaster);
898  mInter = inter;
899 }
900 
901 template<typename GridT, typename IntersectorT>
903 setShader(const BaseShader& shader)
904 {
905  assert(mIsMaster);
906  mShader.reset(shader.copy());
907 }
908 
909 template<typename GridT, typename IntersectorT>
912 {
913  assert(mIsMaster);
914  mCamera = &camera;
915 }
916 
917 template<typename GridT, typename IntersectorT>
919 setPixelSamples(size_t pixelSamples, unsigned int seed)
920 {
921  assert(mIsMaster);
922  if (pixelSamples == 0) {
923  OPENVDB_THROW(ValueError, "pixelSamples must be larger than zero!");
924  }
925  mSubPixels = pixelSamples - 1;
926  delete [] mRand;
927  if (mSubPixels > 0) {
928  mRand = new double[16];
929  math::Rand01<double> rand(seed);//offsets for anti-aliaing by jittered super-sampling
930  for (size_t i=0; i<16; ++i) mRand[i] = rand();
931  } else {
932  mRand = nullptr;
933  }
934 }
935 
936 template<typename GridT, typename IntersectorT>
938 render(bool threaded) const
939 {
940  tbb::blocked_range<size_t> range(0, mCamera->height());
941  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
942 }
943 
944 template<typename GridT, typename IntersectorT>
946 operator()(const tbb::blocked_range<size_t>& range) const
947 {
948  const BaseShader& shader = *mShader;
949  Vec3Type xyz, nml;
950  const float frac = 1.0f / (1.0f + float(mSubPixels));
951  for (size_t j=range.begin(), n=0, je = range.end(); j<je; ++j) {
952  for (size_t i=0, ie = mCamera->width(); i<ie; ++i) {
953  Film::RGBA& bg = mCamera->pixel(i,j);
954  RayType ray = mCamera->getRay(i, j);//primary ray
955  Film::RGBA c = mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
956  for (size_t k=0; k<mSubPixels; ++k, n +=2 ) {
957  ray = mCamera->getRay(i, j, mRand[n & 15], mRand[(n+1) & 15]);
958  c += mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
959  }//loop over sub-pixels
960  bg = c*frac;
961  }//loop over image height
962  }//loop over image width
963 }
964 
966 
967 template<typename IntersectorT, typename SampleT>
969 VolumeRender(const IntersectorT& inter, BaseCamera& camera)
970  : mAccessor(inter.grid().getConstAccessor())
971  , mCamera(&camera)
972  , mPrimary(new IntersectorT(inter))
973  , mShadow(new IntersectorT(inter))
974  , mPrimaryStep(1.0)
975  , mShadowStep(3.0)
976  , mCutOff(0.005)
977  , mLightGain(0.2)
978  , mLightDir(Vec3R(0.3, 0.3, 0).unit())
979  , mLightColor(0.7, 0.7, 0.7)
980  , mAbsorption(0.1)
981  , mScattering(1.5)
982 {
983 }
984 
985 template<typename IntersectorT, typename SampleT>
988  : mAccessor(other.mAccessor)
989  , mCamera(other.mCamera)
990  , mPrimary(new IntersectorT(*(other.mPrimary)))
991  , mShadow(new IntersectorT(*(other.mShadow)))
992  , mPrimaryStep(other.mPrimaryStep)
993  , mShadowStep(other.mShadowStep)
994  , mCutOff(other.mCutOff)
995  , mLightGain(other.mLightGain)
996  , mLightDir(other.mLightDir)
997  , mLightColor(other.mLightColor)
998  , mAbsorption(other.mAbsorption)
999  , mScattering(other.mScattering)
1000 {
1001 }
1002 
1003 template<typename IntersectorT, typename SampleT>
1005 print(std::ostream& os, int verboseLevel)
1006 {
1007  if (verboseLevel>0) {
1008  os << "\nPrimary step: " << mPrimaryStep
1009  << "\nShadow step: " << mShadowStep
1010  << "\nCutoff: " << mCutOff
1011  << "\nLightGain: " << mLightGain
1012  << "\nLightDir: " << mLightDir
1013  << "\nLightColor: " << mLightColor
1014  << "\nAbsorption: " << mAbsorption
1015  << "\nScattering: " << mScattering << std::endl;
1016  }
1017  mPrimary->print(os, verboseLevel);
1018 }
1019 
1020 template<typename IntersectorT, typename SampleT>
1022 setIntersector(const IntersectorT& inter)
1023 {
1024  mPrimary.reset(new IntersectorT(inter));
1025  mShadow.reset( new IntersectorT(inter));
1026 }
1027 
1028 template<typename IntersectorT, typename SampleT>
1030 render(bool threaded) const
1031 {
1032  tbb::blocked_range<size_t> range(0, mCamera->height());
1033  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
1034 }
1035 
1036 template<typename IntersectorT, typename SampleT>
1038 operator()(const tbb::blocked_range<size_t>& range) const
1039 {
1040  SamplerType sampler(mAccessor, mShadow->grid().transform());//light-weight wrapper
1041 
1042  // Any variable prefixed with p (or s) means it's associated with a primary (or shadow) ray
1043  const Vec3R extinction = -mScattering-mAbsorption, One(1.0);
1044  const Vec3R albedo = mLightColor*mScattering/(mScattering+mAbsorption);//single scattering
1045  const Real sGain = mLightGain;//in-scattering along shadow ray
1046  const Real pStep = mPrimaryStep;//Integration step along primary ray in voxel units
1047  const Real sStep = mShadowStep;//Integration step along shadow ray in voxel units
1048  const Real cutoff = mCutOff;//Cutoff for density and transmittance
1049 
1050  // For the sake of completeness we show how to use two different
1051  // methods (hits/march) in VolumeRayIntersector that produce
1052  // segments along the ray that intersects active values. Comment out
1053  // the line below to use VolumeRayIntersector::march instead of
1054  // VolumeRayIntersector::hits.
1055 #define USE_HITS
1056 #ifdef USE_HITS
1057  std::vector<typename RayType::TimeSpan> pTS, sTS;
1058  //std::deque<typename RayType::TimeSpan> pTS, sTS;
1059 #endif
1060 
1061  RayType sRay(Vec3R(0), mLightDir);//Shadow ray
1062  for (size_t j=range.begin(), je = range.end(); j<je; ++j) {
1063  for (size_t i=0, ie = mCamera->width(); i<ie; ++i) {
1064  Film::RGBA& bg = mCamera->pixel(i, j);
1065  bg.a = bg.r = bg.g = bg.b = 0;
1066  RayType pRay = mCamera->getRay(i, j);// Primary ray
1067  if( !mPrimary->setWorldRay(pRay)) continue;
1068  Vec3R pTrans(1.0), pLumi(0.0);
1069 #ifndef USE_HITS
1070  Real pT0, pT1;
1071  while (mPrimary->march(pT0, pT1)) {
1072  for (Real pT = pStep*ceil(pT0/pStep); pT <= pT1; pT += pStep) {
1073 #else
1074  mPrimary->hits(pTS);
1075  for (size_t k=0; k<pTS.size(); ++k) {
1076  Real pT = pStep*ceil(pTS[k].t0/pStep), pT1=pTS[k].t1;
1077  for (; pT <= pT1; pT += pStep) {
1078 #endif
1079  Vec3R pPos = mPrimary->getWorldPos(pT);
1080  const Real density = sampler.wsSample(pPos);
1081  if (density < cutoff) continue;
1082  const Vec3R dT = math::Exp(extinction * density * pStep);
1083  Vec3R sTrans(1.0);
1084  sRay.setEye(pPos);
1085  if( !mShadow->setWorldRay(sRay)) continue;
1086 #ifndef USE_HITS
1087  Real sT0, sT1;
1088  while (mShadow->march(sT0, sT1)) {
1089  for (Real sT = sStep*ceil(sT0/sStep); sT <= sT1; sT+= sStep) {
1090 #else
1091  mShadow->hits(sTS);
1092  for (size_t l=0; l<sTS.size(); ++l) {
1093  Real sT = sStep*ceil(sTS[l].t0/sStep), sT1=sTS[l].t1;
1094  for (; sT <= sT1; sT+= sStep) {
1095 #endif
1096  const Real d = sampler.wsSample(mShadow->getWorldPos(sT));
1097  if (d < cutoff) continue;
1098  sTrans *= math::Exp(extinction * d * sStep/(1.0+sT*sGain));
1099  if (sTrans.lengthSqr()<cutoff) goto Luminance;//Terminate sRay
1100  }//Integration over shadow segment
1101  }// Shadow ray march
1102  Luminance:
1103  pLumi += albedo * sTrans * pTrans * (One-dT);
1104  pTrans *= dT;
1105  if (pTrans.lengthSqr()<cutoff) goto Pixel; // Terminate Ray
1106  }//Integration over primary segment
1107  }// Primary ray march
1108  Pixel:
1109  bg.r = static_cast<Film::RGBA::ValueT>(pLumi[0]);
1110  bg.g = static_cast<Film::RGBA::ValueT>(pLumi[1]);
1111  bg.b = static_cast<Film::RGBA::ValueT>(pLumi[2]);
1112  bg.a = static_cast<Film::RGBA::ValueT>(1.0f - pTrans.sum()/3.0f);
1113  }//Horizontal pixel scan
1114  }//Vertical pixel scan
1115 }
1116 
1117 } // namespace tools
1118 } // namespace OPENVDB_VERSION_NAME
1119 } // namespace openvdb
1120 
1121 #endif // OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
1122 
1123 // Copyright (c) 2012-2019 DreamWorks Animation LLC
1124 // All rights reserved. This software is distributed under the
1125 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
const RGBA & pixel(size_t w, size_t h) const
Definition: RayTracer.h:308
Coord Abs(const Coord &xyz)
Definition: Coord.h:536
void lookAt(const Vec3R &xyz, const Vec3R &up=Vec3R(0.0, 1.0, 0.0))
Definition: RayTracer.h:432
MatteShader(const GridT &grid)
Definition: RayTracer.h:600
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:387
VolumeRender(const IntersectorT &inter, BaseCamera &camera)
Constructor taking an intersector and a base camera.
Definition: RayTracer.h:969
Film * mFilm
Definition: RayTracer.h:464
RGBA()
Definition: RayTracer.h:268
Definition: Math.h:857
RGBA(ValueT intensity)
Definition: RayTracer.h:269
void render(bool threaded=true) const
Perform the actual (potentially multithreaded) ray-tracing.
Definition: RayTracer.h:938
Film::RGBA & pixel(size_t i, size_t j)
Definition: RayTracer.h:423
typename IntersectorT::RayType RayType
Definition: RayTracer.h:187
Definition: RayTracer.h:532
typename IntersectorT::GridType GridType
Definition: RayTracer.h:186
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
A (very) simple multithreaded ray tracer specifically for narrow-band level sets. ...
Definition: RayTracer.h:105
Vec3R rasterToScreen(double i, double j, double z) const
Definition: RayTracer.h:444
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:818
BaseShader * copy() const override
Definition: RayTracer.h:710
PositionShader(const math::BBox< Vec3R > &bbox, const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:723
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:781
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:624
void setEye(const Vec3Type &eye)
Definition: Ray.h:91
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
void setDir(const Vec3Type &dir)
Definition: Ray.h:93
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:703
A simple class that allows for concurrent writes to pixels in an image, background initialization of ...
Definition: RayTracer.h:259
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:327
Floating-point RGBA components in the range [0, 1].
Definition: RayTracer.h:264
void operator()(const tbb::blocked_range< size_t > &range) const
Public method required by tbb::parallel_for.
Definition: RayTracer.h:1038
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:603
void setPrimaryStep(Real primaryStep)
Set the integration step-size in voxel units for the primay ray.
Definition: RayTracer.h:218
virtual ~BaseCamera()
Definition: RayTracer.h:421
math::AffineMap mScreenToWorld
Definition: RayTracer.h:467
void savePPM(const std::string &fileName)
Definition: RayTracer.h:333
void scaleTimes(RealT scale)
Definition: Ray.h:111
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:919
void fill(const RGBA &rgb=RGBA(0))
Definition: RayTracer.h:322
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:836
Definition: Math.h:858
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition: Mat3.h:645
void setShader(const BaseShader &shader)
Set the shader derived from the abstract BaseShader class.
Definition: RayTracer.h:903
Axis-aligned bounding box.
Definition: BBox.h:50
MatType unit(const MatType &mat, typename MatType::value_type eps=1.0e-8)
Return a copy of the given matrix with its upper 3×3 rows normalized.
Definition: Mat.h:680
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:135
void setIntersector(const IntersectorT &inter)
Set the intersector that performs the actual intersection of the rays against the volume...
Definition: RayTracer.h:1022
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:547
Definition: Interpolation.h:123
NormalShader(const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:668
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:204
void setCamera(BaseCamera &camera)
Set the camera derived from the abstract BaseCamera class.
Definition: RayTracer.h:911
size_t width() const
Definition: RayTracer.h:390
void setLightGain(Real gain)
Set parameter that imitates multi-scattering. A value of zero implies no multi-scattering.
Definition: RayTracer.h:231
BaseShader()
Definition: RayTracer.h:577
void initRay(double t0, double t1)
Definition: RayTracer.h:457
void setShadowStep(Real shadowStep)
Set the integration step-size in voxel units for the primay ray.
Definition: RayTracer.h:221
void print(std::ostream &os=std::cout, int verboseLevel=1)
Print parameters, statistics, memory usage and other information.
Definition: RayTracer.h:1005
Type Exp(const Type &x)
Return ex.
Definition: Math.h:664
void operator()(const tbb::blocked_range< size_t > &range) const
Public method required by tbb::parallel_for.
Definition: RayTracer.h:946
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:505
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:671
MatteShader(const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:621
Accelerated intersection of a ray with a narrow-band level set or a generic (e.g. density) volume...
void setCutOff(Real cutOff)
Set the cut-off value for density and transmittance.
Definition: RayTracer.h:234
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
Simple diffuse Lambertian surface shader.
Definition: RayTracer.h:751
math::Vec3< Real > Vec3R
Definition: Types.h:79
typename IntersectorT::RayType RayType
Definition: RayTracer.h:110
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:125
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:546
BaseCamera(Film &film, const Vec3R &rotation, const Vec3R &translation, double frameWidth, double nearPlane, double farPlane)
Definition: RayTracer.h:407
void over(const RGBA &rhs)
Definition: RayTracer.h:285
math::Ray< double > mRay
Definition: RayTracer.h:466
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:727
Color shader that treats position (x, y, z) as an RGB color in a cube defined from an axis-aligned bo...
Definition: RayTracer.h:691
void setLightDir(Real x, Real y, Real z)
Set the vector components of a directional light source.
Definition: RayTracer.h:212
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:525
typename IntersectorT::Vec3Type Vec3Type
Definition: RayTracer.h:109
float ValueT
Definition: RayTracer.h:266
T lengthSqr() const
Definition: Vec3.h:236
RGBA & operator+=(const RGBA &rhs)
Definition: RayTracer.h:283
DiffuseShader(const Film::RGBA &d=Film::RGBA(1.0f))
Definition: RayTracer.h:778
double Real
Definition: Types.h:67
RGBA(double _r, double _g, double _b, double _a=1.0)
Definition: RayTracer.h:273
const Vec3T & dir() const
Definition: Ray.h:126
Definition: Exceptions.h:40
size_t width() const
Definition: RayTracer.h:425
Color shader that treats the surface normal (x, y, z) as an RGB color.
Definition: RayTracer.h:644
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...
size_t height() const
Definition: RayTracer.h:426
void checkerboard(const RGBA &c1=RGBA(0.3f), const RGBA &c2=RGBA(0.6f), size_t size=32)
Definition: RayTracer.h:323
double mScaleWidth
Definition: RayTracer.h:465
BaseShader * copy() const override
Definition: RayTracer.h:766
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:558
void setScattering(Real x, Real y, Real z)
Set Scattering coefficients.
Definition: RayTracer.h:224
typename GridType::ValueType ValueType
Definition: RayTracer.h:188
void setCamera(BaseCamera &camera)
Set the camera derived from the abstract BaseCamera class.
Definition: RayTracer.h:204
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:647
NormalShader(const GridT &grid)
Definition: RayTracer.h:647
Class that provides the interface for continuous sampling of values in a tree.
Definition: Interpolation.h:310
Definition: Transform.h:66
Film(size_t width, size_t height)
Definition: RayTracer.h:298
ValueT a
Definition: RayTracer.h:294
void render(bool threaded=true) const
Perform the actual (potentially multithreaded) volume rendering.
Definition: RayTracer.h:1030
ValueT b
Definition: RayTracer.h:294
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
RGBA(ValueT _r, ValueT _g, ValueT _b, ValueT _a=static_cast< ValueT >(1.0))
Definition: RayTracer.h:270
BaseShader * copy() const override
Definition: RayTracer.h:656
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:650
BaseShader * copy() const override
Definition: RayTracer.h:675
A (very) simple multithreaded volume render specifically for scalar density.
Definition: RayTracer.h:182
size_t height() const
Definition: RayTracer.h:391
Definition: Math.h:859
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:216
ValueT g
Definition: RayTracer.h:294
RGBA & pixel(size_t w, size_t h)
Definition: RayTracer.h:315
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:757
Mat4< double > Mat4d
Definition: Mat4.h:1361
virtual BaseShader * copy() const =0
Definition: Exceptions.h:92
BaseShader * copy() const override
Definition: RayTracer.h:628
ValueT r
Definition: RayTracer.h:294
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:177
size_t numPixels() const
Definition: RayTracer.h:392
A Ray class.
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:895
void setGrid(const GridT &grid)
Set the level set grid to be ray-traced.
Definition: RayTracer.h:887
DiffuseShader(const GridT &grid)
Definition: RayTracer.h:754
GridT GridType
Definition: RayTracer.h:108
Film(size_t width, size_t height, const RGBA &bg)
Definition: RayTracer.h:302
PositionShader(const math::BBox< Vec3R > &bbox, const GridT &grid)
Definition: RayTracer.h:694
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:489
BaseShader * copy() const override
Definition: RayTracer.h:794
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:760
Definition: RayTracer.h:471
void setAbsorption(Real x, Real y, Real z)
Set absorption coefficients.
Definition: RayTracer.h:227
Abstract base class for the shaders.
Definition: RayTracer.h:573
BaseShader * copy() const override
Definition: RayTracer.h:732
typename GridType::ConstAccessor AccessorType
Definition: RayTracer.h:189
~LevelSetRayTracer()
Destructor.
Definition: RayTracer.h:880
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:519
Abstract base class for the perspective and orthographic cameras.
Definition: RayTracer.h:404
Shader that produces a simple matte.
Definition: RayTracer.h:597
const RGBA * pixels() const
Definition: RayTracer.h:393
void setLightColor(Real r, Real g, Real b)
Set the color of the directional light source.
Definition: RayTracer.h:215
Vec3< T > unit(T eps=0) const
return normalized this, throws if null vector
Definition: Vec3.h:399
BaseShader * copy() const override
Definition: RayTracer.h:609