Manta Interactive Ray Tracer Development Mailing List

Text archives Help


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


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r455 - branches/itanium2/Model/Materials
  • Date: Fri, 29 Jul 2005 02:34:56 -0600 (MDT)

Author: boulos
Date: Fri Jul 29 02:34:55 2005
New Revision: 455

Added:
   branches/itanium2/Model/Materials/AmbientOcclusion.cc
   branches/itanium2/Model/Materials/AmbientOcclusion.h
Modified:
   branches/itanium2/Model/Materials/CMakeLists.txt
Log:
Adding an AmbientOcclusion shader.  The shader
precomputes a set of num_directions that are 
cosine weighted and at shading time transforms
these directions using the surface orientation
into directions for occlusion rays.



Added: branches/itanium2/Model/Materials/AmbientOcclusion.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Materials/AmbientOcclusion.cc       Fri Jul 29 
02:34:55 2005
@@ -0,0 +1,124 @@
+#include <Model/Materials/AmbientOcclusion.h>
+#include <Interface/Primitive.h>
+#include <Interface/RayPacket.h>
+#include <Interface/Context.h>
+#include <Interface/Scene.h>
+#include <Model/Textures/Constant.h>
+#include <Core/Math/MT_RNG.h>
+#include <SCIRun/Core/Math/Trig.h>
+
+using namespace Manta;
+
+// TODO: sort the rays generated in generateDirections to make them more
+// coherent for ray packets.
+
+AmbientOcclusion::AmbientOcclusion(const Color& color, float cutoff_dist, 
int num_dirs)
+{
+    colortex = new Constant<Color>(color);
+    cutoff_tex = new Constant<float>(cutoff_dist);
+    num_directions = num_dirs;
+    inv_num_directions = 1.f/float(num_directions);
+    generateDirections();
+}
+
+AmbientOcclusion::AmbientOcclusion(const Texture<Color>* color, const 
Texture<float>* cutoff_dist, int num_dirs) : colortex(color), 
cutoff_tex(cutoff_dist), num_directions(num_dirs)
+{
+    inv_num_directions = 1.f/float(num_directions);
+    generateDirections();
+}
+
+AmbientOcclusion::~AmbientOcclusion()
+{
+    if (directions) delete[] directions;
+}
+
+void AmbientOcclusion::generateDirections()
+
+{
+    directions = new Vector[num_directions];
+    MT_RNG rng;
+    // generate cosine weighted directions
+    for ( int i = 0; i < num_directions; i++ )
+    {
+        double r1 = rng.genRealRand<double>();
+        double r2 = rng.genRealRand<double>();
+
+        double phi = 2.0 * Pi * r1;
+        double r   = sqrt(r2);
+        double x   = r * Cos(phi);
+        double y   = r * Sin(phi);
+        double z   = 1.0 - x*x - y*y;
+        z = (z > 0.0) ? sqrt(z) : 0.0;
+
+        directions[i] = Vector(x, y, z);
+    }
+}
+
+void AmbientOcclusion::shade(const RenderContext& context, RayPacket& rays) 
const
+{
+    // Compute normals
+    rays.computeNormals(context);
+
+    // Compute colors
+    Color colors[RayPacket::MaxSize];
+    float dists[RayPacket::MaxSize];
+    colortex->mapValues(context, rays, colors);
+    cutoff_tex->mapValues(context, rays, dists);
+
+
+
+    for (int i = 0; i < rays.getSize(); i++)
+    {
+        // for each position, compute a local coordinate frame
+        // and build a set of rays to push into a ray packet
+        RayPacket::Element& e = rays.get(i);
+        Vector U,V,W; // surface ONB
+        W = e.normal;
+        W.normalize();
+        U = Cross(W, Vector(1,0,0));
+        double squared_length = U.length2();
+        if ( squared_length < 1e-6 )
+        {
+            U = Cross(W, Vector(0,1,0));
+            U.normalize();
+        }
+        else
+            U *= 1./sqrt(squared_length);
+        V = Cross(W, U);
+
+        int num_sent = 0;
+        float num_miss = 0.f;
+        while ( num_sent < num_directions )
+        {
+            int start = num_sent + 1;
+            int end   = start + RayPacket::MaxSize;
+            if (end > num_directions) end = num_directions;
+
+            RayPacketData occlusion_data;
+            RayPacket occlusion_rays(occlusion_data, end-start, 
rays.getDepth(), RayPacket::NormalizedDirections | RayPacket::ConstantOrigin);
+
+            for ( int r = start; r <= end; r++ )
+            {
+                RayPacket::Element& element = occlusion_rays.get(r-start);
+                Vector trans_dir = directions[r][0]*U + directions[r][1]*V + 
directions[r][2]*W;
+                element.ray.set(e.hitPosition, trans_dir);
+                // set max distance
+                element.hitInfo.reset(dists[i]);
+            }
+            // packet is ready, test it for shadows
+            context.scene->getObject()->intersect(context, occlusion_rays);
+            // count the number of occluded ones
+            for (int r = start; r <= end; r++ )
+            {
+                RayPacket::Element& element = occlusion_rays.get(r-start);
+                if(!element.hitInfo.wasHit())
+                    num_miss+=1.0f;
+            }
+            num_sent = end;
+        }
+
+        // now we can shade our ray
+        *e.color = colors[i]*(num_miss*inv_num_directions);
+    }
+
+}

Added: branches/itanium2/Model/Materials/AmbientOcclusion.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Materials/AmbientOcclusion.h        Fri Jul 29 
02:34:55 2005
@@ -0,0 +1,33 @@
+#ifndef Manta_Model_AmbientOcclusion_h
+#define Manta_Model_AmbientOcclusion_h
+
+#include <Model/Materials/LitMaterial.h>
+#include <Core/Color/Color.h>
+#include <Interface/Texture.h>
+
+namespace Manta
+{
+    class LightSet;
+
+    class AmbientOcclusion : public LitMaterial
+    {
+    public:
+        AmbientOcclusion(const Color& color, float cutoff_dist, int 
num_dirs);
+        AmbientOcclusion(const Texture<Color>* color, const Texture<float>* 
cutoff_dist, int num_dirs);
+        AmbientOcclusion() {  }
+        ~AmbientOcclusion();
+
+        void generateDirections();
+
+        // generate the directions
+        void shade(const RenderContext& context, RayPacket& rays) const;
+    private:
+        const Texture<Color>* colortex;
+        const Texture<float>* cutoff_tex;
+        Vector* directions;
+        int num_directions;
+        float inv_num_directions;
+    };
+}
+
+#endif

Modified: branches/itanium2/Model/Materials/CMakeLists.txt
==============================================================================
--- branches/itanium2/Model/Materials/CMakeLists.txt    (original)
+++ branches/itanium2/Model/Materials/CMakeLists.txt    Fri Jul 29 02:34:55 
2005
@@ -22,4 +22,6 @@
      Materials/CopyColorMaterial.cc
      Materials/NormalMaterial.h
      Materials/NormalMaterial.cc # Shade the material using it's normal.
+     Materials/AmbientOcclusion.h
+     Materials/AmbientOcclusion.cc
      )




  • [MANTA] r455 - branches/itanium2/Model/Materials, boulos, 07/29/2005

Archive powered by MHonArc 2.6.16.

Top of page