GP: New Glow Shader FX (wip)
authorAntonioya <blendergit@gmail.com>
Wed, 10 Oct 2018 20:52:55 +0000 (22:52 +0200)
committerAntonioya <blendergit@gmail.com>
Wed, 10 Oct 2018 21:00:56 +0000 (23:00 +0200)
New shader to simulate a glow of the color.

The glow can be generated by luminance threshold or using a selection color.

13 files changed:
release/scripts/startup/bl_ui/properties_data_shaderfx.py
source/blender/draw/CMakeLists.txt
source/blender/draw/engines/gpencil/gpencil_engine.h
source/blender/draw/engines/gpencil/gpencil_shader_fx.c
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl [new file with mode: 0644]
source/blender/makesdna/DNA_shader_fx_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_shader_fx.c
source/blender/shader_fx/CMakeLists.txt
source/blender/shader_fx/FX_shader_types.h
source/blender/shader_fx/intern/FX_shader_util.c
source/blender/shader_fx/intern/fx_shader_glow.c [new file with mode: 0644]

index fdb962aab68509c1b6c703fe1bc16f8ac0207b99..8b4bd03bc6d0730f64fd770cc12f72030adb3e66 100644 (file)
@@ -125,6 +125,19 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel):
             layout.prop(fx, "period")
             layout.prop(fx, "phase")
 
+    def FX_GLOW(self, layout, fx):
+        layout.prop(fx, "mode")
+        layout.prop(fx, "glow_color")
+        if fx.mode == 'LUMINANCE':
+            layout.prop(fx, "threshold")
+        else:
+            layout.prop(fx, "select_color")
+
+        layout.separator()
+        layout.prop(fx, "radius")
+        layout.prop(fx, "samples")
+        layout.prop(fx, "use_alpha_mode", text="Use alpha mode")
+
     def FX_SWIRL(self, layout, fx):
         layout.prop(fx, "object", text="Object")
 
index 4f9a90ba4f0ea57a9336ae83f6a0bd3a8a61b84e..738efffcd91f7d849c5a1935af48fe003a8c0306 100644 (file)
@@ -337,6 +337,8 @@ data_to_c_simple(engines/gpencil/shaders/gpencil_edit_point_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl SRC)
+data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl SRC)
+data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl SRC)
index 7a9e93ec105246786a181af9c3f95ce02627af84..b8844d3c3e91e2a125eb891961c7fc9482bc9c65 100644 (file)
@@ -73,6 +73,7 @@ typedef struct tGPencilObjectCache {
        DRWShadingGroup *fx_pixel_sh;
        DRWShadingGroup *fx_rim_sh;
        DRWShadingGroup *fx_shadow_sh;
+       DRWShadingGroup *fx_glow_sh;
        DRWShadingGroup *fx_swirl_sh;
        DRWShadingGroup *fx_flip_sh;
        DRWShadingGroup *fx_light_sh;
@@ -231,6 +232,8 @@ typedef struct GPENCIL_e_data {
        struct GPUShader *gpencil_fx_blur_sh;
        struct GPUShader *gpencil_fx_colorize_sh;
        struct GPUShader *gpencil_fx_flip_sh;
+       struct GPUShader *gpencil_fx_glow_prepare_sh;
+       struct GPUShader *gpencil_fx_glow_resolve_sh;
        struct GPUShader *gpencil_fx_light_sh;
        struct GPUShader *gpencil_fx_pixel_sh;
        struct GPUShader *gpencil_fx_rim_prepare_sh;
index 9e04365fe1d111a8190eb656aa6991e026ff36bf..9513f83191e518936f698440a940aa82d9bd6ca6 100644 (file)
@@ -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[];
 
@@ -512,6 +514,67 @@ 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;
+
+       struct 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,
@@ -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);
 }
@@ -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;
@@ -947,6 +1022,92 @@ static void draw_gpencil_shadow_passes(
        DRW_draw_pass(psl->mix_pass_noblend);
 }
 
