diff options
Diffstat (limited to 'source/blender/draw/engines/gpencil/gpencil_shader_fx.c')
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_shader_fx.c | 290 |
1 files changed, 196 insertions, 94 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c index 9e04365fe1d..2165fb251dc 100644 --- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c +++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c @@ -50,6 +50,8 @@ extern char datatoc_gpencil_fx_rim_prepare_frag_glsl[]; extern char datatoc_gpencil_fx_rim_resolve_frag_glsl[]; extern char datatoc_gpencil_fx_shadow_prepare_frag_glsl[]; extern char datatoc_gpencil_fx_shadow_resolve_frag_glsl[]; +extern char datatoc_gpencil_fx_glow_prepare_frag_glsl[]; +extern char datatoc_gpencil_fx_glow_resolve_frag_glsl[]; extern char datatoc_gpencil_fx_swirl_frag_glsl[]; extern char datatoc_gpencil_fx_wave_frag_glsl[]; @@ -208,7 +210,7 @@ static void DRW_gpencil_fx_blur( } } - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); fx_shgrp = DRW_shgroup_create( e_data->gpencil_fx_blur_sh, @@ -236,7 +238,7 @@ static void DRW_gpencil_fx_colorize( GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; DRWShadingGroup *fx_shgrp; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); @@ -269,7 +271,7 @@ static void DRW_gpencil_fx_flip( fxd->flipmode += 1; } - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); @@ -298,7 +300,7 @@ static void DRW_gpencil_fx_light( GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; DRWShadingGroup *fx_shgrp; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); @@ -351,7 +353,7 @@ static void DRW_gpencil_fx_pixel( fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); @@ -380,7 +382,7 @@ static void DRW_gpencil_fx_rim( GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; DRWShadingGroup *fx_shgrp; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); /* prepare pass */ fx_shgrp = DRW_shgroup_create( e_data->gpencil_fx_rim_prepare_sh, @@ -431,8 +433,8 @@ static void DRW_gpencil_fx_rim( /* Shadow FX */ static void DRW_gpencil_fx_shadow( - ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, - tGPencilObjectCache *cache) + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) { if (fx == NULL) { return; @@ -446,7 +448,7 @@ static void DRW_gpencil_fx_shadow( GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; DRWShadingGroup *fx_shgrp; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); /* prepare pass */ fx_shgrp = DRW_shgroup_create( e_data->gpencil_fx_shadow_prepare_sh, @@ -512,10 +514,71 @@ static void DRW_gpencil_fx_shadow( fxd->runtime.fx_sh_c = fx_shgrp; } +/* Glow FX */ +static void DRW_gpencil_fx_glow( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) +{ + if (fx == NULL) { + return; + } + GlowShaderFxData *fxd = (GlowShaderFxData *)fx; + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + /* prepare pass */ + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_glow_prepare_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + + DRW_shgroup_uniform_vec3(fx_shgrp, "glow_color", &fxd->glow_color[0], 1); + DRW_shgroup_uniform_vec3(fx_shgrp, "select_color", &fxd->select_color[0], 1); + DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1); + DRW_shgroup_uniform_float(fx_shgrp, "threshold", &fxd->threshold, 1); + + fxd->runtime.fx_sh = fx_shgrp; + + /* blur pass */ + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_blur_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx); + DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2); + + DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1); + + fxd->runtime.fx_sh_b = fx_shgrp; + + /* resolve pass */ + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_glow_resolve_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowColor", &e_data->temp_color_tx_fx); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowDepth", &e_data->temp_depth_tx_fx); + + /* reuse field */ + DRW_shgroup_uniform_int(fx_shgrp, "alpha_mode", &fxd->blur[1], 1); + + fxd->runtime.fx_sh_c = fx_shgrp; +} + /* Swirl FX */ static void DRW_gpencil_fx_swirl( ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, - tGPencilObjectCache *cache) + tGPencilObjectCache *cache) { if (fx == NULL) { return; @@ -531,7 +594,7 @@ static void DRW_gpencil_fx_swirl( fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); @@ -562,7 +625,7 @@ static void DRW_gpencil_fx_wave( WaveShaderFxData *fxd = (WaveShaderFxData *)fx; GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; - struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); @@ -617,6 +680,13 @@ void GPENCIL_create_fx_shaders(GPENCIL_e_data *e_data) e_data->gpencil_fx_shadow_resolve_sh = DRW_shader_create_fullscreen( datatoc_gpencil_fx_shadow_resolve_frag_glsl, NULL); } + if (!e_data->gpencil_fx_glow_prepare_sh) { + e_data->gpencil_fx_glow_prepare_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_glow_prepare_frag_glsl, NULL); + + e_data->gpencil_fx_glow_resolve_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_glow_resolve_frag_glsl, NULL); + } if (!e_data->gpencil_fx_swirl_sh) { e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen( datatoc_gpencil_fx_swirl_frag_glsl, NULL); @@ -639,6 +709,8 @@ void GPENCIL_delete_fx_shaders(GPENCIL_e_data *e_data) DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh); DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_prepare_sh); DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_resolve_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_prepare_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_resolve_sh); DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh); DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh); } @@ -659,8 +731,8 @@ void GPENCIL_create_fx_passes(GPENCIL_PassList *psl) /* prepare fx shading groups */ void DRW_gpencil_fx_prepare( - struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, - struct tGPencilObjectCache *cache) + GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) { GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; int ob_idx = cache->idx; @@ -693,6 +765,9 @@ void DRW_gpencil_fx_prepare( case eShaderFxType_Shadow: DRW_gpencil_fx_shadow(fx, e_data, vedata, cache); break; + case eShaderFxType_Glow: + DRW_gpencil_fx_glow(fx, e_data, vedata, cache); + break; case eShaderFxType_Swirl: DRW_gpencil_fx_swirl(fx, e_data, vedata, cache); break; @@ -718,8 +793,7 @@ static void gpencil_draw_fx_pass( return; } - static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - + const float clearcol[4] = {0.0f}; GPU_framebuffer_bind(fbl->temp_fb_b); GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); @@ -743,9 +817,9 @@ static void gpencil_draw_fx_pass( /* helper to manage gaussian blur passes */ static void draw_gpencil_blur_passes( - struct GPENCIL_e_data *e_data, - struct GPENCIL_Data *vedata, - struct BlurShaderFxData *fxd) + GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, + BlurShaderFxData *fxd) { if (fxd->runtime.fx_sh == NULL) { return; @@ -782,19 +856,19 @@ static void draw_gpencil_blur_passes( } } -static void draw_gpencil_rim_blur( - struct GPENCIL_e_data *UNUSED(e_data), - struct GPENCIL_Data *vedata, - struct RimShaderFxData *fxd) +/* blur intermediate pass */ +static void draw_gpencil_midpass_blur( + GPENCIL_Data *vedata, + ShaderFxData_Runtime *runtime) { GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; - static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + const float clearcol[4] = {0.0f}; GPU_framebuffer_bind(fbl->temp_fb_b); GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); DRW_draw_pass_subset(psl->fx_shader_pass_blend, - fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b); + runtime->fx_sh_b, runtime->fx_sh_b); /* copy pass from b for ping-pong frame buffers */ GPU_framebuffer_bind(fbl->temp_fb_fx); @@ -802,11 +876,40 @@ static void draw_gpencil_rim_blur( DRW_draw_pass(psl->mix_pass_noblend); } +/* do blur of mid passes */ +static void draw_gpencil_do_blur( + GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, + ShaderFxData_Runtime *runtime, + int samples, int bx, int by, int blur[2]) +{ + e_data->input_depth_tx = e_data->temp_depth_tx_b; + e_data->input_color_tx = e_data->temp_color_tx_b; + + if ((samples > 0) && ((bx > 0) || (by > 0))) { + for (int x = 0; x < samples * 4; x++) { + + /* horizontal */ + blur[0] = bx; + blur[1] = 0; + draw_gpencil_midpass_blur(vedata, runtime); + + /* Vertical */ + blur[0] = 0; + blur[1] = by; + draw_gpencil_midpass_blur(vedata, runtime); + + blur[0] = bx; + blur[1] = by; + } + } +} + /* helper to draw RIM passes */ static void draw_gpencil_rim_passes( - struct GPENCIL_e_data *e_data, - struct GPENCIL_Data *vedata, - struct RimShaderFxData *fxd) + GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, + RimShaderFxData *fxd) { if (fxd->runtime.fx_sh_b == NULL) { return; @@ -815,9 +918,7 @@ static void draw_gpencil_rim_passes( GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; - static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - int bx = fxd->blur[0]; - int by = fxd->blur[1]; + const float clearcol[4] = {0.0f}; /* prepare mask */ GPU_framebuffer_bind(fbl->temp_fb_fx); @@ -827,26 +928,11 @@ static void draw_gpencil_rim_passes( fxd->runtime.fx_sh, fxd->runtime.fx_sh); /* blur rim */ - e_data->input_depth_tx = e_data->temp_depth_tx_b; - e_data->input_color_tx = e_data->temp_color_tx_b; - - if ((fxd->samples > 0) && ((bx > 0) || (by > 0))) { - for (int x = 0; x < fxd->samples; x++) { - - /* horizontal */ - fxd->blur[0] = bx; - fxd->blur[1] = 0; - draw_gpencil_rim_blur(e_data, vedata, fxd); - - /* Vertical */ - fxd->blur[0] = 0; - fxd->blur[1] = by; - draw_gpencil_rim_blur(e_data, vedata, fxd); - - fxd->blur[0] = bx; - fxd->blur[1] = by; - } - } + draw_gpencil_do_blur( + e_data, vedata, &fxd->runtime, + fxd->samples, + fxd->blur[0], fxd->blur[1], + &fxd->blur[0]); /* resolve */ GPU_framebuffer_bind(fbl->temp_fb_b); @@ -864,32 +950,55 @@ static void draw_gpencil_rim_passes( DRW_draw_pass(psl->mix_pass_noblend); } -/* blur shadow */ -static void draw_gpencil_shadow_blur( - struct GPENCIL_e_data *UNUSED(e_data), - struct GPENCIL_Data *vedata, - struct ShadowShaderFxData *fxd) +/* helper to draw SHADOW passes */ +static void draw_gpencil_shadow_passes( + GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, + ShadowShaderFxData *fxd) { + if (fxd->runtime.fx_sh_b == NULL) { + return; + } + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; - static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + const float clearcol[4] = {0.0f}; + + /* prepare shadow */ + GPU_framebuffer_bind(fbl->temp_fb_fx); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f); + DRW_draw_pass_subset( + psl->fx_shader_pass_blend, + fxd->runtime.fx_sh, fxd->runtime.fx_sh); + + /* blur shadow */ + draw_gpencil_do_blur( + e_data, vedata, &fxd->runtime, + fxd->samples, + fxd->blur[0], fxd->blur[1], + &fxd->blur[0]); + /* resolve */ GPU_framebuffer_bind(fbl->temp_fb_b); GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); - DRW_draw_pass_subset(psl->fx_shader_pass_blend, - fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b); + DRW_draw_pass_subset( + psl->fx_shader_pass_blend, + fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c); - /* copy pass from b for ping-pong frame buffers */ - GPU_framebuffer_bind(fbl->temp_fb_fx); - GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f); + /* copy pass from b to a for ping-pong frame buffers */ + e_data->input_depth_tx = e_data->temp_depth_tx_b; + e_data->input_color_tx = e_data->temp_color_tx_b; + + GPU_framebuffer_bind(fbl->temp_fb_a); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f); DRW_draw_pass(psl->mix_pass_noblend); } -/* helper to draw SHADOW passes */ -static void draw_gpencil_shadow_passes( - struct GPENCIL_e_data *e_data, - struct GPENCIL_Data *vedata, - struct ShadowShaderFxData *fxd) +/* helper to draw GLOW passes */ +static void draw_gpencil_glow_passes( + GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, + GlowShaderFxData *fxd) { if (fxd->runtime.fx_sh_b == NULL) { return; @@ -898,42 +1007,29 @@ static void draw_gpencil_shadow_passes( GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; - static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - int bx = fxd->blur[0]; - int by = fxd->blur[1]; + const float clearcol[4] = {0.0f}; - /* prepare shadow */ + /* prepare glow */ GPU_framebuffer_bind(fbl->temp_fb_fx); GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f); DRW_draw_pass_subset( psl->fx_shader_pass_blend, fxd->runtime.fx_sh, fxd->runtime.fx_sh); - /* blur shadow */ - e_data->input_depth_tx = e_data->temp_depth_tx_b; - e_data->input_color_tx = e_data->temp_color_tx_b; - - if ((fxd->samples > 0) && ((bx > 0) || (by > 0))) { - for (int x = 0; x < fxd->samples; x++) { - - /* horizontal */ - fxd->blur[0] = bx; - fxd->blur[1] = 0; - draw_gpencil_shadow_blur(e_data, vedata, fxd); - - /* Vertical */ - fxd->blur[0] = 0; - fxd->blur[1] = by; - draw_gpencil_shadow_blur(e_data, vedata, fxd); - - fxd->blur[0] = bx; - fxd->blur[1] = by; - } - } + /* blur glow */ + draw_gpencil_do_blur( + e_data, vedata, &fxd->runtime, + fxd->samples, + fxd->blur[0], fxd->blur[0], + &fxd->blur[0]); /* resolve */ GPU_framebuffer_bind(fbl->temp_fb_b); GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); + + /* reuses blur field to keep alpha mode */ + fxd->blur[1] = (fxd->flag & FX_GLOW_USE_ALPHA) ? 1 : 0; + DRW_draw_pass_subset( psl->fx_shader_pass_blend, fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c); @@ -949,8 +1045,8 @@ static void draw_gpencil_shadow_passes( /* apply all object fx effects */ void DRW_gpencil_fx_draw( - struct GPENCIL_e_data *e_data, - struct GPENCIL_Data *vedata, struct tGPencilObjectCache *cache) + GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, tGPencilObjectCache *cache) { GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; @@ -1003,6 +1099,12 @@ void DRW_gpencil_fx_draw( draw_gpencil_shadow_passes(e_data, vedata, fxd); break; } + case eShaderFxType_Glow: + { + GlowShaderFxData *fxd = (GlowShaderFxData *)fx; + draw_gpencil_glow_passes(e_data, vedata, fxd); + break; + } case eShaderFxType_Swirl: { SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx; |