slang-shaders/misc/tonemapping.slang

178 lines
5.9 KiB
Plaintext
Raw Normal View History

2017-03-03 12:03:40 +11:00
#version 450
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float MAP1;
float MAP2;
float SPLIT_LINE;
2017-03-03 12:03:40 +11:00
} params;
#pragma parameter MAP1 "Tone Map Method Left" 0.0 0.0 7.0 1.0
#define MAP1 params.MAP1
#pragma parameter MAP2 "Tone Map Method Right" 0.0 0.0 7.0 1.0
#define MAP2 params.MAP2
#pragma parameter SPLIT_LINE "Split Location" 0.5 0.0 1.0 0.05
#define SPLIT_LINE params.SPLIT_LINE
2017-03-04 09:29:03 +11:00
// uncomment one of the following lines to divide the screen into
// sections using each tonemapping method or do splitscreen comparison
// #define HORIZ_BANDS
// #define VERT_BANDS
#define SPLITSCREEN
2017-03-03 12:03:40 +11:00
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
/*
This shader experiments the effect of different tone mapping operators.
This is still a work in progress.
More info:
http://slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting
http://filmicgames.com/archives/75
http://filmicgames.com/archives/183
http://filmicgames.com/archives/190
http://imdoingitwrong.wordpress.com/2010/08/19/why-reinhard-desaturates-my-blacks-3/
http://mynameismjp.wordpress.com/2010/04/30/a-closer-look-at-tone-mapping/
http://renderwonk.com/publications/s2010-color-course/
--
Zavie
*/
float gamma = 2.2;
vec3 linearToneMapping(vec3 color)
{
float exposure = 1.;
color = clamp(exposure * color, 0., 1.);
color = pow(color, vec3(1. / gamma));
return color;
}
vec3 simpleReinhardToneMapping(vec3 color)
{
float exposure = 1.5;
color *= exposure/(1. + color / exposure);
color = pow(color, vec3(1. / gamma));
return color;
}
vec3 lumaBasedReinhardToneMapping(vec3 color)
{
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
float toneMappedLuma = luma / (1. + luma);
color *= toneMappedLuma / luma;
color = pow(color, vec3(1. / gamma));
return color;
}
vec3 whitePreservingLumaBasedReinhardToneMapping(vec3 color)
{
float white = 2.;
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
float toneMappedLuma = luma * (1. + luma / (white*white)) / (1. + luma);
color *= toneMappedLuma / luma;
color = pow(color, vec3(1. / gamma));
return color;
}
vec3 RomBinDaHouseToneMapping(vec3 color)
{
color = exp( -1.0 / ( 2.72*color + 0.15 ) );
color = pow(color, vec3(1. / gamma));
return color;
}
vec3 filmicToneMapping(vec3 color)
{
color = max(vec3(0.), color - vec3(0.004));
color = (color * (6.2 * color + .5)) / (color * (6.2 * color + 1.7) + 0.06);
return color;
}
vec3 Uncharted2ToneMapping(vec3 color)
{
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;
float exposure = 2.;
color *= exposure;
color = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
float white = ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F)) - E / F;
color /= white;
color = pow(color, vec3(1. / gamma));
return color;
}
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord * 1.0001;
2017-03-03 12:03:40 +11:00
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
void main()
{
2017-03-03 13:01:32 +11:00
vec3 color = texture(Source, vTexCoord.xy).rgb;
2017-03-04 09:29:03 +11:00
vec4 mapped = vec4(color, 1.0);
vec4 right;
2017-03-04 09:29:03 +11:00
#ifdef HORIZ_BANDS
if (vTexCoord.x < 0.15) mapped = vec4(linearToneMapping(color), 1.0);
else if (vTexCoord.x > 0.15 && vTexCoord.x < 0.30) mapped = vec4(simpleReinhardToneMapping(color), 1.0);
else if (vTexCoord.x > 0.30 && vTexCoord.x < 0.45) mapped = vec4(lumaBasedReinhardToneMapping(color), 1.0);
else if (vTexCoord.x > 0.45 && vTexCoord.x < 0.60) mapped = vec4(whitePreservingLumaBasedReinhardToneMapping(color), 1.0);
else if (vTexCoord.x > 0.60 && vTexCoord.x < 0.75) mapped = vec4(RomBinDaHouseToneMapping(color), 1.0);
else if (vTexCoord.x > 0.75 && vTexCoord.x < 0.90) mapped = vec4(filmicToneMapping(color), 1.0);
else mapped = vec4(Uncharted2ToneMapping(color), 1.0);
2017-03-04 09:29:03 +11:00
#endif
#ifdef VERT_BANDS
if (vTexCoord.y < 0.15) mapped = vec4(linearToneMapping(color), 1.0);
else if (vTexCoord.y > 0.15 && vTexCoord.y < 0.30) mapped = vec4(simpleReinhardToneMapping(color), 1.0);
else if (vTexCoord.y > 0.30 && vTexCoord.y < 0.45) mapped = vec4(lumaBasedReinhardToneMapping(color), 1.0);
else if (vTexCoord.y > 0.45 && vTexCoord.y < 0.60) mapped = vec4(whitePreservingLumaBasedReinhardToneMapping(color), 1.0);
else if (vTexCoord.y > 0.60 && vTexCoord.y < 0.75) mapped = vec4(RomBinDaHouseToneMapping(color), 1.0);
else if (vTexCoord.y > 0.75 && vTexCoord.y < 0.90) mapped = vec4(filmicToneMapping(color), 1.0);
else mapped = vec4(Uncharted2ToneMapping(color), 1.0);
#endif
#ifdef SPLITSCREEN
if (MAP1 == 0.0) mapped = vec4(linearToneMapping(color), 1.0);
if (MAP1 == 1.0) mapped = vec4(simpleReinhardToneMapping(color), 1.0);
if (MAP1 == 2.0) mapped = vec4(lumaBasedReinhardToneMapping(color), 1.0);
if (MAP1 == 3.0) mapped = vec4(whitePreservingLumaBasedReinhardToneMapping(color), 1.0);
if (MAP1 == 4.0) mapped = vec4(RomBinDaHouseToneMapping(color), 1.0);
if (MAP1 == 5.0) mapped = vec4(filmicToneMapping(color), 1.0);
if (MAP1 == 6.0) mapped = vec4(Uncharted2ToneMapping(color), 1.0);
if (MAP1 == 7.0) mapped = vec4(color, 1.0);
if (MAP2 == 0.0) right = vec4(linearToneMapping(color), 1.0);
if (MAP2 == 1.0) right = vec4(simpleReinhardToneMapping(color), 1.0);
if (MAP2 == 2.0) right = vec4(lumaBasedReinhardToneMapping(color), 1.0);
if (MAP2 == 3.0) right = vec4(whitePreservingLumaBasedReinhardToneMapping(color), 1.0);
if (MAP2 == 4.0) right = vec4(RomBinDaHouseToneMapping(color), 1.0);
if (MAP2 == 5.0) right = vec4(filmicToneMapping(color), 1.0);
if (MAP2 == 6.0) right = vec4(Uncharted2ToneMapping(color), 1.0);
if (MAP2 == 7.0) right = vec4(color, 1.0);
2017-03-04 09:29:03 +11:00
mapped = (vTexCoord.x < SPLIT_LINE) ? mapped : right;
#endif
FragColor = mapped;
2017-03-03 12:03:40 +11:00
}