[Bf-blender-cvs] [b57ec68fcf8] temp-gpencil-drw-engine: GPencil: Rework Layer Blending
Clément Foucault
noreply at git.blender.org
Fri Jun 28 17:41:35 CEST 2019
Commit: b57ec68fcf83bd30bc3bfaa4763b1987ff291d43
Author: Clément Foucault
Date: Fri Jun 28 17:41:23 2019 +0200
Branches: temp-gpencil-drw-engine
https://developer.blender.org/rBb57ec68fcf83bd30bc3bfaa4763b1987ff291d43
GPencil: Rework Layer Blending
Layer blending is now done by the hardware and uses dual source blending.
This patch breaks a few things:
- The depth of the blended strokes are not merged anymore.
- The layer masking is broken.
Theses will be for a different patch.
I'm not sure if overlay fading (based on alpha) is handle correctly but it
does fade to neutral.
===================================================================
M source/blender/draw/engines/gpencil/gpencil_engine.c
M source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
===================================================================
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 26b4b4cc1c1..10f50f14675 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -540,18 +540,13 @@ void GPENCIL_cache_init(void *vedata)
/* blend layers pass */
psl->blend_layers_pass = DRW_pass_create("GPencil Blend Layers Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA |
- DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh,
psl->blend_layers_pass);
DRW_shgroup_call(blend_shgrp, quad, NULL);
DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &stl->g_data->temp_color_a_tx);
DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &stl->g_data->temp_depth_a_tx);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &stl->g_data->temp_color_fx_tx);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &stl->g_data->temp_depth_fx_tx);
DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
- DRW_shgroup_uniform_int(blend_shgrp, "mask_layer", &stl->storage->mask_layer, 1);
- DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
/* create effects passes */
if (!stl->storage->simplify_fx) {
@@ -1036,15 +1031,15 @@ void GPENCIL_draw_scene(void *ved)
init_shgrp = array_elm->init_shgrp;
end_shgrp = array_elm->end_shgrp;
+ if (stl->storage->multisamples > 0) {
+ GPU_framebuffer_bind(fbl->multisample_fb);
+ }
+ else {
+ GPU_framebuffer_bind(fbl->temp_a_fb);
+ }
+
if (array_elm->mode == eGplBlendMode_Regular) {
/* Draw current group in MSAA texture or final texture. */
- if (stl->storage->multisamples > 0) {
- GPU_framebuffer_bind(fbl->multisample_fb);
- }
- else {
- GPU_framebuffer_bind(fbl->temp_a_fb);
- }
-
gpencil_draw_pass_range(
fbl, stl, psl, txl, fbl->temp_a_fb, ob, gpd, init_shgrp, end_shgrp);
}
@@ -1053,16 +1048,17 @@ void GPENCIL_draw_scene(void *ved)
GPU_framebuffer_bind(blend_fb);
GPU_framebuffer_clear_color_depth_stencil(blend_fb, clearcol, 1.0f, 0x0);
gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_a_fb, ob, gpd, init_shgrp, end_shgrp);
+ fbl, stl, psl, txl, fbl->temp_fx_fb, ob, gpd, init_shgrp, end_shgrp);
/* Draw Blended texture over MSAA texture */
- GPU_framebuffer_bind(fbl->multisample_fb);
- // TODO: How resolve the Blend?
- // TODO: Mask Layers?
- // Do I need use the blend layer pass/fragment (blend_layers_pass)
- // stl->g_data->input_depth_tx = txl->multisample_depth;
- // stl->g_data->input_color_tx = txl->multisample_color;
- // DRW_draw_pass(psl->mix_screen_noblend_pass); // general copy of buffers
+ if (stl->storage->multisamples > 0) {
+ GPU_framebuffer_bind(fbl->multisample_fb);
+ }
+ else {
+ GPU_framebuffer_bind(fbl->temp_a_fb);
+ }
+ stl->storage->blend_mode = array_elm->mode;
+ DRW_draw_pass(psl->blend_layers_pass); // general copy of buffers
}
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
index 85dee4390a5..c118e05a4a0 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
@@ -1,17 +1,7 @@
-in vec4 uvcoordsvar;
-
-out vec4 FragColor;
uniform sampler2D strokeColor;
uniform sampler2D strokeDepth;
-uniform sampler2D blendColor;
-uniform sampler2D blendDepth;
uniform int mode;
-uniform int mask_layer;
-uniform int tonemapping;
-
-#define ON 1
-#define OFF 0
#define MODE_REGULAR 0
#define MODE_OVERLAY 1
@@ -20,138 +10,67 @@ uniform int tonemapping;
#define MODE_MULTIPLY 4
#define MODE_DIVIDE 5
-float overlay_color(float a, float b)
-{
- float rtn;
- if (a < 0.5) {
- rtn = 2.0 * a * b;
- }
- else {
- rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
- }
-
- return rtn;
-}
+/* Blend equation is : FragColor0 + FragColor1 * DstColor */
+layout(location = 0, index = 0) out vec4 FragColor0;
+layout(location = 0, index = 1) out vec4 FragColor1;
-vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color)
+void main()
{
- vec4 outcolor;
-
- if (mix_color.a == 0) {
- return src_color;
- }
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+ vec4 src = texelFetch(strokeColor, texel, 0).rgba;
+ gl_FragDepth = texelFetch(strokeDepth, texel, 0).r;
switch (mode) {
- case MODE_REGULAR: {
- /* premult */
- src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
- mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
-
- outcolor = vec4(mix(src_color.rgb, mix_color.rgb, mix_color.a), src_color.a);
+ case MODE_REGULAR:
+ FragColor0 = src;
+ FragColor1 = 1.0 - vec4(src.a);
break;
- }
- case MODE_OVERLAY: {
- src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
- mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
-
- mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
- outcolor.r = overlay_color(src_color.r, mix_color.r);
- outcolor.g = overlay_color(src_color.g, mix_color.g);
- outcolor.b = overlay_color(src_color.b, mix_color.b);
- outcolor.a = src_color.a;
+ case MODE_OVERLAY:
+ /* Original overlay is :
+ * overlay = (a < 0.5) ? (2 * a * b) : (1 - 2 * (1 - a) * (1 - b));
+ * But we are using dual source blending. So we need to rewrite it as a function of b (DST).
+ * overlay = 1 - 2 * (1 - a) * (1 - b);
+ * overlay = 1 + (2 * a - 2) * (1 - b);
+ * overlay = 1 + (2 * a - 2) - (2 * a - 2) * b;
+ * overlay = (2 * a - 1) + (2 - 2 * a) * b;
+ *
+ * With the right coefficient, we can get the 2 * a * b from the same equation.
+ * q0 = 0, q1 = -1;
+ * overlay = (2 * a - 1) * q0 + (2 * q0 - 2 * q1 * a) * b;
+ * overlay = 2 * a * b;
+ * */
+ src.rgb = mix(vec3(0.5), src.rgb, src.a);
+ vec3 q0 = vec3(greaterThanEqual(src.rgb, vec3(0.5)));
+ vec3 q1 = ((q0 - 0.5) * 2.0);
+ vec3 src2 = 2.0 * src.rgb;
+ FragColor0.rgb = src2 * q0 - q0;
+ FragColor0.a = 0.0;
+ FragColor1.rgb = 2.0 * q0 - src2 * q1;
+ FragColor1.a = 1.0;
break;
- }
- case MODE_ADD: {
- mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
- outcolor = src_color + mix_color;
- outcolor.a = src_color.a;
+ case MODE_ADD:
+ FragColor0.rgb = src.rgb * src.a;
+ FragColor0.a = 0.0;
+ FragColor1 = vec4(1.0);
break;
- }
- case MODE_SUB: {
- mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
- outcolor = src_color - mix_color;
- outcolor.a = clamp(src_color.a - mix_color.a, 0.0, 1.0);
+ case MODE_SUB:
+ FragColor0.rgb = -src.rgb * src.a;
+ FragColor0.a = 0.0;
+ FragColor1 = vec4(1.0);
break;
- }
- case MODE_MULTIPLY: {
- src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
- mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
-
- mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
- outcolor = src_color * mix_color;
- outcolor.a = src_color.a;
+ case MODE_MULTIPLY:
+ FragColor0 = vec4(0.0);
+ FragColor1.rgb = mix(vec3(1.0), src.rgb, src.a);
+ FragColor1.a = 1.0;
break;
- }
- case MODE_DIVIDE: {
- mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
- outcolor = src_color / mix_color;
- outcolor.a = src_color.a;
+ case MODE_DIVIDE:
+ FragColor0 = vec4(0.0);
+ FragColor1.rgb = 1.0 / mix(vec3(1.0), src.rgb, src.a);
+ FragColor1.a = 1.0;
break;
- }
- default: {
- outcolor = mix_color;
- outcolor.a = src_color.a;
+ default:
+ FragColor0 = vec4(0.0);
+ FragColor1 = vec4(1.0);
break;
- }
- }
- return clamp(outcolor, 0.0, 1.0);
-}
-
-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 tone(vec4 stroke_color)
-{
- if (tonemapping == 1) {
- vec4 color = vec4(0, 0, 0, stroke_color.a);
- color.r = linearrgb_to_srgb(stroke_color.r);
- color.g = linearrgb_to_srgb(stroke_color.g);
- color.b = linearrgb_to_srgb(stroke_color.b);
- return color;
- }
- else {
- return stroke_color;
- }
-}
-
-void main()
-{
- vec4 outcolor;
- ivec2 uv = ivec2(gl_FragCoord.xy);
- vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
- float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
-
- vec4 mix_color = texelFetch(blendColor, uv, 0).rgba;
- float mix_depth = texelFetch(blendDepth, uv, 0).r;
-
- if (stroke_color.a > 0) {
- if (mix_color.a > 0) {
- /* apply blend mode */
- FragColor = get_blend_color(mode, stroke_color, mix_color);
- }
- else {
- FragColor = stroke_color;
- }
- gl_FragDepth = min(stroke_depth, mix_depth);
}
- else {
- if (mask_layer == ON) {
- discard;
- }
- else {
- /* if not using mask, return mix color */
- FragColor = mix_color;
- gl_FragDepth = mix_depth;
- }
- }
-
- /* apply tone mapping */
- FragColor = tone(FragColor);
}
More information about the Bf-blender-cvs
mailing list