浏览代码

Merge pull request #949 from Azaezel/alpha403/hdrFixes

Alpha403/hdr fixes
Brian Roberts 2 年之前
父节点
当前提交
d8d0139ff1

+ 3 - 4
Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript

@@ -283,8 +283,7 @@ function HDRPostFX::setShaderConsts( %this )
       %tonemapMode = 4;	  
  else if($PostFX::HDRPostFX::tonemapMode $= "Linear")
       %tonemapMode = 5;
- 
-      
+   
    %combinePass.setShaderConst( "$g_fTonemapMode", %tonemapMode );
    
    %clampedGamma  = mClamp( $pref::Video::Gamma, 2.0, 2.5);
@@ -302,6 +301,7 @@ function HDRPostFX::setShaderConsts( %this )
    {
      %mip = %bloom.getObject(%this.mipsCount + %idx);
      %mip.setShaderConst("$filterRadius", $PostFX::HDRPostFX::radius);
+     %mip.setShaderConst("$mipId", %idx);
    }
 
    %strength = $PostFX::HDRPostFX::intensity;
@@ -447,7 +447,7 @@ function HDRPostFX::populatePostFXSettings(%this)
    PostEffectEditorInspector.addField("$PostFX::HDRPostFX::enableBloom", "Enable Bloom", "bool", "", $PostFX::HDRPostFX::enableBloom, "");
    PostEffectEditorInspector.addField("$PostFX::HDRPostFX::threshold", "Threshold", "range", "", $PostFX::HDRPostFX::threshold, "0 2 10");
    PostEffectEditorInspector.addField("$PostFX::HDRPostFX::intensity", "Intensity", "range", "", $PostFX::HDRPostFX::intensity, "0 10 10");
-   PostEffectEditorInspector.addField("$PostFX::HDRPostFX::radius", "Radius", "float", "", $PostFX::HDRPostFX::radius, "");
+   PostEffectEditorInspector.addField("$PostFX::HDRPostFX::radius", "Radius", "range", "", $PostFX::HDRPostFX::radius, "0 25 50");
    PostEffectEditorInspector.endGroup();
    
    PostEffectEditorInspector.startGroup("HDR - Lens Dirt");
@@ -763,4 +763,3 @@ function LuminanceVisPostFX::onDisabled( %this )
 {      
    HDRPostFX.skip = false; 
 }
-

+ 47 - 24
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl

@@ -20,43 +20,66 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+#include "core/rendering/shaders/gl/torque.glsl"
 #include "core/rendering/shaders/gl/hlslCompat.glsl"
 #include "core/rendering/shaders/postFX/gl/postFx.glsl"
+#include "core/postFX/scripts/HDR/HDR_colorUtils.glsl"
 #include "shadergen:/autogenConditioners.h"
-
-#line 27
-
-#define KERNEL_SAMPLES 9
-const vec3 KERNEL[9] = vec3[](
-  vec3( 0.0000, 0.0000, 0.2500),
-  vec3( 1.0000, 0.0000, 0.1250),
-  vec3( 0.0000, 1.0000, 0.1250),
-  vec3(-1.0000, 0.0000, 0.1250),
-  vec3( 0.0000,-1.0000, 0.1250),
-  vec3( 1.0000, 1.0000, 0.0625),
-  vec3( 1.0000,-1.0000, 0.0625),
-  vec3(-1.0000,-1.0000, 0.0625),
-  vec3(-1.0000, 1.0000, 0.0625)
-);
-
+#line 28
 uniform sampler2D inputTex;
 uniform vec2 oneOverTargetSize;
