Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1349 - in trunk: Model/Materials Model/Primitives SwigInterface


Chronological Thread 
  • From: bigler@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1349 - in trunk: Model/Materials Model/Primitives SwigInterface
  • Date: Wed, 18 Apr 2007 15:23:57 -0600 (MDT)

Author: bigler
Date: Wed Apr 18 15:23:56 2007
New Revision: 1349

Modified:
   trunk/Model/Materials/Dielectric.cc
   trunk/Model/Materials/Dielectric.h
   trunk/Model/Primitives/Cylinder.cc
   trunk/SwigInterface/runmanta.py
Log:

Model/Materials/Dielectric.cc
Model/Materials/Dielectric.h

  Added an interface to switch between using Schlick's approximation
  to the Fresnel reflectance or not.

  Made some variable names more consistent with Steve's notes (and
  other references).

Model/Primitives/Cylinder.cc

  Fix normal computation.  It was transforming the hit location as a
  vector instead of a point.

SwigInterface/runmanta.py

  Some slight changes for my crazy debug scene.


Modified: trunk/Model/Materials/Dielectric.cc
==============================================================================
--- trunk/Model/Materials/Dielectric.cc (original)
+++ trunk/Model/Materials/Dielectric.cc Wed Apr 18 15:23:56 2007
@@ -48,22 +48,63 @@
 Dielectric::Dielectric(const Texture<Real>* n, const Texture<Real>* nt,
                        const Texture<Color>* sigma_a,
                        Real cutoff)
-  : n(n), nt(nt), sigma_a(sigma_a)
+  : n(n), nt(nt), sigma_a(sigma_a), doSchlick(false)
 {
-
 }
 
 Dielectric::~Dielectric()
 {
 }
 
+// Given eta         = eta_t/eta_i (or eta2/eta1)
+//       eta_inverse = eta_i/eta_t (or eta1/eta2)
+// r0 = (1 - eta_inverse) / (1 + eta_inverse);
+// r0 = (eta - 1)         / (1 + eta);
+// r0 = (eta_t - eta_i)   / (eta_t - eta_i);
+//
+// Note that because r0 is squared, eta_t and eta_i can be swapped and
+// get the same result.
+//
+// (eta_t - eta_i)^2 = eta_t^2 - 2*eta_t*eta_i + eta_i^2
+// (eta_i - eta_t)^2 = eta_i^2 - 2*eta_i*eta_t + eta_t^2
+//
+// We can conclude that the reflection coefficient is not dependent on
+// wether the ray is entering or leaving the dielectric, but rather
+// the relative angles.
+
+static inline Real SchlickReflection(Real costheta, Real costheta2,
+                                     Real eta_inverse)
+{
+  Real k = 1 - SCIRun::Min(costheta, costheta2);
+  Real k5 = (k*k)*(k*k)*k;
+  Real r0 = (1 - eta_inverse) / (1 + eta_inverse);
+  r0 *= r0;
+  return r0*(1-k5) + k5;
+}
+
+// Similarly to the Schlick approximation to the reflection, eta1 and
+// eta2 can be swapped and get the same result.
+static inline Real FresnelReflection(Real costheta, Real costheta2,
+                                     Real eta1, Real eta2)
+{
+  Real r_parallel = (((eta2 * costheta) - (eta1 * costheta2)) /
+                     ((eta2 * costheta) + (eta1 * costheta2)));
+  Real r_perp     = (((eta1 * costheta) - (eta2 * costheta2)) /
+                     ((eta1 * costheta) + (eta2 * costheta2)));
+  return (Real)(.5)*(r_parallel*r_parallel + r_perp*r_perp);
+}
+
 void Dielectric::shade(const RenderContext& context, RayPacket& rays) const
 {
+  int debugFlag = rays.getAllFlags() & RayPacket::DebugPacket;
   if(rays.getDepth() >= context.scene->getRenderParameters().maxDepth) {
     for(int i=rays.begin();i<rays.end();i++)
       rays.setColor(i, Color::black());
     return;
   }
+  if (debugFlag) {
+    cerr << "Dielectric::shade: depth = "<< rays.getDepth() << "\n";
+  }
 
   rays.computeHitPositions();
   rays.normalizeDirections();
@@ -81,14 +122,9 @@
   RayPacketData refracted_data;
 
   RayPacket reflected_rays(reflected_data, RayPacket::UnknownShape,
-                           0, 0, rays.getDepth()+1, 
RayPacket::NormalizedDirections);
+                           0, 0, rays.getDepth()+1, 
RayPacket::NormalizedDirections | debugFlag);
   RayPacket refracted_rays(refracted_data, RayPacket::UnknownShape,
-                           0, 0, rays.getDepth()+1, 
RayPacket::NormalizedDirections);
-
-  if (rays.getFlag(RayPacket::DebugPacket)) {
-    reflected_rays.setFlag(RayPacket::DebugPacket);
-    refracted_rays.setFlag(RayPacket::DebugPacket);
-  }
+                           0, 0, rays.getDepth()+1, 
RayPacket::NormalizedDirections | debugFlag);
 
   Color results[RayPacket::MaxSize];
   Color refl_attenuation[RayPacket::MaxSize];
