This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/draw/engines/overlay/shaders/background_frag.glsl
Jeroen Bakker 278011e44d Fix T80748: Render Emissive Colors in Compositor Backdrop
This change will use the image engine to draw the backdrop of the compositor. With this patch the alpha blending will be done in Linear Scene Reference space and shows pure emissive colors.

See differential for an example image.

**Technical changes**

As only the backdrop drawing is done using the draw manager there are some technical changes.
1. The overlay buffer is partly drawn outside the draw manager. When drawing the backdrop image the overlay buffer needs to be masked to simulate premultiplied alpha under.
2. The backdrop of the node editor is done in region pixel space. A `DRWView` is constructed with this space.
3. UDIM textures uses world position to generate the UV coordinates. This has been implemented more strict by the `IMAGE_DRAW_FLAG_USE_WORLD_POS`. When the flag isn't used the local coordinates are used to generate the UV coordinates what is image space.
4. The draw manager now checks the actual `eSpaceType` of the space data to use different code paths. In the future the movie clip editor will be added.

NOTE: The preview images in nodes are drawn in display space and cannot show pure emissive colors. As preview images are used on more locations it is best to fix this in a separate patch.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D9451
2020-11-24 13:22:17 +01:00

100 lines
3.2 KiB
GLSL

uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
uniform int bgType;
uniform vec4 colorOverride;
in vec4 uvcoordsvar;
out vec4 fragColor;
#define BG_SOLID 0
#define BG_GRADIENT 1
#define BG_CHECKER 2
#define BG_RADIAL 3
#define BG_SOLID_CHECKER 4
#define BG_MASK 5
#define SQRT2 1.4142135623730950488
/* 4x4 bayer matrix prepared for 8bit UNORM precision error. */
#define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0))
const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)),
vec4(P(12.0), P(4.0), P(14.0), P(6.0)),
vec4(P(3.0), P(11.0), P(1.0), P(9.0)),
vec4(P(15.0), P(7.0), P(13.0), P(5.0)));
float dither(void)
{
ivec2 co = ivec2(gl_FragCoord.xy) % 4;
return dither_mat4x4[co.x][co.y];
}
void main()
{
/* The blend equation is:
* resutl.rgb = SRC.rgb * (1 - DST.a) + DST.rgb * (SRC.a)
* result.a = SRC.a * 0 + DST.a * SRC.a
* This removes the alpha channel and put the background behind reference images
* while masking the reference images by the render alpha.
*/
float alpha = texture(colorBuffer, uvcoordsvar.st).a;
float depth = texture(depthBuffer, uvcoordsvar.st).r;
vec3 bg_col;
vec3 col_high;
vec3 col_low;
/* BG_SOLID_CHECKER selects BG_SOLID when no pixel has been drawn otherwise use the BG_CHERKER.
*/
int bg_type = bgType == BG_SOLID_CHECKER ? (depth == 1.0 ? BG_SOLID : BG_CHECKER) : bgType;
switch (bg_type) {
case BG_SOLID:
bg_col = colorBackground.rgb;
break;
case BG_GRADIENT:
/* XXX do interpolation in a non-linear space to have a better visual result. */
col_high = pow(colorBackground.rgb, vec3(1.0 / 2.2));
col_low = pow(colorBackgroundGradient.rgb, vec3(1.0 / 2.2));
bg_col = mix(col_low, col_high, uvcoordsvar.t);
/* Convert back to linear. */
bg_col = pow(bg_col, vec3(2.2));
/* Dither to hide low precision buffer. (Could be improved) */
bg_col += dither();
break;
case BG_RADIAL:
/* Do interpolation in a non-linear space to have a better visual result. */
col_high = pow(colorBackground.rgb, vec3(1.0 / 2.2));
col_low = pow(colorBackgroundGradient.rgb, vec3(1.0 / 2.2));
vec2 uv_n = uvcoordsvar.xy - 0.5;
bg_col = mix(col_high, col_low, length(uv_n) * SQRT2);
/* Convert back to linear. */
bg_col = pow(bg_col, vec3(2.2));
/* Dither to hide low precision buffer. (Could be improved) */
bg_col += dither();
break;
case BG_CHECKER:
float size = sizeChecker * sizePixel;
ivec2 p = ivec2(floor(gl_FragCoord.xy / size));
bool check = mod(p.x, 2) == mod(p.y, 2);
bg_col = (check) ? colorCheckerPrimary.rgb : colorCheckerSecondary.rgb;
break;
case BG_MASK:
fragColor = vec4(vec3(1.0 - alpha), 0.0);
return;
}
bg_col = mix(bg_col, colorOverride.rgb, colorOverride.a);
/* Mimic alpha under behavior. Result is premultiplied. */
fragColor = vec4(bg_col, 1.0) * (1.0 - alpha);
/* Special case: If the render is not transparent, do not clear alpha values. */
if (depth == 1.0 && alpha == 1.0) {
fragColor.a = 1.0;
}
}