Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1967 - in trunk: Core/Color Image Model/Textures


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1967 - in trunk: Core/Color Image Model/Textures
  • Date: Sun, 6 Jan 2008 14:29:00 -0700 (MST)

Author: boulos
Date: Sun Jan  6 14:28:57 2008
New Revision: 1967

Modified:
   trunk/Core/Color/ColorSpace.h
   trunk/Core/Color/GrayTraits.h
   trunk/Core/Color/RGBTraits.h
   trunk/Image/SimpleImage_special.cc
   trunk/Model/Textures/ImageTexture.cc
   trunk/Model/Textures/ImageTexture.h
Log:
Core/Color/ColorSpace.h
Core/Color/GrayTraits.h
Core/Color/RGBTraits.h

 Adding a linearize function to ColorSpaces that describes how to
 convert a gamma corrected value into a linear value.

 The RGBTraits class uses the sRGB conversion (with simplified
 approximation ifdef'ed out), while GrayTraits assumes linear (this
 might not be a good idea for grey bump maps, but not many formats
 store only 1 channel anyway).

Image/SimpleImage_special.cc

 Adding an SSE implementation of RGBtoSRGB (the opposite of linearize)
 to prepare Manta's linear values for display. After a lot of
 searching, I think we have to tell OpenGL that our framebuffer will
 be sRGB (otherwise it seems to be up to the vendor). 

 This is currently disabled by default.

Model/Textures/ImageTexture.cc
Model/Textures/ImageTexture.h

 Adding support for linearizing image textures on input. This is also
 disabled by default to retain current behavior for people that expect
 this during the SIGGRAPH season ;).


Modified: trunk/Core/Color/ColorSpace.h
==============================================================================
--- trunk/Core/Color/ColorSpace.h       (original)
+++ trunk/Core/Color/ColorSpace.h       Sun Jan  6 14:28:57 2008
@@ -260,6 +260,10 @@
       return Traits::luminance(data);
     }
 
+    static ComponentType linearize(ComponentType val) {
+      return Traits::linearize(val);
+    }
+
 #ifndef SWIG // Swig gets confused about NumComponents, and you can
              // use the regular [] operators.
     ComponentType data[NumComponents];
@@ -320,7 +324,7 @@
     }
     static bool force_initialize;
   };
-  
+
 }
 
 #endif

Modified: trunk/Core/Color/GrayTraits.h
==============================================================================
--- trunk/Core/Color/GrayTraits.h       (original)
+++ trunk/Core/Color/GrayTraits.h       Sun Jan  6 14:28:57 2008
@@ -36,6 +36,10 @@
     static ComponentType luminance(const ComponentType data) {
       return data;
     }
+
+    static ComponentType linearize(const ComponentType val) {
+      return val;
+    }
   };
 }
 

Modified: trunk/Core/Color/RGBTraits.h
==============================================================================
--- trunk/Core/Color/RGBTraits.h        (original)
+++ trunk/Core/Color/RGBTraits.h        Sun Jan  6 14:28:57 2008
@@ -5,6 +5,7 @@
 #include <Core/Color/RGBColor.h>
 #include <Core/Color/Conversion.h>
 #include <Core/Persistent/MantaRTTI.h>
