Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r445 - branches/itanium2/Model/Materials


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r445 - branches/itanium2/Model/Materials
  • Date: Thu, 28 Jul 2005 01:02:21 -0600 (MDT)

Author: boulos
Date: Thu Jul 28 01:02:20 2005
New Revision: 445

Modified:
   branches/itanium2/Model/Materials/Dielectric.cc
   branches/itanium2/Model/Materials/Dielectric.h
Log:
A ray-packeted version of Dielectric.


Modified: branches/itanium2/Model/Materials/Dielectric.cc
==============================================================================
--- branches/itanium2/Model/Materials/Dielectric.cc     (original)
+++ branches/itanium2/Model/Materials/Dielectric.cc     Thu Jul 28 01:02:20 
2005
@@ -52,13 +52,10 @@
 }
 
 
-Dielectric::Dielectric(const Color& diffuse, const Color& specular,  const 
Color &minusC_,
-                      int specpow, double n, double nt)
-  : diffuse(diffuse), specular(specular), specpow(specpow),
-    n(n), nt(nt), minusC( minusC_ )
+Dielectric::Dielectric(const Texture<double>* n, const Texture<double>* nt, 
const Texture<Color>* sigma_a)
+    : n(n), nt(nt), sigma_a(sigma_a)
 {
-    r0 = (n - nt) / (n + nt);
-    r0 *= r0;
+
 }
 
 Dielectric::~Dielectric()
