From ecea7f990e9800f4073e3f7da477ef81ffc0b21c Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 4 Apr 2022 12:15:15 -0400 Subject: [PATCH] Seperate exposure pass from the rest of post processing This prevents gamma-weirdness with SMAA --- engine/CMakeLists.txt | 4 +- engine/renderer/include/renderer.hpp | 1 + engine/renderer/include/rendertarget.hpp | 4 + engine/renderer/src/renderer.cpp | 283 +++++++++++++---------- engine/renderer/src/smaapass.cpp | 2 +- engine/shaders/edge.frag.glsl | 3 +- engine/shaders/expose.frag.glsl | 119 ++++++++++ engine/shaders/expose.vert.glsl | 14 ++ engine/shaders/post.frag.glsl | 108 +-------- 9 files changed, 313 insertions(+), 225 deletions(-) create mode 100644 engine/shaders/expose.frag.glsl create mode 100644 engine/shaders/expose.vert.glsl diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 2a159f4..4966162 100755 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -53,4 +53,6 @@ add_shaders(TARGET Renderer shaders/dof.vert.glsl shaders/dof.frag.glsl shaders/histogram.comp.glsl - shaders/histogram-average.comp.glsl) + shaders/histogram-average.comp.glsl + shaders/expose.frag.glsl + shaders/expose.vert.glsl) diff --git a/engine/renderer/include/renderer.hpp b/engine/renderer/include/renderer.hpp index e83f51f..a2f160e 100755 --- a/engine/renderer/include/renderer.hpp +++ b/engine/renderer/include/renderer.hpp @@ -132,6 +132,7 @@ namespace prism { GFXPipeline* sky_pipeline = nullptr; // post + GFXPipeline* expose_pipeline = nullptr; GFXPipeline* post_pipeline = nullptr; // brdf diff --git a/engine/renderer/include/rendertarget.hpp b/engine/renderer/include/rendertarget.hpp index 7919973..464733d 100755 --- a/engine/renderer/include/rendertarget.hpp +++ b/engine/renderer/include/rendertarget.hpp @@ -33,6 +33,10 @@ public: GFXFramebuffer* edge_framebuffer = nullptr; GFXFramebuffer* blend_framebuffer = nullptr; + + // intermediary + GFXTexture* mid_texture = nullptr; + GFXFramebuffer* mid_framebuffer = nullptr; // imgui GFXBuffer* vertex_buffer[RT_MAX_FRAMES_IN_FLIGHT] = {}; diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index aee5108..0896879 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -197,14 +197,6 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->pop_group(); - if (render_options.enable_aa) { - commandbuffer->push_group("SMAA"); - - smaa_pass->render(commandbuffer, target); - - commandbuffer->pop_group(); - } - if (render_options.enable_depth_of_field && dof_pass != nullptr) dof_pass->render(commandbuffer, *scene); @@ -213,94 +205,137 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->end_render_pass(); // begin auto exposure + { + commandbuffer->set_compute_pipeline(histogram_pipeline); - commandbuffer->set_compute_pipeline(histogram_pipeline); + commandbuffer->bind_texture(target.offscreenColorTexture, 0); + commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, + sizeof(uint32_t) * 256); - commandbuffer->bind_texture(target.offscreenColorTexture, 0); - commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256); + const float lum_range = + render_options.max_luminance - render_options.min_luminance; - const float lum_range = render_options.max_luminance - render_options.min_luminance; + prism::float4 params = + prism::float4(render_options.min_luminance, 1.0f / lum_range, + static_cast(render_extent.width), + static_cast(render_extent.height)); - prism::float4 params = prism::float4(render_options.min_luminance, - 1.0f / lum_range, - static_cast(render_extent.width), - static_cast(render_extent.height)); + commandbuffer->set_push_constant(¶ms, sizeof(prism::float4)); - commandbuffer->set_push_constant(¶ms, sizeof(prism::float4)); + commandbuffer->dispatch( + static_cast( + std::ceil(static_cast(render_extent.width) / 16.0f)), + static_cast( + std::ceil(static_cast(render_extent.height) / 16.0f)), + 1); - commandbuffer->dispatch(static_cast(std::ceil(static_cast(render_extent.width) / 16.0f)), - static_cast(std::ceil(static_cast(render_extent.height) / 16.0f)), 1); + commandbuffer->set_compute_pipeline(histogram_average_pipeline); - commandbuffer->set_compute_pipeline(histogram_average_pipeline); + commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, + sizeof(uint32_t) * 256); - commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256); + params = prism::float4( + render_options.min_luminance, lum_range, + std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), + static_cast(render_extent.width * render_extent.height)); - params = prism::float4(render_options.min_luminance, - lum_range, - std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), - static_cast(render_extent.width * render_extent.height)); + commandbuffer->set_push_constant(¶ms, sizeof(prism::float4)); - commandbuffer->set_push_constant(¶ms, sizeof(prism::float4)); + commandbuffer->bind_texture(average_luminance_texture, 0); - commandbuffer->bind_texture(average_luminance_texture, 0); - - commandbuffer->dispatch(1, 1, 1); - - // continue post processing - beginInfo.framebuffer = nullptr; - beginInfo.render_pass = nullptr; - - commandbuffer->set_render_pass(beginInfo); - - Viewport viewport = {}; - viewport.width = static_cast(render_extent.width); - viewport.height = static_cast(render_extent.height); - - commandbuffer->set_viewport(viewport); - - commandbuffer->set_graphics_pipeline(post_pipeline); - - if (render_options.enable_depth_of_field) - commandbuffer->bind_texture(dof_pass->normal_field, 1); - else - commandbuffer->bind_texture(target.offscreenColorTexture, 1); - - if (render_options.enable_aa) { - commandbuffer->bind_texture(target.blend_texture, 3); - } else { - commandbuffer->bind_texture(dummy_texture, 3); + commandbuffer->dispatch(1, 1, 1); } - - if(auto texture = get_requested_texture(PassTextureType::SelectionSobel)) - commandbuffer->bind_texture(texture, 5); - else - commandbuffer->bind_texture(dummy_texture, 5); - - commandbuffer->bind_texture(average_luminance_texture, 6); - - if(render_options.enable_depth_of_field) - commandbuffer->bind_texture(dof_pass->far_field, 7); - else - commandbuffer->bind_texture(dummy_texture, 7); PostPushConstants pc; pc.options.x = render_options.enable_aa; pc.options.z = render_options.exposure; - + if(render_options.enable_depth_of_field) pc.options.w = 2; - + pc.transform_ops.x = static_cast(render_options.display_color_space); pc.transform_ops.y = static_cast(render_options.tonemapping); - + const auto [width, height] = render_extent; pc.viewport = prism::float4(1.0f / static_cast(width), 1.0f / static_cast(height), static_cast(width), static_cast(height)); - - commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants)); - - commandbuffer->draw(0, 4, 0, 1); - commandbuffer->pop_group(); + // continue post processing + // first we want to manually "expose" the scene, otherwise AA wouldn't work properly + { + beginInfo.framebuffer = target.mid_framebuffer; + beginInfo.render_pass = unorm_render_pass; + + commandbuffer->set_render_pass(beginInfo); + + Viewport viewport = {}; + viewport.width = static_cast(render_extent.width); + viewport.height = static_cast(render_extent.height); + + commandbuffer->set_viewport(viewport); + + commandbuffer->set_graphics_pipeline(expose_pipeline); + + commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants)); + + if (render_options.enable_depth_of_field) + commandbuffer->bind_texture(dof_pass->normal_field, 1); + else + commandbuffer->bind_texture(target.offscreenColorTexture, 1); + + commandbuffer->bind_texture(average_luminance_texture, 6); + + if(render_options.enable_depth_of_field) + commandbuffer->bind_texture(dof_pass->far_field, 7); + else + commandbuffer->bind_texture(dummy_texture, 7); + + commandbuffer->draw(0, 4, 0, 1); + + commandbuffer->end_render_pass(); + } + + if (render_options.enable_aa) { + commandbuffer->push_group("SMAA"); + + smaa_pass->render(commandbuffer, target); + + commandbuffer->pop_group(); + } + + // now we overlay sobel, and perform smaa + { + beginInfo.framebuffer = nullptr; + beginInfo.render_pass = nullptr; + + commandbuffer->set_render_pass(beginInfo); + + Viewport viewport = {}; + viewport.width = static_cast(render_extent.width); + viewport.height = static_cast(render_extent.height); + + commandbuffer->set_viewport(viewport); + + commandbuffer->set_graphics_pipeline(post_pipeline); + + commandbuffer->bind_texture(target.mid_texture, 1); + + if (render_options.enable_aa) { + commandbuffer->bind_texture(target.blend_texture, 3); + } else { + commandbuffer->bind_texture(dummy_texture, 3); + } + + if(auto texture = get_requested_texture(PassTextureType::SelectionSobel)) + commandbuffer->bind_texture(texture, 5); + else + commandbuffer->bind_texture(dummy_texture, 5); + + commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants)); + + commandbuffer->draw(0, 4, 0, 1); + + commandbuffer->pop_group(); + } commandbuffer->push_group("Extra Passes"); @@ -549,52 +584,51 @@ void renderer::create_dummy_texture() { void renderer::create_render_target_resources(RenderTarget& target) { const auto extent = target.get_render_extent(); - - GFXTextureCreateInfo textureInfo = {}; - textureInfo.label = "Offscreen Color"; - textureInfo.width = extent.width; - textureInfo.height = extent.height; - textureInfo.format = GFXPixelFormat::RGBA_32F; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | GFXTextureUsage::Storage; - textureInfo.samplingMode = SamplingMode::ClampToEdge; - target.offscreenColorTexture = gfx->create_texture(textureInfo); + // offscreen + { + GFXTextureCreateInfo textureInfo = {}; + textureInfo.label = "Offscreen Color"; + textureInfo.width = extent.width; + textureInfo.height = extent.height; + textureInfo.format = GFXPixelFormat::RGBA_32F; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | + GFXTextureUsage::Storage; + textureInfo.samplingMode = SamplingMode::ClampToEdge; - textureInfo.label = "Offscreen Depth"; - textureInfo.format = GFXPixelFormat::DEPTH_32F; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; + target.offscreenColorTexture = gfx->create_texture(textureInfo); - target.offscreenDepthTexture = gfx->create_texture(textureInfo); + textureInfo.label = "Offscreen Depth"; + textureInfo.format = GFXPixelFormat::DEPTH_32F; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; - GFXFramebufferCreateInfo framebufferInfo = {}; - framebufferInfo.render_pass = offscreen_render_pass; - framebufferInfo.attachments.push_back(target.offscreenColorTexture); - framebufferInfo.attachments.push_back(target.offscreenDepthTexture); + target.offscreenDepthTexture = gfx->create_texture(textureInfo); - target.offscreenFramebuffer = gfx->create_framebuffer(framebufferInfo); - - if(post_pipeline == nullptr) { - GFXGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.label = "Post"; - - pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("post.vert")); - pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("post.frag")); - - pipelineInfo.shader_input.bindings = { - {4, GFXBindingType::PushConstant}, - {1, GFXBindingType::Texture}, - {2, GFXBindingType::Texture}, - {3, GFXBindingType::Texture}, - {5, GFXBindingType::Texture}, - {6, GFXBindingType::Texture}, - {7, GFXBindingType::Texture} - }; - - pipelineInfo.shader_input.push_constants = { - {sizeof(PostPushConstants), 0} - }; + GFXFramebufferCreateInfo framebufferInfo = {}; + framebufferInfo.render_pass = offscreen_render_pass; + framebufferInfo.attachments.push_back(target.offscreenColorTexture); + framebufferInfo.attachments.push_back(target.offscreenDepthTexture); - post_pipeline = gfx->create_graphics_pipeline(pipelineInfo); + target.offscreenFramebuffer = gfx->create_framebuffer(framebufferInfo); + } + + // mid + { + GFXTextureCreateInfo textureInfo = {}; + textureInfo.label = "Mid Color"; + textureInfo.width = extent.width; + textureInfo.height = extent.height; + textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; + textureInfo.samplingMode = SamplingMode::ClampToEdge; + + target.mid_texture = gfx->create_texture(textureInfo); + + GFXFramebufferCreateInfo framebufferInfo = {}; + framebufferInfo.render_pass = unorm_render_pass; + framebufferInfo.attachments.push_back(target.mid_texture); + + target.mid_framebuffer = gfx->create_framebuffer(framebufferInfo); } target.sceneBuffer = gfx->create_buffer(nullptr, sizeof(SceneInformation), true, GFXBufferUsage::Storage); @@ -609,12 +643,9 @@ void renderer::create_post_pipelines() { pipelineInfo.shader_input.bindings = { {4, GFXBindingType::PushConstant}, - {1, GFXBindingType::Texture}, - {2, GFXBindingType::Texture}, - {3, GFXBindingType::Texture}, - {5, GFXBindingType::Texture}, - {6, GFXBindingType::Texture}, - {7, GFXBindingType::Texture} + {1, GFXBindingType::Texture}, // colorSampler + {3, GFXBindingType::Texture}, // blendSampler + {5, GFXBindingType::Texture} // sobelSampler }; pipelineInfo.shader_input.push_constants = { @@ -622,6 +653,20 @@ void renderer::create_post_pipelines() { }; post_pipeline = gfx->create_graphics_pipeline(pipelineInfo); + + pipelineInfo.label = "Expose"; + pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("expose.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("expose.frag")); + pipelineInfo.render_pass = unorm_render_pass; + + pipelineInfo.shader_input.bindings = { + {4, GFXBindingType::PushConstant}, + {1, GFXBindingType::Texture}, // colorSampler + {6, GFXBindingType::Texture}, // averageLuminanceSampler + {7, GFXBindingType::Texture} // farFieldSampler + }; + + expose_pipeline = gfx->create_graphics_pipeline(pipelineInfo); } void renderer::create_sky_pipeline() { diff --git a/engine/renderer/src/smaapass.cpp b/engine/renderer/src/smaapass.cpp index 8ddf9c7..2f42e06 100755 --- a/engine/renderer/src/smaapass.cpp +++ b/engine/renderer/src/smaapass.cpp @@ -68,7 +68,7 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) { command_buffer->set_graphics_pipeline(edge_pipeline); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - command_buffer->bind_texture(target.offscreenColorTexture, 0); // color + command_buffer->bind_texture(target.mid_texture, 0); // color command_buffer->bind_texture(target.offscreenDepthTexture, 1); // depth command_buffer->draw(0, 3, 0, 1); diff --git a/engine/shaders/edge.frag.glsl b/engine/shaders/edge.frag.glsl index 5f58c5f..255a97b 100644 --- a/engine/shaders/edge.frag.glsl +++ b/engine/shaders/edge.frag.glsl @@ -10,7 +10,8 @@ layout(binding = 0) uniform sampler2D imageSampler; layout(binding = 1) uniform sampler2D depthSampler; void main() { - vec2 edge = SMAALumaEdgeDetectionPS(inUV, inOffset, imageSampler, depthSampler); + //vec2 edge = SMAALumaEdgeDetectionPS(inUV, inOffset, imageSampler, depthSampler); + vec2 edge = SMAADepthEdgeDetectionPS(inUV, inOffset, depthSampler); outColor = vec4(edge, 0.0, 1.0); } diff --git a/engine/shaders/expose.frag.glsl b/engine/shaders/expose.frag.glsl new file mode 100644 index 0000000..600b72a --- /dev/null +++ b/engine/shaders/expose.frag.glsl @@ -0,0 +1,119 @@ +layout(push_constant) uniform PushConstant { + vec4 viewport; + vec4 options; + vec4 transform_ops; +}; + +#include "common.nocompile.glsl" + +layout (location = 0) in vec2 inUV; +layout(location = 1) in vec4 inOffset; + +layout (location = 0) out vec4 outColor; + +layout (binding = 1) uniform sampler2D colorSampler; +layout (binding = 6) uniform sampler2D averageLuminanceSampler; +layout (binding = 7) uniform sampler2D farFieldSampler; + +// adapted from https://bruop.github.io/exposure/ + +vec3 convertRGB2XYZ(vec3 _rgb) +{ + // Reference: + // RGB/XYZ Matrices + // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + vec3 xyz; + xyz.x = dot(vec3(0.4124564, 0.3575761, 0.1804375), _rgb); + xyz.y = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb); + xyz.z = dot(vec3(0.0193339, 0.1191920, 0.9503041), _rgb); + return xyz; +} + +vec3 convertXYZ2RGB(vec3 _xyz) +{ + vec3 rgb; + rgb.x = dot(vec3( 3.2404542, -1.5371385, -0.4985314), _xyz); + rgb.y = dot(vec3(-0.9692660, 1.8760108, 0.0415560), _xyz); + rgb.z = dot(vec3( 0.0556434, -0.2040259, 1.0572252), _xyz); + return rgb; +} + +vec3 convertXYZ2Yxy(vec3 _xyz) +{ + // Reference: + // http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html + float inv = 1.0/dot(_xyz, vec3(1.0, 1.0, 1.0) ); + return vec3(_xyz.y, _xyz.x*inv, _xyz.y*inv); +} + +vec3 convertYxy2XYZ(vec3 _Yxy) +{ + // Reference: + // http://www.brucelindbloom.com/index.html?Eqn_xyY_to_XYZ.html + vec3 xyz; + xyz.x = _Yxy.x*_Yxy.y/_Yxy.z; + xyz.y = _Yxy.x; + xyz.z = _Yxy.x*(1.0 - _Yxy.y - _Yxy.z)/_Yxy.z; + return xyz; +} + +vec3 convertRGB2Yxy(vec3 _rgb) +{ + return convertXYZ2Yxy(convertRGB2XYZ(_rgb) ); +} + +vec3 convertYxy2RGB(vec3 _Yxy) +{ + return convertXYZ2RGB(convertYxy2XYZ(_Yxy) ); +} + +float reinhard2(float _x, float _whiteSqr) +{ + return (_x * (1.0 + _x/_whiteSqr) ) / (1.0 + _x); +} + +void main() { + // passthrough + if(options.w == 1) { + outColor = texture(colorSampler, inUV); + return; + } + + bool enable_dof = options.w == 2; + vec3 sceneColor = vec3(0); + if(enable_dof) { + sceneColor = texture(farFieldSampler, inUV).rgb; + sceneColor += texture(colorSampler, inUV).rgb; + } else { + sceneColor = texture(colorSampler, inUV).rgb; + } + + vec3 hdrColor = sceneColor; // fading removed + + float avg_lum = texture(averageLuminanceSampler, inUV).r; + + vec3 transformed_color = hdrColor; + + if(transform_ops.y == 1) { + transformed_color = vec3(1.0) - exp(-transformed_color * options.z); + } else if(transform_ops.y == 2) { + vec3 Yxy = convertRGB2Yxy(transformed_color); + + // hard-coded for now + float whitePoint = 4.0; + + float lp = Yxy.x / (9.6 * avg_lum + 0.0001); + + // Replace this line with other tone mapping functions + // Here we applying the curve to the luminance exclusively + Yxy.x = reinhard2(lp, whitePoint); + + transformed_color = convertYxy2RGB(Yxy); + } + + if(transform_ops.x == 1) { + transformed_color = from_linear_to_srgb(transformed_color); + } + + outColor = vec4(transformed_color, 1.0); +} diff --git a/engine/shaders/expose.vert.glsl b/engine/shaders/expose.vert.glsl new file mode 100644 index 0000000..aa448ad --- /dev/null +++ b/engine/shaders/expose.vert.glsl @@ -0,0 +1,14 @@ +layout(push_constant) uniform readonlPushConstant { + vec4 viewport; + float fade; + vec4 transform_ops; +}; + +layout (location = 0) out vec2 outUV; +layout(location = 1) out vec4 outOffset; + +void main() { + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f); + outUV.y = 1.0 - outUV.y; +} diff --git a/engine/shaders/post.frag.glsl b/engine/shaders/post.frag.glsl index 36e1d4a..92313a2 100644 --- a/engine/shaders/post.frag.glsl +++ b/engine/shaders/post.frag.glsl @@ -20,11 +20,8 @@ layout(location = 1) in vec4 inOffset; layout (location = 0) out vec4 outColor; layout (binding = 1) uniform sampler2D colorSampler; -layout (binding = 2) uniform sampler2D backSampler; layout (binding = 3) uniform sampler2D blendSampler; layout (binding = 5) uniform sampler2D sobelSampler; -layout (binding = 6) uniform sampler2D averageLuminanceSampler; -layout (binding = 7) uniform sampler2D farFieldSampler; float calculate_sobel() { float x = 1.0 / viewport.z; @@ -46,81 +43,13 @@ float calculate_sobel() { return sqrt((horizEdge.rgb * horizEdge.rgb) + (vertEdge.rgb * vertEdge.rgb)).r; } -// adapted from https://bruop.github.io/exposure/ - -vec3 convertRGB2XYZ(vec3 _rgb) -{ - // Reference: - // RGB/XYZ Matrices - // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html - vec3 xyz; - xyz.x = dot(vec3(0.4124564, 0.3575761, 0.1804375), _rgb); - xyz.y = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb); - xyz.z = dot(vec3(0.0193339, 0.1191920, 0.9503041), _rgb); - return xyz; -} - -vec3 convertXYZ2RGB(vec3 _xyz) -{ - vec3 rgb; - rgb.x = dot(vec3( 3.2404542, -1.5371385, -0.4985314), _xyz); - rgb.y = dot(vec3(-0.9692660, 1.8760108, 0.0415560), _xyz); - rgb.z = dot(vec3( 0.0556434, -0.2040259, 1.0572252), _xyz); - return rgb; -} - -vec3 convertXYZ2Yxy(vec3 _xyz) -{ - // Reference: - // http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html - float inv = 1.0/dot(_xyz, vec3(1.0, 1.0, 1.0) ); - return vec3(_xyz.y, _xyz.x*inv, _xyz.y*inv); -} - -vec3 convertYxy2XYZ(vec3 _Yxy) -{ - // Reference: - // http://www.brucelindbloom.com/index.html?Eqn_xyY_to_XYZ.html - vec3 xyz; - xyz.x = _Yxy.x*_Yxy.y/_Yxy.z; - xyz.y = _Yxy.x; - xyz.z = _Yxy.x*(1.0 - _Yxy.y - _Yxy.z)/_Yxy.z; - return xyz; -} - -vec3 convertRGB2Yxy(vec3 _rgb) -{ - return convertXYZ2Yxy(convertRGB2XYZ(_rgb) ); -} - -vec3 convertYxy2RGB(vec3 _Yxy) -{ - return convertXYZ2RGB(convertYxy2XYZ(_Yxy) ); -} - -float reinhard2(float _x, float _whiteSqr) -{ - return (_x * (1.0 + _x/_whiteSqr) ) / (1.0 + _x); -} - void main() { - // passthrough - if(options.w == 1) { - outColor = texture(colorSampler, inUV); - return; - } - bool enable_dof = options.w == 2; vec3 sceneColor = vec3(0); - if(enable_dof) { - sceneColor = texture(farFieldSampler, inUV).rgb; - sceneColor += texture(colorSampler, inUV).rgb; - } else { - if(options.x == 1) // enable AA - sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, colorSampler, blendSampler).rgb; - else - sceneColor = texture(colorSampler, inUV).rgb; - } + if(options.x == 1) // enable AA + sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, colorSampler, blendSampler).rgb; + else + sceneColor = texture(colorSampler, inUV).rgb; float sobel = 0.0; if(textureSize(sobelSampler, 0).x > 1) @@ -128,32 +57,5 @@ void main() { vec3 sobelColor = vec3(0, 1, 1); - vec3 hdrColor = sceneColor; // fading removed - - float avg_lum = texture(averageLuminanceSampler, inUV).r; - - vec3 transformed_color = hdrColor; - - if(transform_ops.y == 1) { - transformed_color = vec3(1.0) - exp(-transformed_color * options.z); - } else if(transform_ops.y == 2) { - vec3 Yxy = convertRGB2Yxy(transformed_color); - - // hard-coded for now - float whitePoint = 4.0; - - float lp = Yxy.x / (9.6 * avg_lum + 0.0001); - - // Replace this line with other tone mapping functions - // Here we applying the curve to the luminance exclusively - Yxy.x = reinhard2(lp, whitePoint); - - transformed_color = convertYxy2RGB(Yxy); - } - - if(transform_ops.x == 1) { - transformed_color = from_linear_to_srgb(transformed_color); - } - - outColor = vec4(transformed_color + (sobelColor * sobel), 1.0); + outColor = vec4(sceneColor + (sobelColor * sobel), 1.0); }