+#include <Core/Math/Expon.h>
 
 namespace Manta {
   class ArchiveElement;
@@ -41,6 +42,19 @@
 
     static ComponentType luminance(const ComponentType data[3]) {
       return data[0] * ComponentType(0.3) + data[1] * ComponentType(0.59) + 
data[2] * ComponentType(0.11);
+    }
+
+    // Convert from SRGB to RGB
+    static ComponentType linearize(const ComponentType val) {
+#if 1
+      if (val > 0.04045) {
+        return Pow((val + .055)/(1.055), 2.4);
+      } else {
+        return val / 12.92;
+      }
+#else
+      return Pow(val, 2.2f);
+#endif
     }
 
     static void readwrite(ArchiveElement* archive, ComponentType data[3]);

Modified: trunk/Image/SimpleImage_special.cc
==============================================================================
--- trunk/Image/SimpleImage_special.cc  (original)
+++ trunk/Image/SimpleImage_special.cc  Sun Jan  6 14:28:57 2008
@@ -1,4 +1,5 @@
-
+#include <Core/Math/ExponSSE.h>
+#include <Core/Math/SSEDefs.h>
 #include <Image/SimpleImage.h>
 #include <iostream>
 #include <MantaSSE.h>
@@ -6,6 +7,26 @@
 using namespace Manta;
 using namespace std;
 
+#define MANTA_USE_SRGB 0
+
+#if MANTA_USE_SRGB
+inline __m128 RGBtoSRGB(__m128 val) {
+#if 1
+  // NOTE(boulos): This conversion follows that given in the OpenGL
+  // sRGB texture spec (question 14):
+  // http://opengl.org/registry/specs/EXT/texture_sRGB.txt and that of
+  // the framebuffer spec:
+  // http://www.opengl.org/registry/specs/EXT/framebuffer_sRGB.txt
+  __m128 use_gamma = _mm_cmplt_ps(_mm_set1_ps(.0031308f), val);
+  __m128 linear_ver = _mm_mul_ps(val, _mm_set1_ps(12.92f));
+  __m128 gamma_ver  = _mm_sub_ps(_mm_mul_ps(_mm_set1_ps(1.055f), 
PowSSEMathH(val, _mm_set1_ps(0.41666f), use_gamma)), _mm_set1_ps(.055f));
+  return mask4(use_gamma, gamma_ver, linear_ver);
+#else
+  return PowSSEMathH(val, _mm_set1_ps(1.f/2.2f));
+#endif
+}
+#endif
+
 template<>
 void SimpleImage<ARGB8Pixel>::set(const Fragment& fragment)
 {
@@ -24,9 +45,15 @@
         __m128 r = _mm_load_ps(&fragment.color[0][i]);
         __m128 g = _mm_load_ps(&fragment.color[1][i]);
         __m128 b = _mm_load_ps(&fragment.color[2][i]);
+#if MANTA_USE_SRGB
+        r = RGBtoSRGB(r);
+        g = RGBtoSRGB(g);
+        b = RGBtoSRGB(b);
+#endif
         r = _mm_mul_ps(r, scale);
         g = _mm_mul_ps(g, scale);
         b = _mm_mul_ps(b, scale);
+
         __m128i alpha = _mm_set1_epi32(255);  // alpha
         __m128i r32 = _mm_cvttps_epi32(r); // 32 bits: r0r1r2r3
         __m128i g32 = _mm_cvttps_epi32(g); // 32 bits: g0g1g2g3
@@ -203,7 +230,6 @@
         __m128 g = _mm_load_ps(&fragment.color[1][i]);
         __m128 b = _mm_load_ps(&fragment.color[2][i]);
         __m128 a = _mm_set_ps1(1.0f);  // alpha a0a1a2a3
-
         // This will do the following
         // r = r0r1r2r3       r = r0g0b0a0
         // g = g0g1g2g3   =>  g = r1g1b1a1

Modified: trunk/Model/Textures/ImageTexture.cc
==============================================================================
--- trunk/Model/Textures/ImageTexture.cc        (original)
+++ trunk/Model/Textures/ImageTexture.cc        Sun Jan  6 14:28:57 2008
@@ -50,9 +50,11 @@
   // This will potentially throw a InputError exception if there was a
   // problem.
   ImageTexture<Color>* LoadColorImageTexture( const std::string& file_name,
-                                              std::ostream* stream )
+                                              std::ostream* stream,
+                                              bool linearize)
   {
     if (stream) (*stream) << "Trying to load "<<file_name<<"\n";
+    if (linearize && stream) (*stream) << "Will linearize on input\n";
     Image *image = 0;
 
     // Load the image.
@@ -101,7 +103,7 @@
     }
 
     // Create the texture.
-    ImageTexture<Color> *texture = new ImageTexture<Color>( image );
+    ImageTexture<Color> *texture = new ImageTexture<Color>(image, linearize);
 
     // Free time image.
     delete image;

Modified: trunk/Model/Textures/ImageTexture.h
==============================================================================
--- trunk/Model/Textures/ImageTexture.h (original)
+++ trunk/Model/Textures/ImageTexture.h Sun Jan  6 14:28:57 2008
@@ -78,7 +78,8 @@
   // problem.  If stream is non null it will write out chatty stuff to
   // that.
   ImageTexture<Color>* LoadColorImageTexture( const std::string& file_name,
-                                              std::ostream* stream = 0 );
+                                              std::ostream* stream = 0,
+                                              bool linearize = false);
 
   // Whatever type ValueType ends up being, it needs to have
   // ValueType::ScalarType defined.  I'm not sure what to do for
@@ -88,7 +89,7 @@
   template< typename ValueType >
   class ImageTexture : public Texture< ValueType > {
   public:
-    ImageTexture(const Image* image);
+    ImageTexture(const Image* image, bool linearize = true);
     virtual ~ImageTexture() {}
 
     virtual void mapValues(Packet<ValueType>& results,
@@ -210,7 +211,7 @@
   };
 
   template< class ValueType >
-  ImageTexture< ValueType >::ImageTexture(const Image* image):
+  ImageTexture< ValueType >::ImageTexture(const Image* image, bool 
linearize) :
     scale(VectorT< ScalarType, 2 >(1,1)),
     interpolation_method(NearestNeighbor),
     u_edge(Wrap), v_edge(Wrap)
@@ -223,15 +224,34 @@
     }
     texture.resize(xres, yres);
 
-    // Now copy over the data
-    for(int y = 0; y < yres; y++) {
-      for(int x = 0; x < xres; x+=Fragment::MaxSize) {
-        int end = x + Fragment::MaxSize;
-        if (end > xres) end = xres;
-        Fragment fragment(x, end, y, 0);
-        image->get(fragment);
-        for(int i = fragment.begin(); i < fragment.end(); i++) {
-          texture(x+i, y) = fragment.getColor(i);
+    if (linearize) {
+      // Now copy over the data
+      for(int y = 0; y < yres; y++) {
+        for(int x = 0; x < xres; x+=Fragment::MaxSize) {
+          int end = x + Fragment::MaxSize;
+          if (end > xres) end = xres;
+          Fragment fragment(x, end, y, 0);
+          image->get(fragment);
+          for(int i = fragment.begin(); i < fragment.end(); i++) {
+            ValueType new_value = fragment.getColor(i);
+            for (int c = 0; c < ValueType::NumComponents; c++) {
+              new_value[c] = ValueType::linearize(new_value[c]);
+            }
+            texture(x+i, y) = new_value;
+          }
+        }
+      }
+    } else {
+      // Now copy over the data
+      for(int y = 0; y < yres; y++) {
+        for(int x = 0; x < xres; x+=Fragment::MaxSize) {
+          int end = x + Fragment::MaxSize;
+          if (end > xres) end = xres;
+          Fragment fragment(x, end, y, 0);
+          image->get(fragment);
+          for(int i = fragment.begin(); i < fragment.end(); i++) {
+            texture(x+i, y) = fragment.getColor(i);
+          }
         }
       }
     }





Archive powered by MHonArc 2.6.16.

Top of page