+uniform int mipId;
 
 out vec4 OUT_col;
  
 void main()
 {
   vec4 downSample = vec4(0, 0, 0, 0);
+  float x = oneOverTargetSize.x;
+  float y = oneOverTargetSize.y;
   
-  for (int i=0; i<KERNEL_SAMPLES; i++)
+  vec3 a = texture(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y + 2 * y)).rgb;
+  vec3 b = texture(inputTex, vec2(IN_uv0.x,         IN_uv0.y + 2 * y)).rgb;
+  vec3 c = texture(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y + 2 * y)).rgb;
+
+  vec3 d = texture(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y)).rgb;
+  vec3 e = texture(inputTex, vec2(IN_uv0.x,         IN_uv0.y)).rgb;
+  vec3 f = texture(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y)).rgb;
+
+  vec3 g = texture(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y - 2 * y)).rgb;
+  vec3 h = texture(inputTex, vec2(IN_uv0.x,         IN_uv0.y - 2 * y)).rgb;
+  vec3 i = texture(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y - 2 * y)).rgb;
+
+  vec3 j = texture(inputTex, vec2(IN_uv0.x - x, IN_uv0.y + y)).rgb;
+  vec3 k = texture(inputTex, vec2(IN_uv0.x + x, IN_uv0.y + y)).rgb;
+  vec3 l = texture(inputTex, vec2(IN_uv0.x - x, IN_uv0.y - y)).rgb;
+  vec3 m = texture(inputTex, vec2(IN_uv0.x + x, IN_uv0.y - y)).rgb;
+
+  vec3 group[5];
+  switch (mipId)
   {
-    // XY: Sample Offset
-    // Z: Sample Weight
-    vec3 offsetWeight = KERNEL[i];
-    vec2 offsetXY = offsetWeight.xy * oneOverTargetSize;
-    float weight = offsetWeight.z;
-    vec4 sampleCol = texture(inputTex, IN_uv0 + offsetXY);
-    downSample += sampleCol * weight;
+	case 0:
+		group[0] = (a+b+d+e) * (0.125f/4.0f);
+		group[1] = (b+c+e+f) * (0.125f/4.0f);
+		group[2] = (d+e+g+h) * (0.125f/4.0f);
+		group[3] = (e+f+h+i) * (0.125f/4.0f);
+		group[4] = (j+k+l+m) * (0.5f/4.0f);
+		group[0] *= KarisAverage(group[0]);
+		group[1] *= KarisAverage(group[1]);
+		group[2] *= KarisAverage(group[2]);
+		group[3] *= KarisAverage(group[3]);
+		group[4] *= KarisAverage(group[4]);
+		downSample.rgb = group[0]+group[1]+group[2]+group[3]+group[4];
+		downSample.a = 1.0;
+		break;
+		
+	default:
+		downSample.rgb = e*0.125;
+		downSample.rgb += (a+c+g+i)*0.03125;
+		downSample.rgb += (b+d+f+h)*0.0625;
+		downSample.rgb += (j+k+l+m)*0.125;
+		downSample.a = 1.0;
+		break;
   }
   
   OUT_col = downSample;

+ 45 - 22
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl

@@ -21,37 +21,60 @@
 //-----------------------------------------------------------------------------
 
 #include "core/rendering/shaders/postFX/postFx.hlsl"
-
-#define KERNEL_SAMPLES 9
-static const float3 KERNEL[9] = {
-  float3( 0.0000f, 0.0000f, 0.2500f),
-  float3( 1.0000f, 0.0000f, 0.1250f),
-  float3( 0.0000f, 1.0000f, 0.1250f),
-  float3(-1.0000f, 0.0000f, 0.1250f),
-  float3( 0.0000f,-1.0000f, 0.1250f),
-  float3( 1.0000f, 1.0000f, 0.0625f),
-  float3( 1.0000f,-1.0000f, 0.0625f),
-  float3(-1.0000f,-1.0000f, 0.0625f),
-  float3(-1.0000f, 1.0000f, 0.0625f)
-};
+#include "core/postFX/scripts/HDR/HDR_colorUtils.hlsl"
 
 TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
 uniform float2 oneOverTargetSize;
+uniform int mipId;
  
 float4 main(PFXVertToPix IN) : TORQUE_TARGET0
 {
   float4 downSample = float4(0, 0, 0, 0);
+  float x = oneOverTargetSize.x;
+  float y = oneOverTargetSize.y;
+  
+  float3 a = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y + 2*y)).rgb;
+  float3 b = TORQUE_TEX2D(inputTex, float2(IN.uv0.x		   , IN.uv0.y + 2*y)).rgb;
+  float3 c = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y + 2*y)).rgb;
+  
+  float3 d = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y)).rgb;
+  float3 e = TORQUE_TEX2D(inputTex, float2(IN.uv0.x		   , IN.uv0.y)).rgb;
+  float3 f = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y)).rgb;
+  
+  float3 g = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y - 2*y)).rgb;
+  float3 h = TORQUE_TEX2D(inputTex, float2(IN.uv0.x		   , IN.uv0.y - 2*y)).rgb;
+  float3 i = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y - 2*y)).rgb;
+  
+  float3 j = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - x, IN.uv0.y + y)).rgb;
+  float3 k = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + x, IN.uv0.y + y)).rgb;
+  float3 l = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - x, IN.uv0.y - y)).rgb;
+  float3 m = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + x, IN.uv0.y - y)).rgb;
   
