Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
kabergstrom committed Mar 28, 2021
1 parent c0af53b commit 4b649b6
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 154 deletions.
Binary file modified demo/assets/shaders/bloom_combine.frag.cookedshaderpackage
Binary file not shown.
85 changes: 42 additions & 43 deletions demo/shaders/generated_msl/bloom_combine.frag.metal
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static inline __attribute__((always_inline))
float3 visualize_value(thread const float& val)
{
float g = 1.0 - ((0.20000000298023223876953125 * (val - 3.2360498905181884765625)) * (val - 3.2360498905181884765625));
float b = 1.0 - ((1.0 * (val - 1.0)) * (val - 1.0));
float b = val;
float r = 1.0 - (1.0 / ((0.5 * val) - 0.5));
if (val > 1.0)
{
Expand All @@ -80,55 +80,54 @@ float luma(thread const float3& color)
return dot(color, float3(0.2989999949932098388671875, 0.58700001239776611328125, 0.114000000059604644775390625));
}

fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
static inline __attribute__((always_inline))
float3 tonemap(thread const float3& color, thread const int& tonemapper_type)
{
constexpr sampler smp(mip_filter::linear, compare_func::never, max_anisotropy(1));
main0_out out = {};
float4 color = spvDescriptorSet0.in_color.sample(smp, in.inUV) + spvDescriptorSet0.in_blur.sample(smp, in.inUV);
if ((*spvDescriptorSet0.config).tonemapper_type == 1)
switch (tonemapper_type)
{
float3 param = color.xyz;
float3 _227 = tonemap_aces_fitted(param);
out.out_sdr = float4(_227, color.w);
}
else
{
if ((*spvDescriptorSet0.config).tonemapper_type == 2)
case 1:
{
float3 param = color;
float3 _196 = tonemap_aces_fitted(param);
return _196;
}
case 2:
{
float3 param_1 = color;
return tonemap_aces_film_simple(param_1);
}
case 3:
{
float3 param_1 = color.xyz;
out.out_sdr = float4(tonemap_aces_film_simple(param_1), color.w);
return color / (color + float3(1.0));
}
else
case 4:
{
if ((*spvDescriptorSet0.config).tonemapper_type == 3)
{
out.out_sdr = float4(color.xyz / (color.xyz + float3(1.0)), color.w);
}
else
{
if ((*spvDescriptorSet0.config).tonemapper_type == 4)
{
float max_val = fast::max(color.x, fast::max(color.y, color.z));
float param_2 = max_val;
out.out_sdr = float4(visualize_value(param_2), color.w);
}
else
{
if ((*spvDescriptorSet0.config).tonemapper_type == 5)
{
float3 param_3 = color.xyz;
float l = luma(param_3);
float param_4 = l;
out.out_sdr = float4(visualize_value(param_4), color.w);
}
else
{
out.out_sdr = color;
}
}
}
float max_val = fast::max(color.x, fast::max(color.y, color.z));
float param_2 = max_val;
return visualize_value(param_2);
}
case 5:
{
float3 param_3 = color;
float l = luma(param_3);
float param_4 = l;
return visualize_value(param_4);
}
default:
{
return color;
}
}
}

fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
constexpr sampler smp(mip_filter::linear, compare_func::never, max_anisotropy(1));
main0_out out = {};
float4 color = spvDescriptorSet0.in_color.sample(smp, in.inUV) + spvDescriptorSet0.in_blur.sample(smp, in.inUV);
float3 param = color.xyz;
int param_1 = (*spvDescriptorSet0.config).tonemapper_type;
out.out_sdr = float4(tonemap(param, param_1), color.w);
return out;
}

92 changes: 2 additions & 90 deletions demo/shaders/glsl/bloom_combine.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#include "tonemapping.glsl"

// @[export]
layout (set = 0, binding = 0) uniform texture2D in_color;
Expand Down Expand Up @@ -29,99 +30,10 @@ layout (location = 0) in vec2 inUV;

layout (location = 0) out vec4 out_sdr;

// The code for ACESFitted was originally written by Stephen Hill (@self_shadow), who deserves all
// credit for coming up with this fit and implementing it. Buy him a beer next time you see him. :)
// The code is licensed under the MIT license

// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
const mat3 ACESInputMat =
{
{0.59719, 0.35458, 0.04823},
{0.07600, 0.90834, 0.01566},
{0.02840, 0.13383, 0.83777}
};

// ODT_SAT => XYZ => D60_2_D65 => sRGB
const mat3 ACESOutputMat =
{
{ 1.60475, -0.53108, -0.07367},
{-0.10208, 1.10813, -0.00605},
{-0.00327, -0.07276, 1.07602}
};

vec3 RRT_and_ODT_fit(vec3 v)
{
vec3 a = v * (v + 0.0245786f) - 0.000090537f;
vec3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f;
return a / b;
}

vec3 tonemap_aces_fitted(vec3 color)
{
color = ACESInputMat * color;

// Apply RRT and ODT
color = RRT_and_ODT_fit(color);

color = ACESOutputMat * color;

// Clamp to [0, 1]
color = clamp(color, 0, 1);

return color;
}