@@ -107,65 +143,91 @@
 
     Vector rayD = rays.getDirection(i);
     Vector normal = rays.getNormal(i);
-    Real n_dot_v = Dot(normal, rayD);
-    Real eta_tmp_inv;
-    bool was_incoming = ( n_dot_v < 0 );
+    Real costheta = -Dot(normal, rayD);
+    if (debugFlag) {
+      cerr << "ray      = "<<rayD<<"\n";
+      cerr << "normal   = "<<normal<<"\n";
+      cerr << "costheta = "<<costheta<<"\n";
+    }
+    Real eta_inverse;
     Color beers_color;
-    if ( was_incoming ) {
-      eta_tmp_inv = nt_values.data[i]/n_values.data[i];
-      n_dot_v = -n_dot_v;
-      beers_color = Color::white();
-    } else {
+    bool exiting;
+    if ( costheta < 0 ) {
+      // Exiting surface
       normal = -normal;
-      eta_tmp_inv = n_values.data[i]/nt_values.data[i];
+      costheta = -costheta;
+      eta_inverse = n_values.data[i]/nt_values.data[i];
+      exiting = true;
       beers_color = sigma_a_values.get(i).Pow(rays.getMinT(i));
+    } else {
+      eta_inverse = nt_values.data[i]/n_values.data[i];
+      exiting = false;
+      beers_color = Color::white();
     }
 
-    Real cosine_sq = 1 + (n_dot_v*n_dot_v - 1) * (eta_tmp_inv*eta_tmp_inv);
+    Vector refl_dir = rayD + 2*costheta*normal;
+    Real costheta2squared = 
1+(costheta*costheta-1)*(eta_inverse*eta_inverse);
     Color in_importance = rays.getImportance(i);
     Vector hitpos = rays.getHitPosition(i);
-    if ( cosine_sq <= 0 ) {
+    if ( costheta2squared < 0 ) {
       // total internal reflection - no attenuation
+#if 1
       Color refl_importance = in_importance * beers_color;
       if(refl_importance.luminance() > cutoff){
         reflected_rays.setImportance(num_refl, refl_importance);
-        Vector refl_dir = rayD + 2*n_dot_v*normal;
         reflected_rays.setRay(num_refl, hitpos, refl_dir);
         refl_source[num_refl] = i;
         refl_attenuation[num_refl] = beers_color;
         num_refl++;
       }
+#endif
+      if (debugFlag) cerr << "Total internal reflection: " << 
costheta2squared << "\n";
     } else {
-      Real cosine = Sqrt(cosine_sq);
-      Real k = 1 - cosine;
-      k*=(k*k)*(k*k);
-
-      Real r0 = (n_values.data[i] - nt_values.data[i]) / (n_values.data[i] + 
nt_values.data[i]);
-      r0 *= r0;
-      Real R = r0*(1-k) + k;
-      if (rays.getFlag(RayPacket::DebugPacket)) cerr << "r0 = "<<r0<<"\n";
+      Real costheta2 = Sqrt(costheta2squared);
+      Real refl;
 
-      // Possibly create refraction ray
-      refr_attenuation[num_refr] = beers_color * (1-R);
-      Color refr_importance = in_importance * refr_attenuation[num_refr];
-      if(refr_importance.luminance() > cutoff){
-        refracted_rays.setImportance(num_refr, refr_importance);
-        Vector refr_dir = rayD*eta_tmp_inv +
-                          (n_dot_v*eta_tmp_inv - cosine) * normal;
-        refracted_rays.setRay(num_refr, hitpos, refr_dir);
-        refr_source[num_refr] = i;
-        num_refr++;
+      if (doSchlick) {
+        refl = SchlickReflection(costheta, costheta2, eta_inverse);
+      } else {
+        refl = FresnelReflection(costheta, costheta2,
+                                 n_values.data[i], nt_values.data[i]);
+      }
+      if (debugFlag) {
+        Real schlick_refl, fresnel_refl;
+        if (doSchlick) {
+          schlick_refl = refl;
+          fresnel_refl = FresnelReflection(costheta, costheta2,
+                                           n_values.data[i],
+                                           nt_values.data[i]);
+        } else {
+          schlick_refl = SchlickReflection(costheta, costheta2, eta_inverse);
+          fresnel_refl = refl;
+        }
+        cerr << "schlick_refl = "<<schlick_refl<<", fresnel_refl = 
"<<fresnel_refl<<", refl = "<<refl<<"\n";
       }
 
+#if 1
       // Possibly create reflection ray
-      refl_attenuation[num_refl] = beers_color * R;
+      refl_attenuation[num_refl] = beers_color * refl;
       Color refl_importance = in_importance * refl_attenuation[num_refl];
       if(refl_importance.luminance() > cutoff){
         reflected_rays.setImportance(num_refl, refl_importance);
-        Vector refl_dir = rayD + (2*n_dot_v)*normal;
         reflected_rays.setRay(num_refl, hitpos, refl_dir);
         refl_source[num_refl] = i;
         num_refl++;
+      }
+#endif
+
+      // Possibly create refraction ray
+      refr_attenuation[num_refr] = beers_color * (1-refl);
+      Color refr_importance = in_importance * refr_attenuation[num_refr];
+      if(refr_importance.luminance() > cutoff){
+        refracted_rays.setImportance(num_refr, refr_importance);
+        Vector refr_dir = (eta_inverse * rayD +
+                           (eta_inverse * costheta - costheta2) * normal);
+        refracted_rays.setRay(num_refr, hitpos, refr_dir);
+        refr_source[num_refr] = i;
+        num_refr++;
       }
     }
   }

Modified: trunk/Model/Materials/Dielectric.h
==============================================================================
--- trunk/Model/Materials/Dielectric.h  (original)
+++ trunk/Model/Materials/Dielectric.h  Wed Apr 18 15:23:56 2007
@@ -46,8 +46,9 @@
                Real localCutoffScale = 1)
       : n(new Constant<Real>(n)),
         nt(new Constant<Real>(nt)),
-      sigma_a(new Constant<Color>(sigma_a)),
-      localCutoffScale(localCutoffScale)
+        sigma_a(new Constant<Color>(sigma_a)),
+        localCutoffScale(localCutoffScale),
+        doSchlick(false)
         { }
 
     Dielectric(const Texture<Real>* n, const Texture<Real>* nt,
@@ -58,12 +59,14 @@
     void shade(const RenderContext& context, RayPacket& rays) const;
     virtual void attenuateShadows(const RenderContext& context,
                                   RayPacket& shadowRays) const;
-                       
+
+    void setDoSchlick(bool new_val) { doSchlick = new_val; }
   private:
     const Texture<Real>* n;
     const Texture<Real>* nt;
     const Texture<Color>* sigma_a;
     Real localCutoffScale;
+    bool doSchlick;
   };
 }
 