-  [unroll]
-  for (int i=0; i<KERNEL_SAMPLES; i++)
+  float3 group[5];
+  switch (mipId)
   {
-    // XY: Sample Offset
-    // Z: Sample Weight
-    float3 offsetWeight = KERNEL[i];
-    float2 offset = offsetWeight.xy * oneOverTargetSize;
-    float weight = offsetWeight.z;
-    float4 sampleCol = TORQUE_TEX2D(inputTex, IN.uv0 + offset);
-    downSample += sampleCol * weight;
+	case 0:
+		group[0] = (a+b+d+e) * (0.125f/4.0f);
+		group[1] = (b+c+e+f) * (0.125f/4.0f);
+		group[2] = (d+e+g+h) * (0.125f/4.0f);
+		group[3] = (e+f+h+i) * (0.125f/4.0f);
+		group[4] = (j+k+l+m) * (0.5f/4.0f);
+		group[0] *= KarisAverage(group[0]);
+		group[1] *= KarisAverage(group[1]);
+		group[2] *= KarisAverage(group[2]);
+		group[3] *= KarisAverage(group[3]);
+		group[4] *= KarisAverage(group[4]);
+		downSample.rgb = group[0]+group[1]+group[2]+group[3]+group[4];
+		downSample.a = 1.0;
+		break;
+		
+	default:
+		downSample.rgb = e*0.125;
+		downSample.rgb += (a+c+g+i)*0.03125;
+		downSample.rgb += (b+d+f+h)*0.0625;
+		downSample.rgb += (j+k+l+m)*0.125;
+		downSample.a = 1.0;
+		break;
   }
   
   return downSample;

+ 20 - 26
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/upSampleP.glsl

@@ -23,22 +23,7 @@
 #include "core/rendering/shaders/gl/hlslCompat.glsl"
 #include "core/rendering/shaders/postFX/gl/postFx.glsl"
 #include "shadergen:/autogenConditioners.h"
-
-#line 27
-
-#define KERNEL_SAMPLES 9
-const vec3 KERNEL[9] = vec3[](
-  vec3( 0.0000, 0.0000, 0.5000),
-  vec3( 1.0000, 0.0000, 0.0625),
-  vec3( 0.0000, 1.0000, 0.0625),
-  vec3(-1.0000, 0.0000, 0.0625),
-  vec3( 0.0000,-1.0000, 0.0625),
-  vec3( 0.7070, 0.7070, 0.0625),
-  vec3( 0.7070,-0.7070, 0.0625),
-  vec3(-0.7070,-0.7070, 0.0625),
-  vec3(-0.7070, 0.7070, 0.0625)
-);
-
+#line 26
 uniform sampler2D nxtTex;
 uniform sampler2D mipTex;
 uniform float filterRadius;