// source: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
vec3 tonemap_aces_film_simple(vec3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
}

float luma(vec3 color) {
return dot(color, vec3(0.299, 0.587, 0.114));
}

vec3 visualize_value(float val) {
// parabolic curves visualize the range
// blue is used to visualize 0-1 exclusively
// green covers 0-5
// red is 3+
float g = 1 - 0.2 * (val - 3.23605) * (val - 3.23605);
float b = 1 - 1 * (val - 1) * (val - 1);
float r = 1 - 1 / (0.5 * val - 0.5);
if (val > 1.0) {
b = 0;
}
if (val < 3.0) {
r = 0;
}
return clamp(vec3(r, g, b), 0, 1);
}

void main()
{
vec4 color = texture(sampler2D(in_color, smp), inUV) + texture(sampler2D(in_blur, smp), inUV);

// tonemapping.. TODO: implement auto-exposure
if (config.tonemapper_type == 1) {
out_sdr = vec4(tonemap_aces_fitted(color.rgb), color.a);
} else if (config.tonemapper_type == 2) {
out_sdr = vec4(tonemap_aces_film_simple(color.rgb), color.a);
} else if (config.tonemapper_type == 3) {
out_sdr = vec4(color.rgb / (color.rgb + vec3(1.0)), color.a);
} else if (config.tonemapper_type == 4) {
float max_val = max(color.r, max(color.g, color.b));
out_sdr = vec4(visualize_value(max_val), color.a);
} else if (config.tonemapper_type == 5) {
float l = luma(color.rgb);
out_sdr = vec4(visualize_value(l), color.a);
} else {
out_sdr = color;
}
// out_sdr = vec4(mapped, color.a);
out_sdr = vec4(tonemap(color.rgb, config.tonemapper_type), color.a);
}
107 changes: 107 additions & 0 deletions demo/shaders/glsl/tonemapping.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// The code for ACESFitted was originally written by Stephen Hill (@self_shadow), who deserves all
// credit for coming up with this fit and implementing it. Buy him a beer next time you see him. :)
// The code is licensed under the MIT license. The code has been converted to glsl, and was originally found at:
// https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl

// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
const mat3 ACESInputMat =
{
{0.59719, 0.35458, 0.04823},
{0.07600, 0.90834, 0.01566},
{0.02840, 0.13383, 0.83777}
};

// ODT_SAT => XYZ => D60_2_D65 => sRGB
const mat3 ACESOutputMat =
{
{ 1.60475, -0.53108, -0.07367},
{-0.10208, 1.10813, -0.00605},
{-0.00327, -0.07276, 1.07602}
};

vec3 RRT_and_ODT_fit(vec3 v)
{
vec3 a = v * (v + 0.0245786f) - 0.000090537f;
vec3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f;
return a / b;
}

vec3 tonemap_aces_fitted(vec3 color)
{
color = ACESInputMat * color;

// Apply RRT and ODT
color = RRT_and_ODT_fit(color);

color = ACESOutputMat * color;

// Clamp to [0, 1]
color = clamp(color, 0, 1);

return color;
}

// source: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
vec3 tonemap_aces_film_simple(vec3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
}

float luma(vec3 color) {
return dot(color, vec3(0.299, 0.587, 0.114));
}

vec3 visualize_value(float val) {
// blue is used to visualize 0-1 exclusively in a linear fashion.
// green covers 0-5 and is a parabolic curve, so it transitions over into red.
// red is 3+ and is a log-ish curve so that it can handle differences in very large values
float g = 1 - 0.2 * (val - 3.23605) * (val - 3.23605);
float b = val;
float r = 1 - 1 / (0.5 * val - 0.5);
// the transition blue -> green is hard, to make it easier to spot when values go over 1
if (val > 1.0) {
b = 0;
}
if (val < 3.0) {
r = 0;
}
return clamp(vec3(r, g, b), 0, 1);
}

// Should be kept in sync with the constants in TonemapperType
const int TM_StephenHillACES = 1;
const int TM_SimplifiedLumaACES = 2;
const int TM_LogDerivative = 3;
const int TM_VisualizeRGBMax = 4;
const int TM_VisualizeLuma = 5;

vec3 tonemap(vec3 color, int tonemapper_type) {
// tonemapping.. TODO: implement auto-exposure
switch (tonemapper_type) {
case TM_StephenHillACES: {
return tonemap_aces_fitted(color.rgb);
} break;
case TM_SimplifiedLumaACES: {
return tonemap_aces_film_simple(color.rgb);
} break;
case TM_LogDerivative: {
return color.rgb / (color.rgb + vec3(1.0));
} break;
case TM_VisualizeRGBMax: {
float max_val = max(color.r, max(color.g, color.b));
return visualize_value(max_val);
} break;
case TM_VisualizeLuma: {
float l = luma(color.rgb);
return visualize_value(l);
} break;
default: {
return color;
} break;
}
}
Loading

0 comments on commit 4b649b6

Please sign in to comment.