@@ -67,15 +64,6 @@
 
 void Dielectric::shade(const RenderContext& context, RayPacket& rays) const
 {
-  rays.normalizeDirections();
-  rays.computeNormals(context);
-  if (!(rays.getFlags()  & rays.HaveUnitNormals)) {
-       // I would like to replace this with a call to
-       // rays.normalizeNormals() but need to add it.
-       fprintf(stderr, "Dielectric assumes unit normals\n");
-       exit(-1);
-  }
-  
   if(rays.getDepth() >= context.scene->getRenderParameters().maxDepth)
   {
     for(int i=0;i<rays.getSize();i++)
@@ -83,86 +71,155 @@
   }
   else
   {
-    rays.computeHitPositions();
-    for(int i=0;i<rays.getSize();i++)
-    {  
-         RayPacket::Element& e = rays.get(i);
-         double cosine = -Dot(e.normal, e.ray.direction());
-         Vector refl_dir, refr_dir;
-         bool from_outside = (cosine > 0);
-         bool total_internal_reflection;
-         refr_dir = e.ray.direction();
-         refl_dir = e.ray.direction() + 2 * cosine * e.normal;
-         if (from_outside) {
-              total_internal_reflection = !Refract(e.normal, n, nt, 
refr_dir);
-         }
-         else
-         {
-              total_internal_reflection = !Refract(-e.normal, nt, n, 
refr_dir);
+      rays.computeHitPositions();
+      rays.normalizeDirections();
+      rays.computeNormals(context);
+      if (!(rays.getFlags()  & rays.HaveUnitNormals))
+      {
+          // I would like to replace this with a call to
+          // rays.normalizeNormals() but need to add it.
+          fprintf(stderr, "Dielectric assumes unit normals\n");
+          exit(-1);
+      }
+
+      double n_values[RayPacket::MaxSize];
+      double nt_values[RayPacket::MaxSize];
+      Color sigma_a_values[RayPacket::MaxSize];
+
+      n->mapValues(context, rays, n_values);
+      nt->mapValues(context, rays, nt_values);
+      sigma_a->mapValues(context, rays, sigma_a_values);
+
+      bool internally_reflected[RayPacket::MaxSize];
+      Vector refl_dirs[RayPacket::MaxSize];
+      Vector refr_dirs[RayPacket::MaxSize];
+      float fresnel_coeffs[RayPacket::MaxSize]; // might be better to compute
+      int num_internal = 0;
+      int num_branch   = 0;
+
+      for(int i=0;i<rays.getSize();i++)
+      {
+          RayPacket::Element& e = rays.get(i);
+          double cosine = -Dot(e.normal, e.ray.direction());
+          Vector refl_dir, refr_dir;
+          bool from_outside = (cosine > 0);
+          bool total_internal_reflection;
+          refr_dir = e.ray.direction();
+          refl_dir = e.ray.direction() + 2 * cosine * e.normal;
+
+          if (from_outside)
+          {
+              // refract changes the refr_dir
+              total_internal_reflection = !Refract(e.normal,
+                                                   n_values[i],
+                                                   nt_values[i],
+                                                   refr_dir);
+          }
+          else
+          {
+              total_internal_reflection = !Refract(-e.normal,
+                                                   nt_values[i],
+                                                   n_values[i],
+                                                   refr_dir);
               cosine = -cosine;
-         }
+          }
 
-         if (total_internal_reflection) {
-              // Create a size one ray packet
-             int flags = 0;
-             int size = 1;
-             RayPacketData raydata;
-             RayPacket refl_rays(raydata, size, rays.getDepth()+1, flags);
-
-             RayPacket::Element& r = refl_rays.get(0);
-             r.ray.set(e.hitPosition,  refl_dir);
-             refl_rays.useLocalColors();
-             context.renderer->traceRays(context, refl_rays);
-                                                
-                                                // Apply beer's law 
attenuation.
-                                                // (*r.color) = 
r.color->attenuate( minusC * r.hitInfo.minT() );
-                                                
-             rays.setResult(i, *r.color);
-         }
-         else  // reflection and refraction
-         {
+          if (total_internal_reflection)
+          {
+              internally_reflected[i] = true;
+              num_internal++;
+              refl_dirs[i] = refl_dir;
+          }
+          else  // reflection and refraction
+          {
               float cosine2;
               if (from_outside) {
-                    cosine2 = -Dot(e.normal, refr_dir);
+                  cosine2 = -Dot(e.normal, refr_dir);
               }
               else {
-                    cosine2 = Dot(e.normal, refr_dir);
+                  cosine2 = Dot(e.normal, refr_dir);
               }
 
               if (cosine2 < cosine) cosine = cosine2; // for Schlick
               float k = 1 - cosine;
               k*=k*k*k*k;
-              float R = r0*(1-k) + k;
-
-              int flags = 0;
-              int size = 1;
-
 
-                                                       // Reflected rays.
-              RayPacketData raydata;
-              RayPacket refl_rays(raydata, size, rays.getDepth()+1, flags);
-              RayPacket::Element& r = refl_rays.get(0);
-              r.ray.set(e.hitPosition,  refl_dir);
-              refl_rays.useLocalColors();
-              context.renderer->traceRays(context, refl_rays);
-
-                                                       // Refracted rays.
-              RayPacketData raydata2;
-              RayPacket refr_rays(raydata2, size, rays.getDepth()+1, flags);
-              RayPacket::Element& r2 = refr_rays.get(0);
-              r2.ray.set(e.hitPosition,  refr_dir);
-              refr_rays.normalizeDirections();
-              refr_rays.useLocalColors();
-              context.renderer->traceRays(context, refr_rays);
+              double r0 = (n_values[i] - nt_values[i]) / (n_values[i] + 
nt_values[i]);
+              r0 *= r0;
+              float R = r0*(1-k) + k;
 
-                                                       // Apply beer's law 
attenuation.
-                                                       // (*r2.color) *= 
minusC.attenuate( r2.hitInfo.minT() );
+              internally_reflected[i] = false;
+              num_branch++;
+              refl_dirs[i] = refl_dir;
+              refr_dirs[i] = refr_dir;
+              fresnel_coeffs[i] = R;
+         }
+      }
 
-               rays.setResult(i, (Color::white()*R)*(*r.color) +
-                   (Color::white()*(1-R))*(*r2.color) ); 
+      // okay we've got everything ready now
 
-         }
-    }
-    
+      RayPacketData total_internal_data;
+      RayPacketData reflected_data;
+      RayPacketData refracted_data;
+
+      RayPacket internal_rays(total_internal_data, num_internal, 
rays.getDepth()+1, RayPacket::NormalizedDirections);
+      RayPacket reflected_rays(reflected_data, num_branch, 
rays.getDepth()+1, RayPacket::NormalizedDirections);
+      RayPacket refracted_rays(refracted_data, num_branch, 
rays.getDepth()+1, RayPacket::NormalizedDirections);
+
+      internal_rays.useLocalColors();
+      reflected_rays.useLocalColors();
+      refracted_rays.useLocalColors();
+
+      // for accessing ray packet elements between the 3 sets (or 2 pairs 
really)
+      int internal_counter = 0;
+      int branch_counter   = 0;
+      // fill in the raypackets
+      for (int i = 0; i < rays.getSize(); i++)
+      {
+          RayPacket::Element& e = rays.get(i);
+
+          if (internally_reflected[i])
+          {
+              RayPacket::Element& r = internal_rays.get(internal_counter);
+              r.ray.set(e.hitPosition, refl_dirs[i]);
+              internal_counter++;
+          }
+          else
+          {
+              RayPacket::Element& refl = reflected_rays.get(branch_counter);
+              refl.ray.set(e.hitPosition, refl_dirs[i]);
+              RayPacket::Element& refr = refracted_rays.get(branch_counter);
+              refr.ray.set(e.hitPosition, refr_dirs[i]);
+              branch_counter++;
+          }
+      }
+
+      // fire them off
+      context.renderer->traceRays(context, reflected_rays);
+      context.renderer->traceRays(context, refracted_rays);
+      context.renderer->traceRays(context, internal_rays);
+
+      internal_counter = 0;
+      branch_counter   = 0;
+      // compute their results
+      for (int i = 0; i < rays.getSize(); i++)
+      {
+          if (internally_reflected[i])
+          {
+              RayPacket::Element& r = internal_rays.get(internal_counter);
+              // TODO: Apply beer's law attenuation to total internal 
reflection ray.
+              rays.setResult(i, *r.color);
+              internal_counter++;
+          }
+          else
+          {
+              RayPacket::Element& refl = reflected_rays.get(branch_counter);
+              RayPacket::Element& refr = refracted_rays.get(branch_counter);
+              // TODO: Apply beer's law attenuation to refracted ray
+              rays.setResult(i, 
(Color::white()*fresnel_coeffs[i])*(*refl.color) +
+                             
(Color::white()*(1.-fresnel_coeffs[i]))*(*refr.color) );
+              branch_counter++;
+          }
+      }
   }
 }