@@ -49,17 +34,26 @@ out vec4 OUT_col;
 void main()
 {
   vec4 upSample = vec4(0, 0, 0, 0);
+  float x = filterRadius*oneOverTargetSize.x;
+  float y = filterRadius*oneOverTargetSize.y;
+
+  vec3 a = texture(mipTex, vec2(IN_uv1.x - x, IN_uv1.y + y)).rgb;
+  vec3 b = texture(mipTex, vec2(IN_uv1.x,     IN_uv1.y + y)).rgb;
+  vec3 c = texture(mipTex, vec2(IN_uv1.x + x, IN_uv1.y + y)).rgb;
+
+  vec3 d = texture(mipTex, vec2(IN_uv1.x - x, IN_uv1.y)).rgb;
+  vec3 e = texture(mipTex, vec2(IN_uv1.x,     IN_uv1.y)).rgb;
+  vec3 f = texture(mipTex, vec2(IN_uv1.x + x, IN_uv1.y)).rgb;
+
+  vec3 g = texture(mipTex, vec2(IN_uv1.x - x, IN_uv1 - y)).rgb;
+  vec3 h = texture(mipTex, vec2(IN_uv1.x,     IN_uv1 - y)).rgb;
+  vec3 i = texture(mipTex, vec2(IN_uv1.x + x, IN_uv1 - y)).rgb;
 
-  for (int i=0; i<KERNEL_SAMPLES; i++)
-  {
-    // XY: Sample Offset
-    // Z: Sample Weight
-    vec3 offsetWeight = KERNEL[i];
-    vec2 offsetXY = offsetWeight.xy * oneOverTargetSize * filterRadius;
-    float weight = offsetWeight.z;
-    vec4 sampleCol = texture(mipTex, IN_uv1 + offsetXY);
-    upSample += sampleCol * weight;
-  }
+  upSample.rgb = e*4.0;
+  upSample.rgb += (b+d+f+h)*2.0;
+  upSample.rgb += (a+c+g+i);
+  upSample.rgb *= 1.0 / 16.0; 
+  upSample.a = 1.0;
   
   upSample = texture(nxtTex, IN_uv0) + upSample;
   

+ 19 - 24
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/upSampleP.hlsl

@@ -22,19 +22,6 @@
 
 #include "core/rendering/shaders/postFX/postFx.hlsl"
 
-#define KERNEL_SAMPLES 9
-static const float3 KERNEL[9] = {
-  float3( 0.0000f, 0.0000f, 0.5000f),
-  float3( 1.0000f, 0.0000f, 0.0625f),
-  float3( 0.0000f, 1.0000f, 0.0625f),
-  float3(-1.0000f, 0.0000f, 0.0625f),
-  float3( 0.0000f,-1.0000f, 0.0625f),
-  float3( 0.7070f, 0.7070f, 0.0625f),
-  float3( 0.7070f,-0.7070f, 0.0625f),
-  float3(-0.7070f,-0.7070f, 0.0625f),
-  float3(-0.7070f, 0.7070f, 0.0625f)
-};
-
 TORQUE_UNIFORM_SAMPLER2D(nxtTex, 0);
 TORQUE_UNIFORM_SAMPLER2D(mipTex, 1);
 uniform float filterRadius;
@@ -43,18 +30,26 @@ uniform float2 oneOverTargetSize;
 float4 main(PFXVertToPix IN) : TORQUE_TARGET0
 {
   float4 upSample = float4(0, 0, 0, 0);
+  float x = filterRadius*oneOverTargetSize.x;
+  float y = filterRadius*oneOverTargetSize.y;
+  
+  float3 a = TORQUE_TEX2D(mipTex, float2(IN.uv1.x - x, IN.uv1.y + y)).rgb;
+  float3 b = TORQUE_TEX2D(mipTex, float2(IN.uv1.x,     IN.uv1.y + y)).rgb;
+  float3 c = TORQUE_TEX2D(mipTex, float2(IN.uv1.x + x, IN.uv1.y + y)).rgb;
+  
+  float3 d = TORQUE_TEX2D(mipTex, float2(IN.uv1.x - x, IN.uv1.y)).rgb;
+  float3 e = TORQUE_TEX2D(mipTex, float2(IN.uv1.x,     IN.uv1.y)).rgb;
+  float3 f = TORQUE_TEX2D(mipTex, float2(IN.uv1.x + x, IN.uv1.y)).rgb;
+
+  float3 g = TORQUE_TEX2D(mipTex, float2(IN.uv1.x - x, IN.uv1.y - y)).rgb;
+  float3 h = TORQUE_TEX2D(mipTex, float2(IN.uv1.x,     IN.uv1.y - y)).rgb;
+  float3 i = TORQUE_TEX2D(mipTex, float2(IN.uv1.x + x, IN.uv1.y - y)).rgb;
   
-  [unroll]
-  for (int i=0; i<KERNEL_SAMPLES; i++)
-  {
-    // XY: Sample Offset
-    // Z: Sample Weight
-    float3 offsetWeight = KERNEL[i];
-    float2 offset = offsetWeight.xy * oneOverTargetSize * filterRadius;
-    float weight = offsetWeight.z;
-    float4 sampleCol = TORQUE_TEX2D(mipTex, IN.uv1 + offset);
-    upSample += sampleCol * weight;
-  }
+  upSample.rgb = e*4.0;
+  upSample.rgb += (b+d+f+h)*2.0;
+  upSample.rgb += (a+c+g+i);
+  upSample.rgb *= 1.0 / 16.0;
+  upSample.a = 1.0;
   
   upSample = TORQUE_TEX2D(nxtTex, IN.uv0) + upSample;
   

+ 7 - 1
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_colorUtils.glsl

@@ -37,4 +37,10 @@ float TO_LogContrast (float x, float contrast)
 {       
     float a =  0.15 + (log2(x + 0.0001f ) - 0.15)* contrast ;
     return clamp(exp2(a)-0.0001f,0.0 , 2.5);  
-}  
+} 
+
+float KarisAverage(float3 col)
+{
+	float luma = rgbToHSL(col).z;
+	return 1.0 / (1.0f + luma);
+}

+ 7 - 1
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_colorUtils.hlsl

@@ -40,4 +40,10 @@ float TO_LogContrast (float x, float contrast)
 {       
     float a =  0.15 + (log2(x + 0.0001f ) - 0.15)* contrast ;
     return clamp(exp2(a)-0.0001f,0.0 , 2.5);  
-}  
+}
+
+float KarisAverage(float3 col)
+{
+	float luma = rgbToHSL(col).z;
+	return 1.0 / (1.0f + luma);
+}

