[Bf-blender-cvs] [d56f1a5f446] greasepencil-refactor: GPencil: Refactor: Add Rim FX
Clément Foucault
noreply at git.blender.org
Thu Dec 19 01:31:03 CET 2019
Commit: d56f1a5f446cad754382b98bafb621a34c0199a1
Author: Clément Foucault
Date: Wed Dec 18 23:08:57 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rBd56f1a5f446cad754382b98bafb621a34c0199a1
GPencil: Refactor: Add Rim FX
Nothing has changed functionality wise.
===================================================================
M source/blender/draw/engines/gpencil/gpencil_engine.c
M source/blender/draw/engines/gpencil/gpencil_engine.h
M source/blender/draw/engines/gpencil/gpencil_shader.c
M source/blender/draw/engines/gpencil/gpencil_shader_fx.c
M source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
===================================================================
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 39fab08dae8..4fd6ca82a54 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -364,6 +364,7 @@ static void GPENCIL_engine_free(void)
DRW_SHADER_FREE_SAFE(e_data.fx_composite_sh);
DRW_SHADER_FREE_SAFE(e_data.fx_glow_sh);
DRW_SHADER_FREE_SAFE(e_data.fx_pixel_sh);
+ DRW_SHADER_FREE_SAFE(e_data.fx_rim_sh);
DRW_SHADER_FREE_SAFE(e_data.fx_shadow_sh);
DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 2df8688f0d1..be5be0f2861 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -475,6 +475,7 @@ typedef struct GPENCIL_e_data {
struct GPUShader *fx_blur_sh;
struct GPUShader *fx_glow_sh;
struct GPUShader *fx_pixel_sh;
+ struct GPUShader *fx_rim_sh;
struct GPUShader *fx_shadow_sh;
/* general drawing shaders */
@@ -718,6 +719,7 @@ struct GPUShader *GPENCIL_shader_fx_colorize_get(GPENCIL_e_data *e_data);
struct GPUShader *GPENCIL_shader_fx_composite_get(GPENCIL_e_data *e_data);
struct GPUShader *GPENCIL_shader_fx_glow_get(GPENCIL_e_data *e_data);
struct GPUShader *GPENCIL_shader_fx_pixelize_get(GPENCIL_e_data *e_data);
+struct GPUShader *GPENCIL_shader_fx_rim_get(GPENCIL_e_data *e_data);
struct GPUShader *GPENCIL_shader_fx_shadow_get(GPENCIL_e_data *e_data);
/* main functions */
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader.c b/source/blender/draw/engines/gpencil/gpencil_shader.c
index 60bfdf9ccce..8f29c288cd8 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader.c
@@ -141,6 +141,31 @@ struct GPUShader *GPENCIL_shader_fx_colorize_get(GPENCIL_e_data *e_data)
return e_data->fx_colorize_sh;
}
+struct GPUShader *GPENCIL_shader_fx_rim_get(GPENCIL_e_data *e_data)
+{
+ if (!e_data->fx_rim_sh) {
+ e_data->fx_rim_sh = GPU_shader_create_from_arrays({
+ .vert =
+ (const char *[]){
+ datatoc_common_fullscreen_vert_glsl,
+ NULL,
+ },
+ .frag =
+ (const char *[]){
+ datatoc_gpencil_common_lib_glsl,
+ datatoc_gpencil_vfx_frag_glsl,
+ NULL,
+ },
+ .defs =
+ (const char *[]){
+ "#define RIM\n",
+ NULL,
+ },
+ });
+ }
+ return e_data->fx_rim_sh;
+}
+
struct GPUShader *GPENCIL_shader_fx_composite_get(GPENCIL_e_data *e_data)
{
if (!e_data->fx_composite_sh) {
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index fe33113bd6f..95f69b1467e 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -1135,6 +1135,78 @@ static void gpencil_vfx_colorize(ColorizeShaderFxData *fx, Object *UNUSED(ob), g
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
+static void gpencil_vfx_rim(RimShaderFxData *fx, Object *ob, gpIterVfxData *iter)
+{
+ DRWShadingGroup *grp;
+
+ float winmat[4][4], persmat[4][4];
+ float offset[2] = {fx->offset[0], fx->offset[1]};
+ float blur_size[2] = {fx->blur[0], fx->blur[1]};
+ DRW_view_winmat_get(NULL, winmat, false);
+ DRW_view_persmat_get(NULL, persmat, false);
+ const float *vp_size = DRW_viewport_size_get();
+ const float *vp_size_inv = DRW_viewport_invert_size_get();
+
+ const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->obmat[3]));
+
+ /* Modify by distance to camera and object scale. */
+ float world_pixel_scale = 1.0f / 2000.0f;
+ float scale = mat4_to_scale(ob->obmat);
+ float distance_factor = (world_pixel_scale * scale * winmat[1][1] * vp_size[1]) / w;
+ mul_v2_fl(offset, distance_factor);
+ mul_v2_v2(offset, vp_size_inv);
+ mul_v2_fl(blur_size, distance_factor);
+
+ GPUShader *sh = GPENCIL_shader_fx_rim_get(&en_data);
+
+ DRWState state = DRW_STATE_WRITE_COLOR;
+ grp = gpencil_vfx_pass_create("Fx Rim H", state, iter, sh);
+ DRW_shgroup_uniform_vec2_copy(grp, "blurDir", (float[2]){blur_size[0] * vp_size_inv[0], 0.0f});
+ DRW_shgroup_uniform_vec2_copy(grp, "uvOffset", offset);
+ DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, blur_size[0])));
+ DRW_shgroup_uniform_vec3_copy(grp, "maskColor", fx->mask_rgb);
+ DRW_shgroup_uniform_bool_copy(grp, "isFirstPass", true);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+
+ switch (fx->mode) {
+ case eShaderFxRimMode_Normal:
+ state |= DRW_STATE_BLEND_ALPHA_PREMUL;
+ break;
+ case eShaderFxRimMode_Add:
+ state |= DRW_STATE_BLEND_ADD_FULL;
+ break;
+ case eShaderFxRimMode_Subtract:
+ state |= DRW_STATE_BLEND_SUB;
+ break;
+ case eShaderFxRimMode_Multiply:
+ case eShaderFxRimMode_Divide:
+ case eShaderFxRimMode_Overlay:
+ state |= DRW_STATE_BLEND_MUL;
+ break;
+ }
+
+ zero_v2(offset);
+
+ grp = gpencil_vfx_pass_create("Fx Rim V", state, iter, sh);
+ DRW_shgroup_uniform_vec2_copy(grp, "blurDir", (float[2]){0.0f, blur_size[1] * vp_size_inv[1]});
+ DRW_shgroup_uniform_vec2_copy(grp, "uvOffset", offset);
+ DRW_shgroup_uniform_vec3_copy(grp, "rimColor", fx->rim_rgb);
+ DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, blur_size[1])));
+ DRW_shgroup_uniform_int_copy(grp, "blendMode", fx->mode);
+ DRW_shgroup_uniform_bool_copy(grp, "isFirstPass", false);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+
+ if (fx->mode == eShaderFxRimMode_Overlay) {
+ /* We cannot do custom blending on MultiTarget framebuffers.
+ * Workaround by doing 2 passes. */
+ grp = DRW_shgroup_create_sub(grp);
+ DRW_shgroup_state_disable(grp, DRW_STATE_BLEND_MUL);
+ DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ADD_FULL);
+ DRW_shgroup_uniform_int_copy(grp, "blendMode", 999);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ }
+}
+
static void gpencil_vfx_pixelize(PixelShaderFxData *fx, Object *ob, gpIterVfxData *iter)
{
DRWShadingGroup *grp;
@@ -1372,6 +1444,7 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec
gpencil_vfx_pixelize((PixelShaderFxData *)fx, ob, &iter);
break;
case eShaderFxType_Rim:
+ gpencil_vfx_rim((RimShaderFxData *)fx, ob, &iter);
break;
case eShaderFxType_Shadow:
gpencil_vfx_shadow((ShadowShaderFxData *)fx, ob, &iter);
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
index 6e790acff9f..a7a3c4a6a27 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
@@ -159,6 +159,56 @@ void main()
}
}
+#elif defined(RIM)
+
+uniform vec2 blurDir;
+uniform vec2 uvOffset;
+uniform vec3 rimColor;
+uniform vec3 maskColor;
+uniform int sampCount;
+uniform int blendMode;
+uniform bool isFirstPass;
+
+void main()
+{
+ /* Blur revealage buffer. */
+ fragRevealage = vec4(0.0);
+ float weight_accum = 0.0;
+ for (int i = -sampCount; i <= sampCount; i++) {
+ float x = float(i) / float(sampCount);
+ float weight = gaussian_weight(x);
+ weight_accum += weight;
+ vec2 uv = uvcoordsvar.xy + blurDir * x + uvOffset;
+ vec3 col = texture(revealBuf, uv).rgb;
+ if (any(not(equal(vec2(0.0), floor(uv))))) {
+ col = vec3(0.0);
+ }
+ fragRevealage.rgb += col * weight;
+ }
+ fragRevealage /= weight_accum;
+
+ if (isFirstPass) {
+ /* In first pass we copy the reveal buffer. This let us do alpha masking in second pass. */
+ fragColor = texture(revealBuf, uvcoordsvar.xy);
+ /* Also add the masked color to the reveal buffer. */
+ vec3 col = texture(colorBuf, uvcoordsvar.xy).rgb;
+ if (all(lessThan(abs(col - maskColor), vec3(0.05)))) {
+ fragColor = vec4(1.0);
+ }
+ }
+ else {
+ /* Premult by foreground alpha (alpha mask). */
+ float mask = 1.0 - clamp(dot(vec3(0.333334), texture(colorBuf, uvcoordsvar.xy).rgb), 0.0, 1.0);
+
+ /* fragRevealage is blurred shadow. */
+ float rim = clamp(dot(vec3(0.333334), fragRevealage.rgb), 0.0, 1.0);
+
+ vec4 color = vec4(rimColor, 1.0);
+
+ blend_mode_output(blendMode, color, rim * mask, fragColor, fragRevealage);
+ }
+}
+
#elif defined(SHADOW)
uniform vec4 shadowColor;
More information about the Bf-blender-cvs
mailing list