Modified: branches/itanium2/Model/Materials/Dielectric.h
==============================================================================
--- branches/itanium2/Model/Materials/Dielectric.h      (original)
+++ branches/itanium2/Model/Materials/Dielectric.h      Thu Jul 28 01:02:20 
2005
@@ -4,25 +4,23 @@
 
 #include <Model/Materials/LitMaterial.h>
 #include <Core/Color/Color.h>
+#include <Interface/Texture.h>
 
-namespace Manta{
+namespace Manta
+{
   class LightSet;
 
-  class Dielectric : public LitMaterial {
+  class Dielectric : public LitMaterial
+  {
   public:
-               // minusC = log( beersA ) but there isn't an easy way to take 
the log of a color.
-    Dielectric(const Color& reflected, const Color& specular, const Color 
&minusC, int specpow,
-              double n, double nt);
-                                
-    virtual ~Dielectric();
+      Dielectric(const Texture<double>* n, const Texture<double>* nt, const 
Texture<Color>* sigma_a);
+      ~Dielectric();
 
-    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+      void shade(const RenderContext& context, RayPacket& rays) const;
   private:
-    Color diffuse;
-    Color specular;
-               Color minusC; // Beer's law.
-    int specpow;
-    double n, nt, r0;
+      const Texture<double>* n;
+      const Texture<double>* nt;
+      const Texture<Color>* sigma_a;
   };
 }
 




  • [MANTA] r445 - branches/itanium2/Model/Materials, boulos, 07/28/2005

Archive powered by MHonArc 2.6.16.

Top of page