Modified: trunk/Model/Primitives/Cylinder.cc
==============================================================================
--- trunk/Model/Primitives/Cylinder.cc  (original)
+++ trunk/Model/Primitives/Cylinder.cc  Wed Apr 18 15:23:56 2007
@@ -83,12 +83,14 @@
 {
   rays.computeHitPositions();
   for(int i=rays.begin(); i < rays.end(); i++) {
-    Vector xn(xform.multiply_vector(rays.getHitPosition(i)));
+    Vector xn(xform.multiply_point(rays.getHitPosition(i)));
     xn[2]=0.0;
     Vector v=ixform.multiply_vector(xn);
     v.normalize();
     rays.setNormal(i, v);
   }
+  // We either need to set the flag here or don't normalize the normals.
+  rays.setFlag(RayPacket::HaveUnitNormals);
 }
 
 

Modified: trunk/SwigInterface/runmanta.py
==============================================================================
--- trunk/SwigInterface/runmanta.py     (original)
+++ trunk/SwigInterface/runmanta.py     Wed Apr 18 15:23:56 2007
@@ -206,7 +206,7 @@
     objs = Array1_ObjectP()
     #
     checker1 = manta_new(CheckerTexture_Color(Color(RGBColor(.6,.6,.6)),
-                                              Color(RGBColor(0.3,0.3,0.3)),
+                                              Color(RGBColor(0.1,0.6,0.1)),
                                               Vector(1,0,0),
                                               Vector(0,1,0)))
     groundmatl = manta_new(Lambertian(checker1))