+ 3 - 5
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_finalPass.glsl

@@ -63,7 +63,7 @@ vec3 Tonemap(vec3 x)
     //ACES      
     if(g_fTonemapMode == 1.0f)    
    {
-	  x = ACESFitted(x, whitePoint) * 1.4f;  //ACES is crushing our blacks, need to pre-expose!    	  
+	  x = ACESFitted(x, whitePoint);  //ACES is crushing our blacks, need to pre-expose!    	  
    }             
    //Filmic Helji	       
    if(g_fTonemapMode == 2.0f) 
@@ -87,7 +87,7 @@ vec3 Tonemap(vec3 x)
    //Linear Tonemap  
    else if (g_fTonemapMode == 5.0)
    {  
-      x = toLinear(TO_Linear(toGamma(x)));    	   
+      x = toLinear(x);    	   
    }
         
    return x;
@@ -99,10 +99,8 @@ void main()
    float adaptedLum = texture( luminanceTex, vec2( 0.5f, 0.5f ) ).r;
    vec4 bloom = texture( bloomTex, IN_uv2 );
 
-   
-        	    
    // Add the bloom effect.     
-   _sample += bloom;  
+   _sample.rgb +=bloom.rgb;  
            
    //Apply Exposure     
    _sample.rgb *= TO_Exposure(_sample.rgb, exposureValue, colorFilter);

+ 3 - 3
Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_finalPass.hlsl

@@ -58,7 +58,7 @@ float3 Tonemap(float3 x)
     //ACES           
     if(g_fTonemapMode == 1.0f)    
    {              
-      x = ACESFitted(x, whitePoint) * 1.4f; //ACES is crushing our blacks, need to pre-expose!  
+      x = ACESFitted(x, whitePoint); //ACES is crushing our blacks, need to pre-expose!  
    }                             
    //Filmic Helji	       
    if(g_fTonemapMode == 2.0f) 
@@ -82,7 +82,7 @@ float3 Tonemap(float3 x)
    //Linear Tonemap  
    else if (g_fTonemapMode == 5.0)
    {  
-      x = toLinear(TO_Linear(toGamma(x)));   	   
+      x = toLinear(x);   	   
    }
         
    return x;
@@ -95,7 +95,7 @@ float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
    float4 bloom = TORQUE_TEX2D( bloomTex, IN.uv2 ); 
         	    
    // Add the bloom effect.     
-   sample += bloom;         
+   sample.rgb += bloom.rgb;        
    		 	
 	//Apply Exposure     
    sample.rgb *= TO_Exposure(sample.rgb, exposureValue, colorFilter); 

+ 1 - 1
Templates/BaseGame/game/core/postFX/scripts/SMAA/gl/BBtoGamma.glsl

@@ -21,7 +21,7 @@
 //-----------------------------------------------------------------------------
 #include "core/rendering/shaders/gl/torque.glsl"
 #include "core/rendering/shaders/postFX/gl/postFx.glsl"
