From 8f652f8b7d73267295f851a50381620f411284e5 Mon Sep 17 00:00:00 2001 From: redstrate <54911369+redstrate@users.noreply.github.com> Date: Wed, 19 Aug 2020 22:09:32 -0400 Subject: [PATCH] Fix SRGB handling, now converting from srgb->linear properly --- engine/asset/include/material_nodes.hpp | 2 +- engine/renderer/src/materialcompiler.cpp | 3 ++- engine/renderer/src/renderer.cpp | 2 +- engine/renderer/src/scenecapture.cpp | 8 +------- engine/utility/include/utility.hpp | 15 +++++++++++++++ shaders/common.nocompile.glsl | 16 ++++++++++++++++ shaders/post.frag.glsl | 3 ++- shaders/sky.frag.glsl | 3 +-- 8 files changed, 39 insertions(+), 13 deletions(-) diff --git a/engine/asset/include/material_nodes.hpp b/engine/asset/include/material_nodes.hpp index 1157c4d..e7d58d9 100644 --- a/engine/asset/include/material_nodes.hpp +++ b/engine/asset/include/material_nodes.hpp @@ -159,7 +159,7 @@ public: } std::string get_glsl() override { - std::string glsl = "vec3 final_diffuse_color = Color;\n \ + std::string glsl = "vec3 final_diffuse_color = from_srgb_to_linear(Color);\n \ float final_roughness = Roughness;\n \ float final_metallic = Metallic;\n"; diff --git a/engine/renderer/src/materialcompiler.cpp b/engine/renderer/src/materialcompiler.cpp index 840f318..40a4dbf 100755 --- a/engine/renderer/src/materialcompiler.cpp +++ b/engine/renderer/src/materialcompiler.cpp @@ -294,12 +294,13 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo if(use_ibl) { src += "vec3 ibl(const int probe, const ComputedSurfaceInfo surface_info, const float intensity) {\n \ + const vec3 F = fresnel_schlick_roughness(surface_info.NdotV, surface_info.F0, surface_info.roughness);\n \ const vec3 R = get_reflect(probe, surface_info.N);\n \ const vec2 brdf = texture(brdfSampler, vec2(surface_info.NdotV, surface_info.roughness)).rg; \n \ const vec3 sampledIrradiance = texture(irrandianceSampler, vec4(surface_info.N, probe)).xyz;\n \ const vec3 prefilteredColor = textureLod(prefilterSampler, vec4(R, probe), surface_info.roughness * 4).xyz;\n \ const vec3 diffuse = sampledIrradiance * surface_info.diffuse_color;\n \ - const vec3 specular = prefilteredColor * (surface_info.F0 * brdf.x + 1.0 * brdf.y);\n \ + const vec3 specular = prefilteredColor * (F * brdf.x + brdf.y);\n \ return (diffuse + specular) * intensity;\n \ }\n"; } diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index b7ba23b..cbd5bc6 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -360,7 +360,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj Vector3 front = Vector3(0.0f, 0.0f, 1.0f) * scene.get(obj).rotation; sl.directionPower = Vector4(-front, light.power); - sl.colorSize = Vector4(light.color, radians(light.spot_size)); + sl.colorSize = Vector4(utility::from_srgb_to_linear(light.color), radians(light.spot_size)); sl.shadowsEnable = Vector4(light.enable_shadows, radians(light.size), 0, 0); sceneInfo.lights[sceneInfo.numLights++] = sl; diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index bbde600..fbde94d 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -165,7 +165,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { Vector3 front = Vector3(0.0f, 0.0f, 1.0f) * scene->get(obj).rotation; sl.directionPower = Vector4(-front, light.power); - sl.colorSize = Vector4(light.color, radians(light.spot_size)); + sl.colorSize = Vector4(utility::from_srgb_to_linear(light.color), radians(light.spot_size)); sl.shadowsEnable = Vector4(light.enable_shadows, radians(light.size), 0, 0); sceneInfo.lights[sceneInfo.numLights++] = sl; @@ -191,12 +191,6 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { engine->get_renderer()->create_mesh_pipeline(*material.handle); if(!material_indices.count(material.handle)) { - // unused for now - /*sceneInfo.materials[numMaterialsInBuffer].color = material->base_color; - sceneInfo.materials[numMaterialsInBuffer].info[0] = material->metallic; - sceneInfo.materials[numMaterialsInBuffer].info[1] = material->roughness; - sceneInfo.materials[numMaterialsInBuffer].info[2] = radians(material->hue_shift);*/ - material_indices[material.handle] = numMaterialsInBuffer++; } } diff --git a/engine/utility/include/utility.hpp b/engine/utility/include/utility.hpp index a897613..adfddff 100755 --- a/engine/utility/include/utility.hpp +++ b/engine/utility/include/utility.hpp @@ -7,6 +7,8 @@ #include #include +#include "vector.hpp" + namespace utility { template std::string enum_to_string(const Enum e) { @@ -95,4 +97,17 @@ namespace utility { inline uint16_t to_fixed(const float f) { return static_cast(32.0f * f + 0.5f); } + + inline Vector3 from_srgb_to_linear(const Vector3 sRGB) { + Vector3 linear = sRGB; + for(auto& component : linear.data) { + if(component > 0.04045f) { + component = std::powf((component + 0.055) / (1.055), 2.4f); + } else if (component <= 0.04045) { + component /= 12.92f; + } + } + + return linear; + } } diff --git a/shaders/common.nocompile.glsl b/shaders/common.nocompile.glsl index a3fefec..6d5ea8f 100755 --- a/shaders/common.nocompile.glsl +++ b/shaders/common.nocompile.glsl @@ -142,3 +142,19 @@ vec3 importance_sample_ggx(const vec2 Xi, const vec3 N, const float roughness) { return normalize(tangent * H.x + bitangent * H.y + N * H.z); } + +vec3 from_linear_to_srgb(const vec3 linearRGB) { + bvec3 cutoff = lessThan(linearRGB, vec3(0.0031308)); + vec3 higher = vec3(1.055)*pow(linearRGB, vec3(1.0/2.4)) - vec3(0.055); + vec3 lower = linearRGB * vec3(12.92); + + return mix(higher, lower, cutoff); +} + +vec3 from_srgb_to_linear(const vec3 sRGB) { + bvec3 cutoff = lessThan(sRGB, vec3(0.04045)); + vec3 higher = pow((sRGB + vec3(0.055))/vec3(1.055), vec3(2.4)); + vec3 lower = sRGB/vec3(12.92); + + return mix(higher, lower, cutoff); +} \ No newline at end of file diff --git a/shaders/post.frag.glsl b/shaders/post.frag.glsl index 92bddc1..32343a7 100755 --- a/shaders/post.frag.glsl +++ b/shaders/post.frag.glsl @@ -11,6 +11,7 @@ layout(std430, push_constant, binding = 4) uniform PushConstant { }; #include "smaa.glsl" +#include "common.nocompile.glsl" layout (location = 0) in vec2 inUV; layout(location = 1) in vec4 inOffset; @@ -63,5 +64,5 @@ void main() { vec3 hdrColor = sceneColor; // fading removed hdrColor = vec3(1.0) - exp(-hdrColor * options.z); // exposure - outColor = vec4(hdrColor + (sobelColor * sobel), 1.0); + outColor = vec4(from_linear_to_srgb(hdrColor) + (sobelColor * sobel), 1.0); } diff --git a/shaders/sky.frag.glsl b/shaders/sky.frag.glsl index 3b3027a..3b8e634 100755 --- a/shaders/sky.frag.glsl +++ b/shaders/sky.frag.glsl @@ -43,6 +43,5 @@ void main() { 0.758 ); - // apply exposure - out_color = vec4(1.0 - exp(-1.0 * color), 1.0); + out_color = vec4(color, 1.0); }