Initial Commit

This commit is contained in:
marauder2k7 2023-01-10 04:06:22 +00:00
parent 1fc7b99bd6
commit 05a2f8c4cf
13 changed files with 314 additions and 149 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
[unroll]
for (int i=0; i<KERNEL_SAMPLES; i++)
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;
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;

View file

@ -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;
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;
}
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;
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;

View file

@ -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;
[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;
}
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;
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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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 = mix(_sample.rgb, bloom.rgb, vec3(0.4));
//Apply Exposure
_sample.rgb *= TO_Exposure(_sample.rgb, exposureValue, colorFilter);

View file

@ -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 = lerp(sample.rgb, bloom.rgb, float3(0.04, 0.04, 0.04));
//Apply Exposure
sample.rgb *= TO_Exposure(sample.rgb, exposureValue, colorFilter);

View file

@ -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;

View file

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

View file

@ -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
// RGB -> HSL
vec3 rgbToHSL(vec3 col)
{
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);
}
// HSL -> RGB
vec3 hslToRGB(vec3 hsl)
{
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);
}
// 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);
}
vec4 toLinear(vec4 tex)
{
return tex;
}
// Encodes gamma.
vec4 toGamma(vec4 tex)
{
return tex;
return vec4(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b), tex.a);
}
vec3 toLinear(vec3 tex)
{
return tex;
return vec3(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b));
}
// Encodes gamma.
vec3 toGamma(vec3 tex)
float toGamma(float col)
{
return tex;
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;
}
#else
// Sample in linear space. Decodes gamma.
vec4 toLinear(vec4 tex)
{
return vec4(pow(abs(tex.rgb), vec3(2.2)), tex.a);
}
// Encodes gamma.
vec4 toGamma(vec4 tex)
{
return vec4(pow(abs(tex.rgb), vec3(1.0/2.2)), tex.a);
return vec4(toGamma(tex.r), toGamma(tex.g), toGamma(tex.b), tex.a);
}
// Sample in linear space. Decodes gamma.
vec3 toLinear(vec3 tex)
{
return pow(abs(tex), vec3(2.2));
}
// 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)
{

View file

@ -301,25 +301,98 @@ bool getFlag(float flags, int num)
return (fmod(process, pow(2, squareNum)) >= squareNum);
}
// RGB -> HSL
float3 rgbToHSL(float3 col)
{
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);
}
// HSL -> RGB
float3 hslToRGB(float3 hsl)
{
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(pow(abs(tex.rgb), 2.2), tex.a);
return float4(toLinear(tex.r),toLinear(tex.g),toLinear(tex.b), tex.a);
}
// Encodes gamma.
float4 toGamma(float4 tex)
{
return float4(pow(abs(tex.rgb), 1.0/2.2), tex.a);
}
// Sample in linear space. Decodes gamma.
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));
}
//