-
+#line 24
 uniform sampler2D backBuffer; 
 out vec4 OUT_col;
 

+ 1 - 2
Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyP.glsl

@@ -22,8 +22,7 @@
 
 #include "torque.glsl"
 #include "hlslCompat.glsl"
-
-
+#line 25
 // Conn
 in vec4  rayleighColor;
 #define IN_rayleighColor rayleighColor

+ 74 - 25
Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl

@@ -311,49 +311,98 @@ bool getFlag(float flags, float num)
    return (mod(process, pow(2.0, squareNum)) >= squareNum); 
 }
 
-// #define TORQUE_STOCK_GAMMA
-#ifdef TORQUE_STOCK_GAMMA
-// Sample in linear space. Decodes gamma.
-vec4 toLinear(vec4 tex)
+// RGB -> HSL
+vec3 rgbToHSL(vec3 col)
 {
-   return tex;
+	float cmax, cmin, h, s, l;
+	cmax = max(col.r, max(col.g, col.b));
+	cmin = min(col.r, min(col.g, col.b));
+	l = min(1.0, (cmax + cmin) / 2.0);
+
+    if (cmax == cmin) {
+    h = s = 0.0; /* achromatic */
+    }
+    else 
+	{
+        float cdelta = cmax - cmin;
+        s = l > 0.5 ? cdelta / (2.0 - cmax - cmin) : cdelta / (cmax + cmin);
+        if (cmax == col.r) {
+          h = (col.g - col.b) / cdelta + (col.g < col.b ? 6.0 : 0.0);
+        }
+        else if (cmax == col.g) {
+          h = (col.b - col.r) / cdelta + 2.0;
+        }
+        else {
+          h = (col.r - col.b) / cdelta + 4.0;
+        }
+    }
+    h /= 6.0;
+
+	
+	return vec3(h,s,l);
 }
-// Encodes gamma.
-vec4 toGamma(vec4 tex)
+
+// HSL -> RGB
+vec3 hslToRGB(vec3 hsl)
 {
-   return tex;
+	float nr, ng, nb, chroma, h, s, l;
+	h = hsl.r;
+	s = hsl.g;
+	l = hsl.b;
+	
+	nr = abs(h * 6.0 - 3.0) - 1.0;
+	ng = 2.0 - abs(h * 6.0 - 2.0);
+	nb = 2.0 - abs(h * 6.0 - 4.0);
+	
+	nr = clamp(nr, 0.0, 1.0);
+	nb = clamp(nb, 0.0, 1.0);
+	ng = clamp(ng, 0.0, 1.0);
+
+	chroma = (1.0 - abs(2.0 * l - 1.0)) * s;
+	
+	return vec3((nr - 0.5) * chroma + l, (ng - 0.5) * chroma + l, (nb - 0.5) * chroma + l);
 }
-vec3 toLinear(vec3 tex)
+
+// Sample in linear space. Decodes gamma.
+float toLinear(float col)
 {
-   return tex;
+	if(col < 0.04045)
+	{
+		return (col < 0.0) ? 0.0 : col * (1.0 / 12.92);
+	}
+	
+	return pow(abs(col + 0.055) * (1.0 / 1.055), 2.4);
 }
-// Encodes gamma.
-vec3 toGamma(vec3 tex)
+vec4 toLinear(vec4 tex)
 {
-   return tex;
+   return vec4(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b), tex.a);
 }
-#else
-// Sample in linear space. Decodes gamma.
-vec4 toLinear(vec4 tex)
+
+vec3 toLinear(vec3 tex)
 {
-   return vec4(pow(abs(tex.rgb), vec3(2.2)), tex.a);
+   return vec3(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b));
 }
+
 // Encodes gamma.
-vec4 toGamma(vec4 tex)
+float toGamma(float col)
 {
-   return vec4(pow(abs(tex.rgb), vec3(1.0/2.2)), tex.a);
+	if(col < 0.0031308)
+	{
+		return (col < 0.0) ? 0.0 : col * 12.92;
+	}
+	
+	return 1.055 * pow(abs(col), 1.0 / 2.4) - 0.055;
 }
