Workbench: Fix srgb texture not being color managed in texture color mode
authorClément Foucault <foucault.clem@gmail.com>
Fri, 14 Dec 2018 18:16:35 +0000 (19:16 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 17 Dec 2018 16:05:57 +0000 (17:05 +0100)
source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
source/blender/draw/engines/workbench/workbench_materials.c

index 76b00469f154e346ead0069a64c5299af24fd858..25942b162ee8d08f7e92d14bb4330f84de7f4b3b 100644 (file)
@@ -141,3 +141,21 @@ vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped)
        }
        return matcap_uv * 0.496 + 0.5;
 }
+
+float srgb_to_linearrgb(float c)
+{
+       if (c < 0.04045)
+               return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
+       else
+               return pow((c + 0.055) * (1.0 / 1.055), 2.4);
+}
+
+vec4 srgb_to_linearrgb(vec4 col_from)
+{
+       vec4 col_to;
+       col_to.r = srgb_to_linearrgb(col_from.r);
+       col_to.g = srgb_to_linearrgb(col_from.g);
+       col_to.b = srgb_to_linearrgb(col_from.b);
+       col_to.a = col_from.a;
+       return col_to;
+}
index d42b6bde791f7b7c16f4e45776154f4a479c8fa5..aed86937e0dea59af0235e45d20e6b636f50fb3d 100644 (file)
@@ -1,8 +1,8 @@
-#ifdef V3D_SHADING_TEXTURE_COLOR
-uniform sampler2D image;
+
 uniform float ImageTransparencyCutoff = 0.1;
+uniform sampler2D image;
+uniform bool imageSrgb;
 
-#endif
 uniform mat4 ProjectionMatrix;
 uniform mat4 ViewMatrixInverse;
 uniform float alpha = 0.5;
@@ -39,6 +39,9 @@ void main()
        if (diffuse_color.a < ImageTransparencyCutoff) {
                discard;
        }
+       if (imageSrgb) {
+               diffuse_color = srgb_to_linearrgb(diffuse_color);
+       }
 #else
        diffuse_color = vec4(materialDiffuseColor, 1.0);
 #endif /* V3D_SHADING_TEXTURE_COLOR */
index 722add22a89a5cde9f961ad305087dd239b41c47..2ce816c648435d58295975d6f718918be6841e76 100644 (file)
@@ -6,6 +6,7 @@ uniform float materialRoughness;
 
 uniform sampler2D image;
 uniform float ImageTransparencyCutoff = 0.1;
+uniform bool imageSrgb;
 
 #ifdef NORMAL_VIEWPORT_PASS_ENABLED
 in vec3 normal_viewport;
@@ -40,6 +41,9 @@ void main()
        if (color.a < ImageTransparencyCutoff) {
                discard;
        }
+       if (imageSrgb) {
+               color = srgb_to_linearrgb(color);
+       }
 #  else
        color.rgb = materialDiffuseColor;
 #  endif
index c4ab39897f35e4d18dbd330038b737763112ebab..5360cf3683b5cfacf02b4507971178e58ddc7fd4 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "BIF_gl.h"
 
+#include "BKE_image.h"
+
 #include "BLI_dynstr.h"
 #include "BLI_hash.h"
 
@@ -189,8 +191,12 @@ void workbench_material_shgroup_uniform(
        }
 
        if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) {
+               ImBuf *ibuf = BKE_image_acquire_ibuf(material->ima, NULL, NULL);
+               const bool do_color_correction = (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0);
+               BKE_image_release_ibuf(material->ima, ibuf, NULL);
                GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false, 0.0f);
                DRW_shgroup_uniform_texture(grp, "image", tex);
+               DRW_shgroup_uniform_bool_copy(grp, "imageSrgb", do_color_correction);
        }
        else {
                DRW_shgroup_uniform_vec3(grp, "materialDiffuseColor", (use_metallic) ? material->base_color : material->diffuse_color, 1);