+/* blur glow */
+static void draw_gpencil_glow_blur(
+       struct GPENCIL_e_data *UNUSED(e_data),
+       struct GPENCIL_Data *vedata,
+       struct GlowShaderFxData *fxd)
+{
+       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 };
+
+       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);
+
+       /* 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);
+       DRW_draw_pass(psl->mix_pass_noblend);
+}
+
+/* helper to draw GLOW passes */
+static void draw_gpencil_glow_passes(
+       struct GPENCIL_e_data *e_data,
+       struct GPENCIL_Data *vedata,
+       struct GlowShaderFxData *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 };
+       int bx = fxd->blur[0];
+       int by = fxd->blur[0];
+
+       /* 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 glow */
+       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_glow_blur(e_data, vedata, fxd);
+
+                       /* Vertical */
+                       fxd->blur[0] = 0;
+                       fxd->blur[1] = by;
+                       draw_gpencil_glow_blur(e_data, vedata, fxd);
+
+                       fxd->blur[0] = bx;
+                       fxd->blur[1] = by;
+               }
+       }
+       /* 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);
+
+       /* 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);
+}
+
 /* apply all object fx effects */
 void DRW_gpencil_fx_draw(
         struct GPENCIL_e_data *e_data,
@@ -1003,6 +1164,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;
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl
new file mode 100644 (file)
index 0000000..237cdf1
--- /dev/null
@@ -0,0 +1,68 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+/* ******************************************************************* */
+/* create glow mask                                                    */
+/* ******************************************************************* */
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform vec3 glow_color;
+uniform vec3 select_color;
+uniform float threshold;
+uniform int mode;
+
+out vec4 FragColor;
+
+#define MODE_LUMINANCE   0
+#define MODE_COLOR       1
+
+/* calc luminance */
+float luma( vec3 color ) {
+       /* the color is linear, so do not apply tonemapping */
+       return (color.r + color.g + color.b) / 3.0;
+}
+
+bool check_color(vec3 color_a, vec3 color_b)
+{
+ /* need round the number to avoid precision errors */
+       if ((floor(color_a.r * 100) == floor(color_b.r * 100)) &&
+               (floor(color_a.g * 100) == floor(color_b.g * 100)) &&
+               (floor(color_a.b * 100) == floor(color_b.b * 100))) 
+               {
+               return true;
+               }
+
+ return false;
+}
+
+void main()
+{
+       vec2 uv = vec2(gl_FragCoord.xy);
+
+       float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
+       vec4 src_pixel= texelFetch(strokeColor, ivec2(uv.xy), 0);
+       vec4 outcolor;
+
+       /* is transparent */
+       if (src_pixel.a == 0.0f) {
+               discard;
+       }
+
+       if (mode == MODE_LUMINANCE) {
+               if (luma(src_pixel.rgb) < threshold) {
+                       discard;
+               }
+       }
+       else if (mode == MODE_COLOR) {
+               if (!check_color(src_pixel.rgb, select_color.rgb)) {
+                       discard;
+               }
+       }
+       else {
+               discard;
+       }
+       
+       gl_FragDepth = stroke_depth;
+       FragColor = vec4(glow_color.rgb, 1.0);
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl
new file mode 100644 (file)
index 0000000..010c4ef
--- /dev/null
@@ -0,0 +1,46 @@
+/* ******************************************************************* */
+/* Resolve GLOW pass                                                   */
+/* ******************************************************************* */
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform sampler2D glowColor;
+uniform sampler2D glowDepth;
+uniform int alpha_mode;
+
+out vec4 FragColor;
+
+void main()
+{
+       vec4 outcolor;
+       ivec2 uv = ivec2(gl_FragCoord.xy);
+
+       float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+       vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
+       vec4 glow_pixel= texelFetch(glowColor, uv.xy, 0);
+       float glow_depth = texelFetch(glowDepth, uv.xy, 0).r;
+
+       if (alpha_mode == 0) {
+               outcolor = src_pixel + glow_pixel;
+       }
+       else {
+               if ((src_pixel.a < 0.1) || (glow_pixel.a < 0.1)) {
+                       outcolor = src_pixel + glow_pixel;
+               }
+               else {
+                       outcolor = src_pixel;
+               }
+       }
+       
+       if (src_pixel.a < glow_pixel.a) {
+               gl_FragDepth = glow_depth;
+       }
+       else {
+               gl_FragDepth = stroke_depth;
+       }
+       
+       if (outcolor.a < 0.001) {
+               discard;
+       }
+       
+       FragColor = outcolor;
+}
index 3884f72fb5626de0254219ae761bbf0797f16b29..7c138f21887023c528066637f40815454c389501 100644 (file)
@@ -45,6 +45,7 @@ typedef enum ShaderFxType {
        eShaderFxType_Rim       = 7,
        eShaderFxType_Colorize  = 8,
        eShaderFxType_Shadow    = 9,
+       eShaderFxType_Glow      = 10,
        NUM_SHADER_FX_TYPES
 } ShaderFxType;
 
@@ -127,6 +128,27 @@ typedef enum eFlipShaderFx_Flag {
        FX_FLIP_VERTICAL = (1 << 1),
 } eFlipShaderFx_Flag;
 
+typedef struct GlowShaderFxData {
+       ShaderFxData shaderfx;
+       float glow_color[3];
+       float select_color[3];
+       float threshold;
+       int   flag; /* flags */
+       int   mode;
+       int   blur[2];
+       int   samples;
+       ShaderFxData_Runtime runtime;
+} GlowShaderFxData;
+
+typedef enum GlowShaderFxModes {
+       eShaderFxGlowMode_Luminance = 0,
+       eShaderFxGlowMode_Color = 1,
+} GlowShaderFxModes;
+
+typedef enum eGlowShaderFx_Flag {
+       FX_GLOW_USE_ALPHA = (1 << 0),
+} eGlowShaderFx_Flag;
+
 typedef struct LightShaderFxData {
        ShaderFxData shaderfx;
        struct Object *object;
index a90248ee53eb5896c445c132b923adb5d8c0c44d..c1eed8093c85d36de9a7f98b551f34d3c0c78711 100644 (file)
@@ -619,6 +619,7 @@ extern StructRNA RNA_ShaderFx;
 extern StructRNA RNA_ShaderFxBlur;
 extern StructRNA RNA_ShaderFxColorize;
 extern StructRNA RNA_ShaderFxFlip;
+extern StructRNA RNA_ShaderFxGlow;
 extern StructRNA RNA_ShaderFxLight;
 extern StructRNA RNA_ShaderFxPixel;
 extern StructRNA RNA_ShaderFxRim;
index 22ebd3f75675ae17660911192aa4d311ce0dc0e5..fe4e20bbd582d352f1cd84f8eda59411dedc1b70 100644 (file)
@@ -52,6 +52,7 @@ const EnumPropertyItem rna_enum_object_shaderfx_type_items[] = {
        {eShaderFxType_Blur, "FX_BLUR", ICON_SHADERFX, "Blur", "Apply Gaussian Blur to object" },
        {eShaderFxType_Colorize, "FX_COLORIZE", ICON_SHADERFX, "Colorize", "Apply different tint effects" },
        {eShaderFxType_Flip, "FX_FLIP", ICON_SHADERFX, "Flip", "Flip image" },
+       {eShaderFxType_Glow, "FX_GLOW", ICON_SHADERFX, "Glow", "Create a glow effect" },
        {eShaderFxType_Light, "FX_LIGHT", ICON_SHADERFX, "Light", "Simulate ilumination" },
        {eShaderFxType_Pixel, "FX_PIXEL", ICON_SHADERFX, "Pixelate", "Pixelate image"},
        {eShaderFxType_Rim, "FX_RIM", ICON_SHADERFX, "Rim", "Add a rim to the image" },
@@ -71,6 +72,12 @@ static const EnumPropertyItem rna_enum_shaderfx_rim_modes_items[] = {
        {0, NULL, 0, NULL, NULL }
 };
 
+static const EnumPropertyItem rna_enum_shaderfx_glow_modes_items[] = {
+       {eShaderFxGlowMode_Luminance, "LUMINANCE", 0, "Luminance", "" },
+       {eShaderFxGlowMode_Color, "COLOR", 0, "Color", "" },
+       {0, NULL, 0, NULL, NULL }
+};
+
 static const EnumPropertyItem rna_enum_shaderfx_colorize_modes_items[] = {
        {eShaderFxColorizeMode_GrayScale, "GRAYSCALE", 0, "Gray Scale", "" },
        {eShaderFxColorizeMode_Sepia, "SEPIA", 0, "Sepia", "" },
@@ -108,6 +115,8 @@ static StructRNA *rna_ShaderFx_refine(struct PointerRNA *ptr)
                        return &RNA_ShaderFxSwirl;
                case eShaderFxType_Flip:
                        return &RNA_ShaderFxFlip;
+               case eShaderFxType_Glow:
+                       return &RNA_ShaderFxGlow;
                case eShaderFxType_Light:
                        return &RNA_ShaderFxLight;
                        /* Default */
@@ -483,6 +492,64 @@ static void rna_def_shader_fx_shadow(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
 }
 
+static void rna_def_shader_fx_glow(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "ShaderFxGlow", "ShaderFx");
+       RNA_def_struct_ui_text(srna, "Glow Effect", "Glow effect");
+       RNA_def_struct_sdna(srna, "GlowShaderFxData");
+       RNA_def_struct_ui_icon(srna, ICON_SHADERFX);
+
+       prop = RNA_def_property(srna, "glow_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+       RNA_def_property_range(prop, 0.0, 1.0);
+       RNA_def_property_float_sdna(prop, NULL, "glow_color");
+       RNA_def_property_array(prop, 3);
+       RNA_def_property_ui_text(prop, "Glow Color", "Color used for generated glow");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+
+       prop = RNA_def_property(srna, "select_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+       RNA_def_property_range(prop, 0.0, 1.0);
+       RNA_def_property_float_sdna(prop, NULL, "select_color");
+       RNA_def_property_array(prop, 3);
+       RNA_def_property_ui_text(prop, "Select Color", "Color selected to apply glow");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+
+       prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "mode");
+       RNA_def_property_enum_items(prop, rna_enum_shaderfx_glow_modes_items);
+       RNA_def_property_ui_text(prop, "Mode", "Glow mode");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+
+       prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "threshold");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 3);
+       RNA_def_property_ui_text(prop, "Threshold", "Limit to select color for glow effect");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+
+       /* use blur fields to make compatible with blur filter, but only makes public first array element */
+       prop = RNA_def_property(srna, "radius", PROP_INT, PROP_PIXEL);
+       RNA_def_property_int_sdna(prop, NULL, "blur[0]");
+       RNA_def_property_range(prop, 0, INT_MAX);
+       RNA_def_property_ui_text(prop, "Radius", "Number of pixels for bluring glow (set to 0 to disable)");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+
+       prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "samples");
+       RNA_def_property_range(prop, 1, 32);
+       RNA_def_property_ui_range(prop, 1, 32, 2, -1);
+       RNA_def_property_int_default(prop, 4);
+       RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+
+       prop = RNA_def_property(srna, "use_alpha_mode", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_GLOW_USE_ALPHA);
+       RNA_def_property_ui_text(prop, "Use Alpha", "Glow only areas with alpha");
+       RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+}
+
 static void rna_def_shader_fx_swirl(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -631,6 +698,7 @@ void RNA_def_shader_fx(BlenderRNA *brna)
        rna_def_shader_fx_pixel(brna);
        rna_def_shader_fx_rim(brna);
        rna_def_shader_fx_shadow(brna);
+       rna_def_shader_fx_glow(brna);
        rna_def_shader_fx_swirl(brna);
        rna_def_shader_fx_flip(brna);
        rna_def_shader_fx_light(brna);
index 89defbd4ac7b6ee7cf554dc7f3d8b855cfd69178..1807635aa8d444b76f891dee87cf9cf9dbac01e5 100644 (file)
@@ -46,6 +46,7 @@ set(SRC
        intern/FX_shader_blur.c
        intern/FX_shader_colorize.c
        intern/FX_shader_flip.c
+       intern/FX_shader_glow.c
        intern/FX_shader_light.c
        intern/FX_shader_pixel.c
        intern/FX_shader_rim.c
index 57b9ae711462b6620fb312734606a05894da3ccd..311f5ec52e887fe3d52b87242ce185f69ef181cf 100644 (file)
@@ -35,6 +35,7 @@ extern ShaderFxTypeInfo shaderfx_Type_None;
 extern ShaderFxTypeInfo shaderfx_Type_Blur;
 extern ShaderFxTypeInfo shaderfx_Type_Colorize;
 extern ShaderFxTypeInfo shaderfx_Type_Flip;
+extern ShaderFxTypeInfo shaderfx_Type_Glow;
 extern ShaderFxTypeInfo shaderfx_Type_Light;
 extern ShaderFxTypeInfo shaderfx_Type_Pixel;
 extern ShaderFxTypeInfo shaderfx_Type_Rim;
index d5cbdc69ba37cab5dca341554d94a1f57b66cadc..b74ff45b991d5214f4efa0b10f2005a0d659ba84 100644 (file)
@@ -46,6 +46,7 @@ void shaderfx_type_init(ShaderFxTypeInfo *types[])
        INIT_FX_TYPE(Blur);
        INIT_FX_TYPE(Colorize);
        INIT_FX_TYPE(Flip);
+       INIT_FX_TYPE(Glow);
        INIT_FX_TYPE(Light);
        INIT_FX_TYPE(Pixel);
        INIT_FX_TYPE(Rim);
diff --git a/source/blender/shader_fx/intern/fx_shader_glow.c b/source/blender/shader_fx/intern/fx_shader_glow.c
new file mode 100644 (file)
index 0000000..cd513ed
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software  Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Antonio Vazquez
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/shader_fx/intern/FX_shader_glow.c
+ *  \ingroup shader_fx
+ */
+
+#include <stdio.h>
+
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_gpencil_types.h"
+
+#include "BLI_math_base.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_library_query.h"
+#include "BKE_modifier.h"
+#include "BKE_shader_fx.h"
+
+#include "FX_shader_types.h"
+
+static void initData(ShaderFxData *md)
+{
+       GlowShaderFxData *gpfx = (GlowShaderFxData *)md;
+       ARRAY_SET_ITEMS(gpfx->glow_color, 0.75f, 1.0f, 1.0f);
+       ARRAY_SET_ITEMS(gpfx->select_color, 0.0f, 0.0f, 0.0f);
+       gpfx->threshold = 0.1f;
+
+       ARRAY_SET_ITEMS(gpfx->blur, 50, 0);
+       gpfx->samples = 16;
+}
+
+static void copyData(const ShaderFxData *md, ShaderFxData *target)
+{
+       BKE_shaderfx_copyData_generic(md, target);
+}
+
+ShaderFxTypeInfo shaderfx_Type_Glow = {
+       /* name */              "Glow",
+       /* structName */        "GlowShaderFxData",
+       /* structSize */        sizeof(GlowShaderFxData),
+       /* type */              eShaderFxType_GpencilType,
+       /* flags */             0,
+
+       /* copyData */          copyData,
+
+       /* initData */          initData,
+       /* freeData */          NULL,
+       /* isDisabled */        NULL,
+       /* updateDepsgraph */   NULL,
+       /* dependsOnTime */     NULL,
+       /* foreachObjectLink */ NULL,
+       /* foreachIDLink */     NULL,
+};