OpenVDB  3.0.0
RayTracer.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2014 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 //
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>
52 #include <openvdb/tools/RayIntersector.h>
53 #include <openvdb/tools/Interpolation.h>
54 #include <boost/scoped_ptr.hpp>
55 #include <boost/scoped_array.hpp>
56 #include <fstream>
57 #include <vector>
58 #include <deque>
59 
60 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
61 #include <OpenEXR/ImfPixelType.h>
62 #include <OpenEXR/ImfChannelList.h>
63 #include <OpenEXR/ImfOutputFile.h>
64 #include <OpenEXR/ImfHeader.h>
65 #include <OpenEXR/ImfFrameBuffer.h>
66 #endif
67 
68 namespace openvdb {
70 namespace OPENVDB_VERSION_NAME {
71 namespace tools {
72 
73 // Forward declarations
74 class BaseCamera;
75 class BaseShader;
76 
78 template<typename GridT>
79 inline void rayTrace(const GridT&,
80  const BaseShader&,
81  BaseCamera&,
82  size_t pixelSamples = 1,
83  unsigned int seed = 0,
84  bool threaded = true);
85 
87 template<typename GridT, typename IntersectorT>
88 inline void rayTrace(const GridT&,
89  const IntersectorT&,
90  const BaseShader&,
91  BaseCamera&,
92  size_t pixelSamples = 1,
93  unsigned int seed = 0,
94  bool threaded = true);
95 
96 
98 
101 template<typename GridT, typename IntersectorT = tools::LevelSetRayIntersector<GridT> >
103 {
104 public:
105  typedef GridT GridType;
106  typedef typename IntersectorT::Vec3Type Vec3Type;
107  typedef typename IntersectorT::RayType RayType;
108 
110  LevelSetRayTracer(const GridT& grid,
111  const BaseShader& shader,
112  BaseCamera& camera,
113  size_t pixelSamples = 1,
114  unsigned int seed = 0);
115 
118  LevelSetRayTracer(const IntersectorT& inter,
119  const BaseShader& shader,
120  BaseCamera& camera,
121  size_t pixelSamples = 1,
122  unsigned int seed = 0);
123 
125  LevelSetRayTracer(const LevelSetRayTracer& other);
126 
129 
131  void setGrid(const GridT& grid);
132 
135  void setIntersector(const IntersectorT& inter);
136 
144  void setShader(const BaseShader& shader);
145 
147  void setCamera(BaseCamera& camera);
148 
153  void setPixelSamples(size_t pixelSamples, unsigned int seed = 0);
154 
156  void render(bool threaded = true) const;
157 
160  void operator()(const tbb::blocked_range<size_t>& range) const;
161 
162 private:
163  const bool mIsMaster;
164  double* mRand;
165  IntersectorT mInter;
166  boost::scoped_ptr<const BaseShader> mShader;
167  BaseCamera* mCamera;
168  size_t mSubPixels;
169 };// LevelSetRayTracer
170 
171 
173 
178 template <typename IntersectorT, typename SamplerT = tools::BoxSampler>
180 {
181 public:
182 
183  typedef typename IntersectorT::GridType GridType;
184  typedef typename IntersectorT::RayType RayType;
185  typedef typename GridType::ValueType ValueType;
186  typedef typename GridType::ConstAccessor AccessorType;
188  BOOST_STATIC_ASSERT(boost::is_floating_point<ValueType>::value);
189 
191  VolumeRender(const IntersectorT& inter, BaseCamera& camera);
192 
194  VolumeRender(const VolumeRender& other);
195 
197  void render(bool threaded=true) const;
198 
200  void setCamera(BaseCamera& camera) { mCamera = &camera; }
201 
204  void setIntersector(const IntersectorT& inter);
205 
208  void setLightDir(Real x, Real y, Real z) { mLightDir = Vec3R(x,y,z).unit(); }
209 
211  void setLightColor(Real r, Real g, Real b) { mLightColor = Vec3R(r,g,b); }
212 
214  void setPrimaryStep(Real primaryStep) { mPrimaryStep = primaryStep; }
215 
217  void setShadowStep(Real shadowStep) { mShadowStep = shadowStep; }
218 
220  void setScattering(Real x, Real y, Real z) { mScattering = Vec3R(x,y,z); }
221 
223  void setAbsorption(Real x, Real y, Real z) { mAbsorption = Vec3R(x,y,z); }
224 
227  void setLightGain(Real gain) { mLightGain = gain; }
228 
230  void setCutOff(Real cutOff) { mCutOff = cutOff; }
231 
236  void print(std::ostream& os = std::cout, int verboseLevel = 1);
237 
240  void operator()(const tbb::blocked_range<size_t>& range) const;
241 
242 private:
243 
244  AccessorType mAccessor;
245  BaseCamera* mCamera;
246  boost::scoped_ptr<IntersectorT> mPrimary, mShadow;
247  Real mPrimaryStep, mShadowStep, mCutOff, mLightGain;
248  Vec3R mLightDir, mLightColor, mAbsorption, mScattering;
249 };//VolumeRender
250 
252 
255 class Film
256 {
257 public:
260  struct RGBA
261  {
262  typedef float ValueT;
263 
264  RGBA() : r(0), g(0), b(0), a(1) {}
265  explicit RGBA(ValueT intensity) : r(intensity), g(intensity), b(intensity), a(1) {}
266  RGBA(ValueT _r, ValueT _g, ValueT _b, ValueT _a = static_cast<ValueT>(1.0)):
267  r(_r), g(_g), b(_b), a(_a)
268  {}
269 
270  RGBA operator* (ValueT scale) const { return RGBA(r*scale, g*scale, b*scale);}
271  RGBA operator+ (const RGBA& rhs) const { return RGBA(r+rhs.r, g+rhs.g, b+rhs.b);}
272  RGBA operator* (const RGBA& rhs) const { return RGBA(r*rhs.r, g*rhs.g, b*rhs.b);}
273  RGBA& operator+=(const RGBA& rhs) { r+=rhs.r; g+=rhs.g; b+=rhs.b, a+=rhs.a; return *this;}
274 
275  void over(const RGBA& rhs)
276  {
277  const float s = rhs.a*(1.0f-a);
278  r = a*r+s*rhs.r;
279  g = a*g+s*rhs.g;
280  b = a*b+s*rhs.b;
281  a = a + s;
282  }
283 
284  ValueT r, g, b, a;
285  };
286 
287 
288  Film(size_t width, size_t height)
289  : mWidth(width), mHeight(height), mSize(width*height), mPixels(new RGBA[mSize])
290  {
291  }
292  Film(size_t width, size_t height, const RGBA& bg)
293  : mWidth(width), mHeight(height), mSize(width*height), mPixels(new RGBA[mSize])
294  {
295  this->fill(bg);
296  }
297 
298  const RGBA& pixel(size_t w, size_t h) const
299  {
300  assert(w < mWidth);
301  assert(h < mHeight);
302  return mPixels[w + h*mWidth];
303  }
304 
305  RGBA& pixel(size_t w, size_t h)
306  {
307  assert(w < mWidth);
308  assert(h < mHeight);
309  return mPixels[w + h*mWidth];
310  }
311 
312  void fill(const RGBA& rgb=RGBA(0)) { for (size_t i=0; i<mSize; ++i) mPixels[i] = rgb; }
313  void checkerboard(const RGBA& c1=RGBA(0.3f), const RGBA& c2=RGBA(0.6f), size_t size=32)
314  {
315  RGBA *p = mPixels.get();
316  for (size_t j = 0; j < mHeight; ++j) {
317  for (size_t i = 0; i < mWidth; ++i, ++p) {
318  *p = ((i & size) ^ (j & size)) ? c1 : c2;
319  }
320  }
321  }
322 
323  void savePPM(const std::string& fileName)
324  {
325  std::string name(fileName + ".ppm");
326  boost::scoped_array<unsigned char> buffer(new unsigned char[3*mSize]);
327  unsigned char *tmp = buffer.get(), *q = tmp;
328  RGBA* p = mPixels.get();
329  size_t n = mSize;
330  while (n--) {
331  *q++ = static_cast<unsigned char>(255.0f*(*p ).r);
332  *q++ = static_cast<unsigned char>(255.0f*(*p ).g);
333  *q++ = static_cast<unsigned char>(255.0f*(*p++).b);
334  }
335 
336  std::ofstream os(name.c_str(), std::ios_base::binary);
337  if (!os.is_open()) {
338  std::cerr << "Error opening PPM file \"" << name << "\"" << std::endl;
339  return;
340  }
341 
342  os << "P6\n" << mWidth << " " << mHeight << "\n255\n";
343  os.write((const char *)&(*tmp), 3*mSize*sizeof(unsigned char));
344  }
345 
346 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
347  void saveEXR(const std::string& fileName, size_t compression = 2, size_t threads = 8)
348  {
349  std::string name(fileName + ".exr");
350 
351  if (threads>0) Imf::setGlobalThreadCount(threads);
352  Imf::Header header(mWidth, mHeight);
353  if (compression==0) header.compression() = Imf::NO_COMPRESSION;
354  if (compression==1) header.compression() = Imf::RLE_COMPRESSION;
355  if (compression>=2) header.compression() = Imf::ZIP_COMPRESSION;
356  header.channels().insert("R", Imf::Channel(Imf::FLOAT));
357  header.channels().insert("G", Imf::Channel(Imf::FLOAT));
358  header.channels().insert("B", Imf::Channel(Imf::FLOAT));
359  header.channels().insert("A", Imf::Channel(Imf::FLOAT));
360 
361  Imf::FrameBuffer framebuffer;
362  framebuffer.insert("R", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].r),
363  sizeof (RGBA), sizeof (RGBA) * mWidth));
364  framebuffer.insert("G", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].g),
365  sizeof (RGBA), sizeof (RGBA) * mWidth));
366  framebuffer.insert("B", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].b),
367  sizeof (RGBA), sizeof (RGBA) * mWidth));
368  framebuffer.insert("A", Imf::Slice( Imf::FLOAT, (char *) &(mPixels[0].a),
369  sizeof (RGBA), sizeof (RGBA) * mWidth));
370 
371  Imf::OutputFile file(name.c_str(), header);
372  file.setFrameBuffer(framebuffer);
373  file.writePixels(mHeight);
374  }
375 #endif
376 
377  size_t width() const { return mWidth; }
378  size_t height() const { return mHeight; }
379  size_t numPixels() const { return mSize; }
380  const RGBA* pixels() const { return mPixels.get(); }
381 
382 private:
383  size_t mWidth, mHeight, mSize;
384  boost::scoped_array<RGBA> mPixels;
385 };// Film
386 
387 
389 
392 {
393 public:
394  BaseCamera(Film& film, const Vec3R& rotation, const Vec3R& translation,
395  double frameWidth, double nearPlane, double farPlane)
396  : mFilm(&film)
397  , mScaleWidth(frameWidth)
398  , mScaleHeight(frameWidth * double(film.height()) / double(film.width()))
399  {
400  assert(nearPlane > 0 && farPlane > nearPlane);
401  mScreenToWorld.accumPostRotation(math::X_AXIS, rotation[0] * M_PI / 180.0);
402  mScreenToWorld.accumPostRotation(math::Y_AXIS, rotation[1] * M_PI / 180.0);
403  mScreenToWorld.accumPostRotation(math::Z_AXIS, rotation[2] * M_PI / 180.0);
404  mScreenToWorld.accumPostTranslation(translation);
405  this->initRay(nearPlane, farPlane);
406  }
407 
408  virtual ~BaseCamera() {}
409 
410  Film::RGBA& pixel(size_t i, size_t j) { return mFilm->pixel(i, j); }
411 
412  size_t width() const { return mFilm->width(); }
413  size_t height() const { return mFilm->height(); }
414 
419  void lookAt(const Vec3R& xyz, const Vec3R& up = Vec3R(0.0, 1.0, 0.0))
420  {
421  const Vec3R orig = mScreenToWorld.applyMap(Vec3R(0.0));
422  const Vec3R dir = orig - xyz;
423  try {
424  Mat4d xform = math::aim<Mat4d>(dir, up);
425  xform.postTranslate(orig);
426  mScreenToWorld = math::AffineMap(xform);
427  this->initRay(mRay.t0(), mRay.t1());
428  } catch (...) {}
429  }
430 
431  Vec3R rasterToScreen(double i, double j, double z) const
432  {
433  return Vec3R( (2 * i / double(mFilm->width()) - 1) * mScaleWidth,
434  (1 - 2 * j / double(mFilm->height())) * mScaleHeight, z );
435  }
436 
440  virtual math::Ray<double> getRay(
441  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const = 0;
442 
443 protected:
444  void initRay(double t0, double t1)
445  {
446  mRay.setTimes(t0, t1);
447  mRay.setEye(mScreenToWorld.applyMap(Vec3R(0.0)));
448  mRay.setDir(mScreenToWorld.applyJacobian(Vec3R(0.0, 0.0, -1.0)));
449  }
450 
452  double mScaleWidth, mScaleHeight;
455 };// BaseCamera
456 
457 
459 {
460  public:
477  const Vec3R& rotation = Vec3R(0.0),
478  const Vec3R& translation = Vec3R(0.0),
479  double focalLength = 50.0,
480  double aperture = 41.2136,
481  double nearPlane = 1e-3,
482  double farPlane = std::numeric_limits<double>::max())
483  : BaseCamera(film, rotation, translation, 0.5*aperture/focalLength, nearPlane, farPlane)
484  {
485  }
486 
487  virtual ~PerspectiveCamera() {}
488 
493  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const
494  {
495  math::Ray<double> ray(mRay);
496  Vec3R dir = BaseCamera::rasterToScreen(Real(i) + iOffset, Real(j) + jOffset, -1.0);
497  dir = BaseCamera::mScreenToWorld.applyJacobian(dir);
498  dir.normalize();
499  ray.scaleTimes(1.0/dir.dot(ray.dir()));
500  ray.setDir(dir);
501  return ray;
502  }
503 
506  static double focalLengthToFieldOfView(double length, double aperture)
507  {
508  return 360.0 / M_PI * atan(aperture/(2.0*length));
509  }
512  static double fieldOfViewToFocalLength(double fov, double aperture)
513  {
514  return aperture/(2.0*(tan(fov * M_PI / 360.0)));
515  }
516 };// PerspectiveCamera
517 
518 
520 {
521 public:
535  const Vec3R& rotation = Vec3R(0.0),
536  const Vec3R& translation = Vec3R(0.0),
537  double frameWidth = 1.0,
538  double nearPlane = 1e-3,
539  double farPlane = std::numeric_limits<double>::max())
540  : BaseCamera(film, rotation, translation, 0.5*frameWidth, nearPlane, farPlane)
541  {
542  }
543  virtual ~OrthographicCamera() {}
544 
546  size_t i, size_t j, double iOffset = 0.5, double jOffset = 0.5) const
547  {
548  math::Ray<double> ray(mRay);
549  Vec3R eye = BaseCamera::rasterToScreen(Real(i) + iOffset, Real(j) + jOffset, 0.0);
550  ray.setEye(BaseCamera::mScreenToWorld.applyMap(eye));
551  return ray;
552  }
553 };// OrthographicCamera
554 
555 
557 
558 
561 {
562 public:
565  virtual ~BaseShader() {}
570  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R& nml, const Vec3R& dir) const = 0;
571  virtual BaseShader* copy() const = 0;
572 };
573 
574 
581 template <typename GridT = Film::RGBA,
582  typename SamplerType = tools::PointSampler>
583 class MatteShader: public BaseShader
584 {
585 public:
586  MatteShader(const GridT& grid) : mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
587  virtual ~MatteShader() {}
588  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const
589  {
590  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
591  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
592  return Film::RGBA(
593  static_cast<Film::RGBA::ValueT>(v[0]),
594  static_cast<Film::RGBA::ValueT>(v[1]),
595  static_cast<Film::RGBA::ValueT>(v[2]));
596  }
597  virtual BaseShader* copy() const { return new MatteShader<GridT, SamplerType>(*this); }
598 
599 private:
600  typename GridT::ConstAccessor mAcc;
601  const math::Transform* mXform;
602 };
603 // Template specialization using a constant color of the material.
604 template <typename SamplerType>
605 class MatteShader<Film::RGBA, SamplerType>: public BaseShader
606 {
607 public:
608  MatteShader(const Film::RGBA& c = Film::RGBA(1.0f)): mRGBA(c) {}
609  virtual ~MatteShader() {}
610  virtual Film::RGBA operator()(const Vec3R&, const Vec3R&, const Vec3R&) const
611  {
612  return mRGBA;
613  }
614  virtual BaseShader* copy() const { return new MatteShader<Film::RGBA, SamplerType>(*this); }
615 
616 private:
617  const Film::RGBA mRGBA;
618 };
619 
620 
628 template <typename GridT = Film::RGBA,
629  typename SamplerType = tools::PointSampler>
631 {
632 public:
633  NormalShader(const GridT& grid) : mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
634  virtual ~NormalShader() {}
635  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R&) const
636  {
637  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
638  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
639  return Film::RGBA(v[0]*(normal[0]+1.0f), v[1]*(normal[1]+1.0f), v[2]*(normal[2]+1.0f));
640  }
641  virtual BaseShader* copy() const { return new NormalShader<GridT, SamplerType>(*this); }
642 
643 private:
644  typename GridT::ConstAccessor mAcc;
645  const math::Transform* mXform;
646 };
647 // Template specialization using a constant color of the material.
648 template <typename SamplerType>
649 class NormalShader<Film::RGBA, SamplerType>: public BaseShader
650 {
651 public:
652  NormalShader(const Film::RGBA& c = Film::RGBA(1.0f)) : mRGBA(c*0.5f) {}
653  virtual ~NormalShader() {}
654  virtual Film::RGBA operator()(const Vec3R&, const Vec3R& normal, const Vec3R&) const
655  {
656  return mRGBA*Film::RGBA(normal[0]+1.0f, normal[1]+1.0f, normal[2]+1.0f);
657  }
658  virtual BaseShader* copy() const { return new NormalShader<Film::RGBA, SamplerType>(*this); }
659 
660 private:
661  const Film::RGBA mRGBA;
662 };
663 
664 
672 template <typename GridT = Film::RGBA,
673  typename SamplerType = tools::PointSampler>
675 {
676 public:
677  PositionShader(const math::BBox<Vec3R>& bbox, const GridT& grid)
678  : mMin(bbox.min())
679  , mInvDim(1.0/bbox.extents())
680  , mAcc(grid.getAccessor())
681  , mXform(&grid.transform())
682  {
683  }
684  virtual ~PositionShader() {}
685  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const
686  {
687  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
688  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
689  const Vec3R rgb = (xyz - mMin)*mInvDim;
690  return Film::RGBA(v[0],v[1],v[2]) * Film::RGBA(rgb[0], rgb[1], rgb[2]);
691  }
692  virtual BaseShader* copy() const { return new PositionShader<GridT, SamplerType>(*this); }
693 
694 private:
695  const Vec3R mMin, mInvDim;
696  typename GridT::ConstAccessor mAcc;
697  const math::Transform* mXform;
698 };
699 // Template specialization using a constant color of the material.
700 template <typename SamplerType>
701 class PositionShader<Film::RGBA, SamplerType>: public BaseShader
702 {
703 public:
704  PositionShader(const math::BBox<Vec3R>& bbox, const Film::RGBA& c = Film::RGBA(1.0f))
705  : mMin(bbox.min()), mInvDim(1.0/bbox.extents()), mRGBA(c) {}
706  virtual ~PositionShader() {}
707  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R&, const Vec3R&) const
708  {
709  const Vec3R rgb = (xyz - mMin)*mInvDim;
710  return mRGBA*Film::RGBA(rgb[0], rgb[1], rgb[2]);
711  }
712  virtual BaseShader* copy() const { return new PositionShader<Film::RGBA, SamplerType>(*this); }
713 
714 private:
715  const Vec3R mMin, mInvDim;
716  const Film::RGBA mRGBA;
717 };
718 
728 template <typename GridT = Film::RGBA,
729  typename SamplerType = tools::PointSampler>
731 {
732 public:
733  DiffuseShader(const GridT& grid): mAcc(grid.getAccessor()), mXform(&grid.transform()) {}
734  virtual ~DiffuseShader() {}
735  virtual Film::RGBA operator()(const Vec3R& xyz, const Vec3R& normal, const Vec3R& rayDir) const
736  {
737  typename GridT::ValueType v = zeroVal<typename GridT::ValueType>();
738  SamplerType::sample(mAcc, mXform->worldToIndex(xyz), v);
739  // We take the abs of the dot product corresponding to having
740  // light sources at +/- rayDir, i.e., two-sided shading.
741  return Film::RGBA(v[0],v[1],v[2]) * math::Abs(normal.dot(rayDir));
742  }
743  virtual BaseShader* copy() const { return new DiffuseShader<GridT, SamplerType>(*this); }
744 
745 private:
746  typename GridT::ConstAccessor mAcc;
747  const math::Transform* mXform;
748 };
749 // Template specialization using a constant color of the material.
750 template <typename SamplerType>
751 class DiffuseShader<Film::RGBA, SamplerType>: public BaseShader
752 {
753 public:
754  DiffuseShader(const Film::RGBA& d = Film::RGBA(1.0f)): mRGBA(d) {}
755  virtual ~DiffuseShader() {}
756  virtual Film::RGBA operator()(const Vec3R&, const Vec3R& normal, const Vec3R& rayDir) const
757  {
758  // We assume a single directional light source at the camera,
759  // so the cosine of the angle between the surface normal and the
760  // direction of the light source becomes the dot product of the
761  // surface normal and inverse direction of the ray. We also ignore
762  // negative dot products, corresponding to strict one-sided shading.
763  //return mRGBA * math::Max(0.0, normal.dot(-rayDir));
764 
765  // We take the abs of the dot product corresponding to having
766  // light sources at +/- rayDir, i.e., two-sided shading.
767  return mRGBA * math::Abs(normal.dot(rayDir));
768  }
769  virtual BaseShader* copy() const { return new DiffuseShader<Film::RGBA, SamplerType>(*this); }
770 
771 private:
772  const Film::RGBA mRGBA;
773 };
774 
776 
777 template<typename GridT>
778 inline void rayTrace(const GridT& grid,
779  const BaseShader& shader,
780  BaseCamera& camera,
781  size_t pixelSamples,
782  unsigned int seed,
783  bool threaded)
784 {
786  tracer(grid, shader, camera, pixelSamples, seed);
787  tracer.render(threaded);
788 }
789 
790 
791 template<typename GridT, typename IntersectorT>
792 inline void rayTrace(const GridT&,
793  const IntersectorT& inter,
794  const BaseShader& shader,
795  BaseCamera& camera,
796  size_t pixelSamples,
797  unsigned int seed,
798  bool threaded)
799 {
800  LevelSetRayTracer<GridT, IntersectorT> tracer(inter, shader, camera, pixelSamples, seed);
801  tracer.render(threaded);
802 }
803 
804 
806 
807 
808 template<typename GridT, typename IntersectorT>
809 inline LevelSetRayTracer<GridT, IntersectorT>::
810 LevelSetRayTracer(const GridT& grid,
811  const BaseShader& shader,
812  BaseCamera& camera,
813  size_t pixelSamples,
814  unsigned int seed)
815  : mIsMaster(true),
816  mRand(NULL),
817  mInter(grid),
818  mShader(shader.copy()),
819  mCamera(&camera)
820 {
821  this->setPixelSamples(pixelSamples, seed);
822 }
823 
824 template<typename GridT, typename IntersectorT>
826 LevelSetRayTracer(const IntersectorT& inter,
827  const BaseShader& shader,
828  BaseCamera& camera,
829  size_t pixelSamples,
830  unsigned int seed)
831  : mIsMaster(true),
832  mRand(NULL),
833  mInter(inter),
834  mShader(shader.copy()),
835  mCamera(&camera)
836 {
837  this->setPixelSamples(pixelSamples, seed);
838 }
839 
840 template<typename GridT, typename IntersectorT>
843  mIsMaster(false),
844  mRand(other.mRand),
845  mInter(other.mInter),
846  mShader(other.mShader->copy()),
847  mCamera(other.mCamera),
848  mSubPixels(other.mSubPixels)
849 {
850 }
851 
852 template<typename GridT, typename IntersectorT>
855 {
856  if (mIsMaster) delete [] mRand;
857 }
858 
859 template<typename GridT, typename IntersectorT>
861 setGrid(const GridT& grid)
862 {
863  assert(mIsMaster);
864  mInter = IntersectorT(grid);
865 }
866 
867 template<typename GridT, typename IntersectorT>
869 setIntersector(const IntersectorT& inter)
870 {
871  assert(mIsMaster);
872  mInter = inter;
873 }
874 
875 template<typename GridT, typename IntersectorT>
877 setShader(const BaseShader& shader)
878 {
879  assert(mIsMaster);
880  mShader.reset(shader.copy());
881 }
882 
883 template<typename GridT, typename IntersectorT>
886 {
887  assert(mIsMaster);
888  mCamera = &camera;
889 }
890 
891 template<typename GridT, typename IntersectorT>
893 setPixelSamples(size_t pixelSamples, unsigned int seed)
894 {
895  assert(mIsMaster);
896  if (pixelSamples == 0) {
897  OPENVDB_THROW(ValueError, "pixelSamples must be larger then zero!");
898  }
899  mSubPixels = pixelSamples - 1;
900  delete [] mRand;
901  if (mSubPixels > 0) {
902  mRand = new double[16];
903  math::Rand01<double> rand(seed);//offsets for anti-aliaing by jittered super-sampling
904  for (size_t i=0; i<16; ++i) mRand[i] = rand();
905  } else {
906  mRand = NULL;
907  }
908 }
909 
910 template<typename GridT, typename IntersectorT>
912 render(bool threaded) const
913 {
914  tbb::blocked_range<size_t> range(0, mCamera->height());
915  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
916 }
917 
918 template<typename GridT, typename IntersectorT>
920 operator()(const tbb::blocked_range<size_t>& range) const
921 {
922  const BaseShader& shader = *mShader;
923  Vec3Type xyz, nml;
924  const float frac = 1.0f / (1.0f + mSubPixels);
925  for (size_t j=range.begin(), n=0, je = range.end(); j<je; ++j) {
926  for (size_t i=0, ie = mCamera->width(); i<ie; ++i) {
927  Film::RGBA& bg = mCamera->pixel(i,j);
928  RayType ray = mCamera->getRay(i, j);//primary ray
929  Film::RGBA c = mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
930  for (size_t k=0; k<mSubPixels; ++k, n +=2 ) {
931  ray = mCamera->getRay(i, j, mRand[n & 15], mRand[(n+1) & 15]);
932  c += mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
933  }//loop over sub-pixels
934  bg = c*frac;
935  }//loop over image height
936  }//loop over image width
937 }
938 
940 
941 template<typename IntersectorT, typename SampleT>
943 VolumeRender(const IntersectorT& inter, BaseCamera& camera)
944  : mAccessor(inter.grid().getConstAccessor())
945  , mCamera(&camera)
946  , mPrimary(new IntersectorT(inter))
947  , mShadow(new IntersectorT(inter))
948  , mPrimaryStep(1.0)
949  , mShadowStep(3.0)
950  , mCutOff(0.005)
951  , mLightGain(0.2)
952  , mLightDir(Vec3R(0.3, 0.3, 0).unit())
953  , mLightColor(0.7, 0.7, 0.7)
954  , mAbsorption(0.1)
955  , mScattering(1.5)
956 {
957 }
958 
959 template<typename IntersectorT, typename SampleT>
962  : mAccessor(other.mAccessor)
963  , mCamera(other.mCamera)
964  , mPrimary(new IntersectorT(*(other.mPrimary)))
965  , mShadow(new IntersectorT(*(other.mShadow)))
966  , mPrimaryStep(other.mPrimaryStep)
967  , mShadowStep(other.mShadowStep)
968  , mCutOff(other.mCutOff)
969  , mLightGain(other.mLightGain)
970  , mLightDir(other.mLightDir)
971  , mLightColor(other.mLightColor)
972  , mAbsorption(other.mAbsorption)
973  , mScattering(other.mScattering)
974 {
975 }
976 
977 template<typename IntersectorT, typename SampleT>
979 print(std::ostream& os, int verboseLevel)
980 {
981  if (verboseLevel>0) {
982  os << "\nPrimary step: " << mPrimaryStep
983  << "\nShadow step: " << mShadowStep
984  << "\nCutoff: " << mCutOff
985  << "\nLightGain: " << mLightGain
986  << "\nLightDir: " << mLightDir
987  << "\nLightColor: " << mLightColor
988  << "\nAbsorption: " << mAbsorption
989  << "\nScattering: " << mScattering << std::endl;
990  }
991  mPrimary->print(os, verboseLevel);
992 }
993 
994 template<typename IntersectorT, typename SampleT>
996 setIntersector(const IntersectorT& inter)
997 {
998  mPrimary.reset(new IntersectorT(inter));
999  mShadow.reset( new IntersectorT(inter));
1000 }
1001 
1002 template<typename IntersectorT, typename SampleT>
1004 render(bool threaded) const
1005 {
1006  tbb::blocked_range<size_t> range(0, mCamera->height());
1007  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
1008 }
1009 
1010 template<typename IntersectorT, typename SampleT>
1012 operator()(const tbb::blocked_range<size_t>& range) const
1013 {
1014  SamplerType sampler(mAccessor, mShadow->grid().transform());//light-weight wrapper
1015 
1016  // Any variable prefixed with p (or s) means it's associate with a primay (or shadow) ray
1017  const Vec3R extinction = -mScattering-mAbsorption, One(1.0);
1018  const Vec3R albedo = mLightColor*mScattering/(mScattering+mAbsorption);//single scattering
1019  const Real sGain = mLightGain;//in-scattering along shadow ray
1020  const Real pStep = mPrimaryStep;//Integration step along primary ray in voxel units
1021  const Real sStep = mShadowStep;//Integration step along shadow ray in voxel units
1022  const Real cutoff = mCutOff;//Cutoff for density and transmittance
1023 
1024  // For the sake of completeness we show how to use two different
1025  // methods (hits/march) in VolumeRayIntersector that produce
1026  // segments along the ray that intersects active values. Comment out
1027  // the line below to use VolumeRayIntersector::march instead of
1028  // VolumeRayIntersector::hits.
1029 #define USE_HITS
1030 #ifdef USE_HITS
1031  std::vector<typename RayType::TimeSpan> pTS, sTS;
1032  //std::deque<typename RayType::TimeSpan> pTS, sTS;
1033 #endif
1034 
1035  RayType sRay(Vec3R(0), mLightDir);//Shadow ray
1036  for (size_t j=range.begin(), je = range.end(); j<je; ++j) {
1037  for (size_t i=0, ie = mCamera->width(); i<ie; ++i) {
1038  Film::RGBA& bg = mCamera->pixel(i, j);
1039  bg.a = bg.r = bg.g = bg.b = 0;
1040  RayType pRay = mCamera->getRay(i, j);// Primary ray
1041  if( !mPrimary->setWorldRay(pRay)) continue;
1042  Vec3R pTrans(1.0), pLumi(0.0);
1043 #ifndef USE_HITS
1044  Real pT0, pT1;
1045  while (mPrimary->march(pT0, pT1)) {
1046  for (Real pT = pStep*ceil(pT0/pStep); pT <= pT1; pT += pStep) {
1047 #else
1048  mPrimary->hits(pTS);
1049  for (size_t k=0; k<pTS.size(); ++k) {
1050  Real pT = pStep*ceil(pTS[k].t0/pStep), pT1=pTS[k].t1;
1051  for (; pT <= pT1; pT += pStep) {
1052 #endif
1053  Vec3R pPos = mPrimary->getWorldPos(pT);
1054  const Real density = sampler.wsSample(pPos);
1055  if (density < cutoff) continue;
1056  const Vec3R dT = math::Exp(extinction * density * pStep);
1057  Vec3R sTrans(1.0);
1058  sRay.setEye(pPos);
1059  if( !mShadow->setWorldRay(sRay)) continue;
1060 #ifndef USE_HITS
1061  Real sT0, sT1;
1062  while (mShadow->march(sT0, sT1)) {
1063  for (Real sT = sStep*ceil(sT0/sStep); sT <= sT1; sT+= sStep) {
1064 #else
1065  mShadow->hits(sTS);
1066  for (size_t l=0; l<sTS.size(); ++l) {
1067  Real sT = sStep*ceil(sTS[l].t0/sStep), sT1=sTS[l].t1;
1068  for (; sT <= sT1; sT+= sStep) {
1069 #endif
1070  const Real d = sampler.wsSample(mShadow->getWorldPos(sT));
1071  if (d < cutoff) continue;
1072  sTrans *= math::Exp(extinction * d * sStep/(1.0+sT*sGain));
1073  if (sTrans.lengthSqr()<cutoff) goto Luminance;//Terminate sRay
1074  }//Integration over shadow segment
1075  }// Shadow ray march
1076  Luminance:
1077  pLumi += albedo * sTrans * pTrans * (One-dT);
1078  pTrans *= dT;
1079  if (pTrans.lengthSqr()<cutoff) goto Pixel; // Terminate Ray
1080  }//Integration over primary segment
1081  }// Primary ray march
1082  Pixel:
1083  bg.r = static_cast<Film::RGBA::ValueT>(pLumi[0]);
1084  bg.g = static_cast<Film::RGBA::ValueT>(pLumi[1]);
1085  bg.b = static_cast<Film::RGBA::ValueT>(pLumi[2]);
1086  bg.a = static_cast<Film::RGBA::ValueT>(1.0f - pTrans.sum()/3.0f);
1087  }//Horizontal pixel scan
1088  }//Vertical pixel scan
1089 }
1090 
1091 } // namespace tools
1092 } // namespace OPENVDB_VERSION_NAME
1093 } // namespace openvdb
1094 
1095 #endif // OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
1096 
1097 // Copyright (c) 2012-2014 DreamWorks Animation LLC
1098 // All rights reserved. This software is distributed under the
1099 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
virtual BaseShader * copy() const
Definition: RayTracer.h:614
RGBA(ValueT _r, ValueT _g, ValueT _b, ValueT _a=static_cast< ValueT >(1.0))
Definition: RayTracer.h:266
virtual BaseShader * copy() const
Definition: RayTracer.h:597
IntersectorT::RayType RayType
Definition: RayTracer.h:184
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:284
A simple class that allows for concurrent writes to pixels in an image, background initialization of ...
Definition: RayTracer.h:255
double mScaleWidth
Definition: RayTracer.h:452
virtual Film::RGBA operator()(const Vec3R &, const Vec3R &normal, const Vec3R &) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:654
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:726
void operator()(const tbb::blocked_range< size_t > &range) const
Public method required by tbb::parallel_for.
Definition: RayTracer.h:920
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:221
MatteShader(const GridT &grid)
Definition: RayTracer.h:586
virtual ~BaseShader()
Definition: RayTracer.h:565
GridType::ValueType ValueType
Definition: RayTracer.h:185
virtual math::Ray< double > getRay(size_t i, size_t j, double iOffset=0.5, double jOffset=0.5) const
Return a Ray in world space given the pixel indices and optional offsets in the range [0...
Definition: RayTracer.h:492
RGBA & pixel(size_t w, size_t h)
Definition: RayTracer.h:305
virtual BaseShader * copy() const
Definition: RayTracer.h:769
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:324
GridType::ConstAccessor AccessorType
Definition: RayTracer.h:186
BaseCamera(Film &film, const Vec3R &rotation, const Vec3R &translation, double frameWidth, double nearPlane, double farPlane)
Definition: RayTracer.h:394
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:153
void setCamera(BaseCamera &camera)
Set the camera derived from the abstract BaseCamera class.
Definition: RayTracer.h:200
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:134
tools::GridSampler< AccessorType, SamplerT > SamplerType
Definition: RayTracer.h:187
void setIntersector(const IntersectorT &inter)
Set the intersector that performs the actual intersection of the rays against the volume...
Definition: RayTracer.h:996
virtual ~MatteShader()
Definition: RayTracer.h:587
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
size_t width() const
Definition: RayTracer.h:377
void setShader(const BaseShader &shader)
Set the shader derived from the abstract BaseShader class.
Definition: RayTracer.h:877
VolumeRender(const IntersectorT &inter, BaseCamera &camera)
Constructor taking an intersector and a base camera.
Definition: RayTracer.h:943
Film(size_t width, size_t height, const RGBA &bg)
Definition: RayTracer.h:292
Axis-aligned bounding box.
Definition: BBox.h:47
virtual Film::RGBA operator()(const Vec3R &, const Vec3R &, const Vec3R &) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:610
void setScattering(Real x, Real y, Real z)
Set Scattering coefficients.
Definition: RayTracer.h:220
DiffuseShader(const GridT &grid)
Definition: RayTracer.h:733
virtual ~PerspectiveCamera()
Definition: RayTracer.h:487
Floating-point RGBA components in the range [0, 1].
Definition: RayTracer.h:260
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:608
RGBA(ValueT intensity)
Definition: RayTracer.h:265
Film(size_t width, size_t height)
Definition: RayTracer.h:288
virtual BaseShader * copy() const
Definition: RayTracer.h:658
void over(const RGBA &rhs)
Definition: RayTracer.h:275
double Real
Definition: Types.h:65
virtual ~OrthographicCamera()
Definition: RayTracer.h:543
virtual math::Ray< double > getRay(size_t i, size_t j, double iOffset=0.5, double jOffset=0.5) const
Return a Ray in world space given the pixel indices and optional offsets in the range [0...
Definition: RayTracer.h:545
virtual Film::RGBA operator()(const Vec3R &, const Vec3R &normal, const Vec3R &rayDir) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:756
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 then one implies a...
Definition: RayTracer.h:893
void setEye(const Vec3Type &eye)
Definition: Ray.h:88
RGBA()
Definition: RayTracer.h:264
void lookAt(const Vec3R &xyz, const Vec3R &up=Vec3R(0.0, 1.0, 0.0))
Definition: RayTracer.h:419
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:208
virtual BaseShader * copy() const
Definition: RayTracer.h:743
Definition: Interpolation.h:90
size_t height() const
Definition: RayTracer.h:413
virtual ~DiffuseShader()
Definition: RayTracer.h:734
Vec3R rasterToScreen(double i, double j, double z) const
Definition: RayTracer.h:431
A (very) simple multithreaded ray tracer specifically for narrow-band level sets. ...
Definition: RayTracer.h:102
Vec3< T > unit(T eps=0) const
return normalized this, throws if null vector
Definition: Vec3.h:360
#define OPENVDB_VERSION_NAME
Definition: version.h:43
void checkerboard(const RGBA &c1=RGBA(0.3f), const RGBA &c2=RGBA(0.6f), size_t size=32)
Definition: RayTracer.h:313
math::Ray< Real > RayT
Definition: RayTracer.h:563
void savePPM(const std::string &fileName)
Definition: RayTracer.h:323
virtual BaseShader * copy() const
Definition: RayTracer.h:692
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:810
Abstract base class for the shaders.
Definition: RayTracer.h:560
Simple diffuse Lambertian surface shader.
Definition: RayTracer.h:730
NormalShader(const GridT &grid)
Definition: RayTracer.h:633
math::Vec3< Real > Vec3R
Definition: Types.h:77
IntersectorT::GridType GridType
Definition: RayTracer.h:183
virtual Film::RGBA operator()(const Vec3R &xyz, const Vec3R &normal, const Vec3R &rayDir) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:735
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:203
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:348
void setCutOff(Real cutOff)
Set the cut-off value for density and transmittance.
Definition: RayTracer.h:230
Definition: Exceptions.h:39
void setCamera(BaseCamera &camera)
Set the camera derived from the abstract BaseCamera class.
Definition: RayTracer.h:885
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:627
ValueT r
Definition: RayTracer.h:284
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
MatteShader(const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:608
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:534
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:869
void setShadowStep(Real shadowStep)
Set the integration step-size in voxel units for the primay ray.
Definition: RayTracer.h:217
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:792
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:506
ValueT b
Definition: RayTracer.h:284
math::AffineMap mScreenToWorld
Definition: RayTracer.h:454
void setDir(const Vec3Type &dir)
Definition: Ray.h:90
float ValueT
Definition: RayTracer.h:262
NormalShader(const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:652
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:512
void render(bool threaded=true) const
Perform the actual (potentially multithreaded) ray-tracing.
Definition: RayTracer.h:912
virtual Film::RGBA operator()(const Vec3R &xyz, const Vec3R &, const Vec3R &) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:588
Film::RGBA & pixel(size_t i, size_t j)
Definition: RayTracer.h:410
void fill(const RGBA &rgb=RGBA(0))
Definition: RayTracer.h:312
Definition: Math.h:823
void setGrid(const GridT &grid)
Set the level set grid to be ray-traced.
Definition: RayTracer.h:861
const RGBA & pixel(size_t w, size_t h) const
Definition: RayTracer.h:298
Abstract base class for the perspective and orthographic cameras.
Definition: RayTracer.h:391
Definition: Exceptions.h:88
void setPrimaryStep(Real primaryStep)
Set the integration step-size in voxel units for the primay ray.
Definition: RayTracer.h:214
~LevelSetRayTracer()
Destructor.
Definition: RayTracer.h:854
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:476
DiffuseShader(const Film::RGBA &d=Film::RGBA(1.0f))
Definition: RayTracer.h:754
size_t width() const
Definition: RayTracer.h:412
void initRay(double t0, double t1)
Definition: RayTracer.h:444
void setLightGain(Real gain)
Set parameter that imitates multi-scattering. A value of zero implies no multi-scattering.
Definition: RayTracer.h:227
virtual ~BaseCamera()
Definition: RayTracer.h:408
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:594
size_t height() const
Definition: RayTracer.h:378
ValueT g
Definition: RayTracer.h:284
virtual Film::RGBA operator()(const Vec3R &xyz, const Vec3R &normal, const Vec3R &) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:635
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
RGBA & operator+=(const RGBA &rhs)
Definition: RayTracer.h:273
Color shader that treats position (x, y, z) as an RGB color in a cube defined from an axis-aligned bo...
Definition: RayTracer.h:674
GridT GridType
Definition: RayTracer.h:105
void render(bool threaded=true) const
Perform the actual (potentially multithreaded) volume rendering.
Definition: RayTracer.h:1004
void operator()(const tbb::blocked_range< size_t > &range) const
Public method required by tbb::parallel_for.
Definition: RayTracer.h:1012
Definition: Math.h:824
Color shader that treats the surface normal (x, y, z) as an RGB color.
Definition: RayTracer.h:630
IntersectorT::RayType RayType
Definition: RayTracer.h:107
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Shader that produces a simple matte.
Definition: RayTracer.h:583
void setAbsorption(Real x, Real y, Real z)
Set absorption coefficients.
Definition: RayTracer.h:223
PositionShader(const math::BBox< Vec3R > &bbox, const Film::RGBA &c=Film::RGBA(1.0f))
Definition: RayTracer.h:704
PositionShader(const math::BBox< Vec3R > &bbox, const GridT &grid)
Definition: RayTracer.h:677
void print(std::ostream &os=std::cout, int verboseLevel=1)
Print parameters, statistics, memory usage and other information.
Definition: RayTracer.h:979
ValueT a
Definition: RayTracer.h:284
Type Exp(const Type &x)
Return .
Definition: Math.h:660
virtual BaseShader * copy() const
Definition: RayTracer.h:712
IntersectorT::Vec3Type Vec3Type
Definition: RayTracer.h:106
BaseShader()
Definition: RayTracer.h:564
virtual ~PositionShader()
Definition: RayTracer.h:684
virtual BaseShader * copy() const
Definition: RayTracer.h:641
T lengthSqr() const
Definition: Vec3.h:223
virtual Film::RGBA operator()(const Vec3R &xyz, const Vec3R &, const Vec3R &) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:707
Definition: Math.h:825
void setLightColor(Real r, Real g, Real b)
Set the color of the direcitonal light source.
Definition: RayTracer.h:211
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:382
A (very) simple multithreaded volume render specifically for scalar density.
Definition: RayTracer.h:179
math::Ray< double > mRay
Definition: RayTracer.h:453
virtual ~NormalShader()
Definition: RayTracer.h:634
virtual Film::RGBA operator()(const Vec3R &xyz, const Vec3R &, const Vec3R &) const
Defines the interface of the virtual function that returns a RGB color.
Definition: RayTracer.h:685
const RGBA * pixels() const
Definition: RayTracer.h:380
size_t numPixels() const
Definition: RayTracer.h:379
virtual BaseShader * copy() const =0
Film * mFilm
Definition: RayTracer.h:451