diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-04-23 14:56:30 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-05-13 16:56:10 +0300 |
commit | 7ad802cf3ae500bc72863b6dba0f28a488fce3d1 (patch) | |
tree | a1dd8b96c21a8ba51434933163b5792564006d55 /source/blender/draw/engines/gpencil/shaders | |
parent | e9d2ec46c413718cd058abba84e2badd48542781 (diff) |
Cycles/Eevee: unified and improved texture image color space handling
Cycles now uses the color space on the image datablock, and uses OpenColorIO
to convert to scene linear as needed. Byte images do not take extra memory,
they are compressed in scene linear + sRGB transfer function which in common
cases is a no-op.
Eevee and workbench were changed to work similar. Float images are stored as
scene linear. Byte images are compressed as scene linear + sRGB and stored in
a GL_SRGB8_ALPHA8 texture. From the GLSL shader side this means they are read
as scene linear, simplifying the code and taking advantage of hardware support.
Further, OpenGL image textures are now all stored with premultiplied alpha.
Eevee texture sampling looks a little different now because interpolation
happens premultiplied and in scene linear space.
Overlays and grease pencil work in sRGB space so those now have an extra
conversion to sRGB after reading from image textures. This is not particularly
elegant but as long as engines use different conventions, one or the other
needs to do conversion.
This change breaks compatibility for cases where multiple image texture nodes
were using the same image with different color space node settings. However it
gives more predictable behavior for baking and texture painting if save, load
and image editing operations have a single color space to handle.
Differential Revision: https://developer.blender.org/D4807
Diffstat (limited to 'source/blender/draw/engines/gpencil/shaders')
3 files changed, 70 insertions, 7 deletions
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl index acf60fc2d59..80fae9ab518 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl @@ -89,6 +89,27 @@ void set_color(in vec4 color, ocolor.a *= layer_opacity; } +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) { + return (c < 0.0) ? 0.0 : c * 12.92; + } + else { + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; + } +} + +vec4 texture_read_as_srgb(sampler2D tex, vec2 co) +{ + /* By convention image textures return scene linear colors, but + * grease pencil still works in srgb. */ + vec4 color = texture2D(tex, co); + color.r = linearrgb_to_srgb(color.r); + color.g = linearrgb_to_srgb(color.g); + color.b = linearrgb_to_srgb(color.b); + return color; +} + void main() { vec2 t_center = vec2(0.5, 0.5); @@ -97,8 +118,8 @@ void main() vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + texture_offset; vec4 tmp_color; tmp_color = (texture_clamp == 0) ? - texture2D(myTexture, rot_tex * texture_scale) : - texture2D(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0)); + texture_read_as_srgb(myTexture, rot_tex * texture_scale) : + texture_read_as_srgb(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0)); vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * texture_opacity); vec4 chesscolor; diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl index cc47e12b303..98c47b1f1f0 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl @@ -47,6 +47,27 @@ vec2 check_box_point(vec2 pt, vec2 radius) return rtn; } +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) { + return (c < 0.0) ? 0.0 : c * 12.92; + } + else { + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; + } +} + +vec4 texture_read_as_srgb(sampler2D tex, vec2 co) +{ + /* By convention image textures return scene linear colors, but + * grease pencil still works in srgb. */ + vec4 color = texture2D(tex, co); + color.r = linearrgb_to_srgb(color.r); + color.g = linearrgb_to_srgb(color.g); + color.b = linearrgb_to_srgb(color.b); + return color; +} + void main() { vec2 centered = mTexCoord - vec2(0.5); @@ -65,7 +86,7 @@ void main() } } - vec4 tmp_color = texture2D(myTexture, mTexCoord); + vec4 tmp_color = texture_read_as_srgb(myTexture, mTexCoord); /* Solid */ if ((color_type == GPENCIL_COLOR_SOLID) || (no_texture)) { @@ -73,7 +94,7 @@ void main() } /* texture */ if ((color_type == GPENCIL_COLOR_TEXTURE) && (!no_texture)) { - vec4 text_color = texture2D(myTexture, mTexCoord); + vec4 text_color = texture_read_as_srgb(myTexture, mTexCoord); if (mix_stroke_factor > 0.0) { fragColor.rgb = mix(text_color.rgb, colormix.rgb, mix_stroke_factor); fragColor.a = text_color.a; @@ -87,7 +108,7 @@ void main() } /* pattern */ if ((color_type == GPENCIL_COLOR_PATTERN) && (!no_texture)) { - vec4 text_color = texture2D(myTexture, mTexCoord); + vec4 text_color = texture_read_as_srgb(myTexture, mTexCoord); fragColor = mColor; /* mult both alpha factor to use strength factor with color alpha limit */ fragColor.a = min(text_color.a * mColor.a, mColor.a); diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl index 6b7cee888ea..6b3fcad1240 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl @@ -27,6 +27,27 @@ out vec4 fragColor; bool no_texture = (shading_type[0] == OB_SOLID) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR); +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) { + return (c < 0.0) ? 0.0 : c * 12.92; + } + else { + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; + } +} + +vec4 texture_read_as_srgb(sampler2D tex, vec2 co) +{ + /* By convention image textures return scene linear colors, but + * grease pencil still works in srgb. */ + vec4 color = texture2D(tex, co); + color.r = linearrgb_to_srgb(color.r); + color.g = linearrgb_to_srgb(color.g); + color.b = linearrgb_to_srgb(color.b); + return color; +} + void main() { @@ -47,10 +68,10 @@ void main() /* texture for endcaps */ vec4 text_color; if (uvfac[1] == ENDCAP) { - text_color = texture2D(myTexture, vec2(mTexCoord.x, mTexCoord.y)); + text_color = texture_read_as_srgb(myTexture, vec2(mTexCoord.x, mTexCoord.y)); } else { - text_color = texture2D(myTexture, mTexCoord); + text_color = texture_read_as_srgb(myTexture, mTexCoord); } /* texture */ |