From 3447dfc5d6cd297d92f3c0b286601208463f3f20 Mon Sep 17 00:00:00 2001 From: Ivan Avdeev Date: Fri, 28 Apr 2023 10:12:15 -0700 Subject: [PATCH] rt: linearize alpha value for blending This makes transparent brushes look more correct. But also makes sprites look a bit dull. Fixes #528 --- ref/vk/shaders/color_spaces.glsl | 5 ++++- ref/vk/shaders/trace_simple_blending.glsl | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ref/vk/shaders/color_spaces.glsl b/ref/vk/shaders/color_spaces.glsl index 0a916f8937..72547ff94b 100644 --- a/ref/vk/shaders/color_spaces.glsl +++ b/ref/vk/shaders/color_spaces.glsl @@ -1,4 +1,4 @@ -#define SRGB_FAST_APPROXIMATION 0 +#define SRGB_FAST_APPROXIMATION #ifdef SRGB_FAST_APPROXIMATION #define LINEARtoSRGB OECF_sRGBFast @@ -32,6 +32,9 @@ vec4 sRGB_OECF(const vec4 sRGB) vec3 sRGB_OECFFast(const vec3 sRGB) { return pow(sRGB, vec3(2.2)); } +float sRGB_OECFFast(const float sRGB) { + return pow(sRGB, 2.2); +} vec4 sRGB_OECFFast(const vec4 sRGB) { return vec4(pow(sRGB.rgb, vec3(2.2)), sRGB.w); } diff --git a/ref/vk/shaders/trace_simple_blending.glsl b/ref/vk/shaders/trace_simple_blending.glsl index 9f228c2088..d507929285 100644 --- a/ref/vk/shaders/trace_simple_blending.glsl +++ b/ref/vk/shaders/trace_simple_blending.glsl @@ -49,8 +49,12 @@ void traceSimpleBlending(vec3 pos, vec3 dir, float L, inout vec3 emissive, inout } #else const vec4 texture_color = texture(textures[nonuniformEXT(kusok.material.tex_base_color)], geom.uv); - float alpha = texture_color.a * kusok.model.color.a * geom.vertex_color.a; - vec3 color = kusok.model.color.rgb * texture_color.rgb * SRGBtoLINEAR(geom.vertex_color.rgb) * alpha; + + // "Linearizing" alpha, while looking weird conceptually in the code, is necessary to make it look close to the original. + // TODO figure out whether texture alpha needs to be linearized too. Don't have good examples to look at. + // TODO this also makes sprites look dull, so likely kusok.model.color linearization should only apply to brush models, not sprites. This is better done when passing brush model to ray tracer. + float alpha = SRGBtoLINEAR(texture_color.a * kusok.model.color.a) * geom.vertex_color.a; + vec3 color = kusok.model.color.rgb * SRGBtoLINEAR(texture_color.rgb) * geom.vertex_color.rgb * alpha; if (kusok.material.mode == MATERIAL_MODE_BLEND_GLOW) { // Glow is additive + small overshoot