-// Sample in linear space. Decodes gamma.
-vec3 toLinear(vec3 tex)
+
+vec4 toGamma(vec4 tex)
 {
-   return pow(abs(tex), vec3(2.2));
+   return vec4(toGamma(tex.r), toGamma(tex.g), toGamma(tex.b), tex.a);
 }
-// Encodes gamma.
+
 vec3 toGamma(vec3 tex)
 {
-   return pow(abs(tex), vec3(1.0/2.2));
+   return vec3(toGamma(tex.r), toGamma(tex.g), toGamma(tex.b));
 }
-#endif //
 
 vec3 PBRFresnel(vec3 albedo, vec3 indirect, float metalness, float fresnel)
 {

+ 81 - 8
Templates/BaseGame/game/core/rendering/shaders/torque.hlsl

@@ -301,25 +301,98 @@ bool getFlag(float flags, int num)
    return (fmod(process, pow(2, squareNum)) >= squareNum); 
 }
 
-// Sample in linear space. Decodes gamma.
-float4 toLinear(float4 tex)
+// RGB -> HSL
+float3 rgbToHSL(float3 col)
 {
-   return float4(pow(abs(tex.rgb), 2.2), tex.a);
+	float cmax, cmin, h, s, l;
+	cmax = max(col.r, max(col.g, col.b));
+	cmin = min(col.r, min(col.g, col.b));
+	l = min(1.0, (cmax + cmin) / 2.0);
+
+    if (cmax == cmin) {
+    h = s = 0.0; /* achromatic */
+    }
+    else 
+	{
+        float cdelta = cmax - cmin;
+        s = l > 0.5 ? cdelta / (2.0 - cmax - cmin) : cdelta / (cmax + cmin);
+        if (cmax == col.r) {
+          h = (col.g - col.b) / cdelta + (col.g < col.b ? 6.0 : 0.0);
+        }
+        else if (cmax == col.g) {
+          h = (col.b - col.r) / cdelta + 2.0;
+        }
+        else {
+          h = (col.r - col.b) / cdelta + 4.0;
+        }
+    }
+    h /= 6.0;
+
+	
+	return float3(h,s,l);
 }
-// Encodes gamma.
-float4 toGamma(float4 tex)
+
+// HSL -> RGB
+float3 hslToRGB(float3 hsl)
 {
-   return float4(pow(abs(tex.rgb), 1.0/2.2), tex.a);
+	float nr, ng, nb, chroma, h, s, l;
+	h = hsl.r;
+	s = hsl.g;
+	l = hsl.b;
+	
+	nr = abs(h * 6.0 - 3.0) - 1.0;
+	ng = 2.0 - abs(h * 6.0 - 2.0);
+	nb = 2.0 - abs(h * 6.0 - 4.0);
+	
+	nr = clamp(nr, 0.0, 1.0);
+	nb = clamp(nb, 0.0, 1.0);
+	ng = clamp(ng, 0.0, 1.0);
+
+	chroma = (1.0 - abs(2.0 * l - 1.0)) * s;
+	
+	return float3((nr - 0.5) * chroma + l, (ng - 0.5) * chroma + l, (nb - 0.5) * chroma + l);
+  
 }
+
 // Sample in linear space. Decodes gamma.
+float toLinear(float col)
+{
+	if(col < 0.04045)
+	{
+		return (col < 0.0) ? 0.0 : col * (1.0 / 12.92);
+	}
+	
+	return pow(abs(col + 0.055) * (1.0 / 1.055), 2.4);
+}
+float4 toLinear(float4 tex)
+{
+   return float4(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b), tex.a);
+}
+
 float3 toLinear(float3 tex)
 {
-   return pow(abs(tex.rgb), 2.2);
+   return float3(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b));
 }
+
 // Encodes gamma.
+float toGamma(float col)
+{
+	if(col < 0.0031308)
+	{
+		return (col < 0.0) ? 0.0 : col * 12.92;
+	}
+	
+	return 1.055 * pow(abs(col), 1.0 / 2.4) - 0.055;
+}
+
+float4 toGamma(float4 tex)
+{
+   return float4(toGamma(tex.r), toGamma(tex.g), toGamma(tex.b), tex.a);
+}
+
 float3 toGamma(float3 tex)
 {
-   return pow(abs(tex.rgb), 1.0/2.2);
+   return float3(toGamma(tex.r), toGamma(tex.g), toGamma(tex.b));
 }
 
 //