Quellcode durchsuchen

fill in the LogLuv, RGBM, and RGBD decoders/encoders.

Ben Houston vor 9 Jahren
Ursprung
Commit
af4929ea08

+ 2 - 2
src/Three.js

@@ -311,7 +311,7 @@ THREE.TriangleFanDrawMode = 2;
 THREE.LinearEncoding = 3000; // No encoding at all.
 THREE.sRGBEncoding = 3001; // AKA gamma 2.2.
 THREE.RGBEEncoding = 3002; // AKA Radiance
-//THREE.LogLuvEncoding = 3003; TODO
+THREE.LogLuvEncoding = 3003;
 THREE.RGBM7Encoding = 3004;
 THREE.RGBM16Encoding = 3005;
-//THREE.RGBDEncoding = 3006; TODO
+THREE.RGBDEncoding = 3006; // MaxRange is 256

+ 14 - 14
src/renderers/shaders/ShaderChunk/encoding_template.glsl

@@ -9,14 +9,14 @@
     return sRGBToLinear( value );
   #elif ( MACRO_DECODE == ENCODING_RGBE )
     return RGBEToLinear( value );
-  //#elif ( MACRO_DECODE == ENCODING_LogLuv )  TODO
-  //  return LogLuvToLinear( value );
+  #elif ( MACRO_DECODE == ENCODING_LogLuv )
+    return LogLuvToLinear( value );
   #elif ( MACRO_DECODE == ENCODING_RGBM7 )
-    return RGBM7ToLinear( value );
+    return RGBMToLinear( value, 7.0 );
   #elif ( MACRO_DECODE == ENCODING_RGBM16 )
-    return RGBM16ToLinear( value );
-  //#elif ( MACRO_DECODE == ENCODING_RGBD )  TODO
-  //  return RGBMDToLinear( value );
+    return RGBMToLinear( value, 16.0 );
+  #elif ( MACRO_DECODE == ENCODING_RGBD )
+    return RGBDToLinear( value, 256.0 );
   #else
     return vec4( 1.0, 0.0, 0.0, 1.0 );
   #endif
@@ -29,14 +29,14 @@
     return LinearTosRGB( value );
   #elif ( MACRO_ENCODE == ENCODING_RGBE )
     return LinearToRGBE( value );
-  //#elif ( MACRO_ENCODE == ENCODING_LogLuv )  TODO
-  //  return LinearToLogLuv( value );
-  //#elif ( MACRO_ENCODE == ENCODING_RGBM7 )  TODO
-  //  return LinearToRGBM7( value );
-  //#elif ( MACRO_ENCODE == ENCODING_RGBM16 )  TODO
-  //  return LinearToRGBM16( value );
-  //#elif ( MACRO_ENCODE == ENCODING_RGBD )  TODO
-  //  return LinearToRGBMD( value );
+  #elif ( MACRO_ENCODE == ENCODING_LogLuv )
+    return LinearToLogLuv( value );
+  #elif ( MACRO_ENCODE == ENCODING_RGBM7 )
+    return LinearToRGBM( value, 7.0 );
+  #elif ( MACRO_ENCODE == ENCODING_RGBM16 )
+    return LinearToRGBM( value, 16.0 );
+  #elif ( MACRO_ENCODE == ENCODING_RGBD )
+    return LinearToRGBD( value, 256.0 );
   #else
     return vec4( 1.0, 0.0, 0.0, 1.0 );
   #endif

+ 57 - 12
src/renderers/shaders/ShaderChunk/encodings.glsl

@@ -4,10 +4,10 @@
 #define ENCODING_Linear 3000
 #define ENCODING_sRGB   3001
 #define ENCODING_RGBE   3002
-//#define ENCODING_LogLuv 3003
+#define ENCODING_LogLuv 3003
 #define ENCODING_RGBM7  3004
 #define ENCODING_RGBM16 3005
-//#define ENCODING_RGBM16 3007
+#define ENCODING_RGBD   3006
 
 vec4 LinearToLinear( in vec4 value ) {
   return value;
@@ -16,25 +16,70 @@ vec4 LinearToLinear( in vec4 value ) {
 vec4 sRGBToLinear( in vec4 value ) {
   return vec4( pow( value.xyz, vec3( float( GAMMA_FACTOR ) ) ), value.w );
 }
+vec4 LinearTosRGB( in vec4 value ) {
+  return vec4( pow( value.xyz, vec3( 1.0 / float( GAMMA_FACTOR ) ) ), value.w );
+}
 
 vec4 RGBEToLinear( in vec4 value ) {
   return vec4( value.xyz * exp2( value.w*256.0 - 128.0 ), 1.0 );
 }
+vec4 LinearToRGBE( in vec4 value ) {
+  float maxComponent = max(max(value.r, value.g), value.b );
+  float fExp = ceil( log2(maxComponent) );
+  return vec4( value.rgb / exp2(fExp), (fExp + 128.0) / 255.0 );
+}
 
-vec4 RGBM7ToLinear( in vec4 value ) {
-  return vec4( value.xyz * value.w * 7.0, 1.0 );
+// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
+vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
+  return vec4( value.xyz * value.w * maxRange, 1.0 );
+}
+vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
+  float maxRGB = max( value.x, max( value.g, value.b ) );
+  float M      = maxRGB / maxRange;
+  M            = ceil( M * 255.0 ) / 255.0;
+  return vec4( value.rgb / ( M * maxRange ), M );
 }
 
-vec4 RGBM16ToLinear( in vec4 value ) {
-  return vec4( value.xyz * value.w * 16.0, 1.0 );
+// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
+vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
+    return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
+}
+vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
+    float maxRGB = max( value.x, max( value.g, value.b ) );
+    float D      = max( maxRange / maxRGB, 1.0 );
+    D            = saturate( floor( D ) / 255.0 );
+    return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
 }
 
-vec4 LinearTosRGB( in vec4 value ) {
-  return vec4( pow( value.xyz, vec3( 1.0 / float( GAMMA_FACTOR ) ) ), value.w );
+// LogLuv reference: http://graphicrants.blogspot.ca/2009/04/rgbm-color-encoding.html
+
+// M matrix, for encoding
+const mat3 cLogLuvM = mat3(
+  0.2209, 0.3390, 0.4184,
+  0.1138, 0.6780, 0.7319,
+  0.0102, 0.1130, 0.2969);
+vec4 LinearToLogLuv( in vec4 value )  {
+  vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;
+  Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));
+  vec4 vResult;
+  vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
+  float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
+  vResult.w = fract(Le);
+  vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;
+  return vResult;
 }
 
-vec4 LinearToRGBE( in vec4 value ) {
-  float maxComponent = max(max(value.r, value.g), value.b );
-  float fExp = ceil( log2(maxComponent) );
-  return vec4( value.rgb / exp2(fExp), (fExp + 128.0) / 255.0 );
+// Inverse M matrix, for decoding
+const mat3 cLogLuvInverseM = mat3(
+  6.0014, -2.7008, -1.7996,
+  -1.3320,  3.1029, -5.7721,
+  0.3008, -1.0882,  5.6268);
+vec4 LogLuvToLinear( in vec4 value ) {
+  float Le = value.z * 255.0 + value.w;
+  vec3 Xp_Y_XYZp;
+  Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);
+  Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
+  Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
+  vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;
+  return vec4( max(vRGB, 0.0), 1.0 );
 }