@@ -216,7 +216,8 @@
     #
     lenscale = 2.5
     glass = Color(RGBColor(pow(0.80, lenscale), pow(0.93, lenscale), 
pow(0.87, lenscale)))
-    transp_matl = manta_new(Dielectric(1.5, 1, glass))
+    transp_matl = manta_new(Dielectric(1.1, 1.0, glass))
+#    transp_matl.setDoSchlick(True)
     print transp_matl
     objs.add(manta_new(Cube(transp_matl,
                             Vector(-5, -2, 2.95 ),
@@ -225,8 +226,8 @@
 #                             Vector(-5, -2, 2.95 ),
 #                             Vector(-1, 2, 3.05))))
 
-#     objs.add(manta_new(Sphere(transp_matl,
-#                               Vector( -3, 0, 4.5), 0.5)))
+    objs.add(manta_new(Sphere(transp_matl,
+                              Vector( -3, 0, 4.5), 0.5)))
                               
     ringmatl = manta_new(Lambertian(Color(RGBColor(.9, .3, .2))))
     print ringmatl
@@ -234,13 +235,13 @@
     inner_radius = r*0.5
     center = Vector(-6, 0, 3.5+r)
     offset = Vector(2.25*r, 0, 0)
-    for i in range(9):
-        objs.add(manta_new(Ring(ringmatl,
-                                center+offset*i,
-                                Vector(0, 0, 1),
-                                inner_radius, r-inner_radius)))
+#     for i in range(9):
+#         objs.add(manta_new(Ring(ringmatl,
+#                                 center+offset*i,
+#                                 Vector(0, 0, 1),
+#                                 inner_radius, r-inner_radius)))
 
-    #addDebugRays(objs, "raytree", 0.05)
+    #addDebugRays(objs, "raytree", 0.025)
     # Create a BVH
     world.add(manta_new(RealisticBvh(objs.get_objs(), objs.size())))
     scene.setObject(world)
@@ -307,8 +308,9 @@
 
 #defaultCamera = factory.createCamera("pinhole(-eye 3 3 2 -lookat 0 0 0.3 
-up 0 0 1 -fov 60)")
 #defaultCamera = factory.createCamera("pinhole(-eye 8 -18 8.5 -lookat -4.7 
2.5 2.5 -up 0 0 1 -fov 15)")
-defaultCamera = factory.createCamera("pinhole(-eye 8.3 -18 7 -lookat -4.7 
2.5 3 -up 0 0 1 -fov 15)")
+#defaultCamera = factory.createCamera("pinhole(-eye 8.3 -18 7 -lookat -4.7 
2.5 3 -up 0 0 1 -fov 15)")
 #defaultCamera = factory.createCamera("pinhole( -eye 8.06072 -17.7429 
8.73358 -lookat -4.98977 2.23422 2.74486 -up -0.0793095 0.0464671 0.995767 
-fov 15 )")
+defaultCamera = factory.createCamera("pinhole( -eye 7.92503 -16.4782 12.1826 
-lookat -4.42502 2.59203 2.7444 -up -0.216459 0.129008 0.967731 -fov 15 )")
 
 addXInterface(engine, defaultCamera, 512, 512)
 #addNullInterface(engine, defaultCamera, 512, 512)




  • [MANTA] r1349 - in trunk: Model/Materials Model/Primitives SwigInterface, bigler, 04/18/2007

Archive powered by MHonArc 2.6.16.

Top of page