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; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs