From 340e4394d43e8c3eed6ef84dafb4093299f22a29 Mon Sep 17 00:00:00 2001 From: Luca Rood Date: Tue, 23 May 2017 14:25:12 +0200 Subject: [PATCH] Use custom shader for dot particles --- source/blender/draw/CMakeLists.txt | 2 ++ source/blender/draw/modes/object_mode.c | 5 ++- .../shaders/object_particle_dot_frag.glsl | 36 +++++++++++++++++++ .../shaders/object_particle_dot_vert.glsl | 23 ++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 source/blender/draw/modes/shaders/object_particle_dot_frag.glsl create mode 100644 source/blender/draw/modes/shaders/object_particle_dot_vert.glsl diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 4b4307f2bd5..a8a6d3144ca 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -164,6 +164,8 @@ data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC) data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC) data_to_c_simple(modes/shaders/object_particle_prim_vert.glsl SRC) data_to_c_simple(modes/shaders/object_particle_prim_frag.glsl SRC) +data_to_c_simple(modes/shaders/object_particle_dot_vert.glsl SRC) +data_to_c_simple(modes/shaders/object_particle_dot_frag.glsl SRC) data_to_c_simple(modes/shaders/paint_texture_frag.glsl SRC) data_to_c_simple(modes/shaders/paint_texture_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC) diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index dbc18e19b41..ee95d4a0598 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -68,6 +68,8 @@ extern char datatoc_object_empty_image_frag_glsl[]; extern char datatoc_object_empty_image_vert_glsl[]; extern char datatoc_object_particle_prim_vert_glsl[]; extern char datatoc_object_particle_prim_frag_glsl[]; +extern char datatoc_object_particle_dot_vert_glsl[]; +extern char datatoc_object_particle_dot_frag_glsl[]; extern char datatoc_common_globals_lib_glsl[]; /* *********** LISTS *********** */ @@ -290,7 +292,7 @@ static void OBJECT_engine_init(void *vedata) } if (!e_data.part_dot_sh) { - e_data.part_dot_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); + e_data.part_dot_sh = DRW_shader_create(datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL); } { @@ -438,6 +440,7 @@ static void OBJECT_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.object_empty_image_wire_sh); DRW_SHADER_FREE_SAFE(e_data.grid_sh); DRW_SHADER_FREE_SAFE(e_data.part_prim_sh); + DRW_SHADER_FREE_SAFE(e_data.part_dot_sh); } static DRWShadingGroup *shgroup_outline(DRWPass *pass, const float col[4], GPUShader *sh) diff --git a/source/blender/draw/modes/shaders/object_particle_dot_frag.glsl b/source/blender/draw/modes/shaders/object_particle_dot_frag.glsl new file mode 100644 index 00000000000..eae5ee633ae --- /dev/null +++ b/source/blender/draw/modes/shaders/object_particle_dot_frag.glsl @@ -0,0 +1,36 @@ + +uniform vec4 color; +uniform vec4 outlineColor; + +in vec4 radii; +out vec4 fragColor; + +void main() { + float dist = length(gl_PointCoord - vec2(0.5)); + +// transparent outside of point +// --- 0 --- +// smooth transition +// --- 1 --- +// pure outline color +// --- 2 --- +// smooth transition +// --- 3 --- +// pure point color +// ... +// dist = 0 at center of point + + float midStroke = 0.5 * (radii[1] + radii[2]); + + if (dist > midStroke) { + fragColor.rgb = outlineColor.rgb; + fragColor.a = mix(outlineColor.a, 0.0, smoothstep(radii[1], radii[0], dist)); + } + else { + fragColor = mix(color, outlineColor, smoothstep(radii[3], radii[2], dist)); + } + + if (fragColor.a == 0.0) { + discard; + } +} diff --git a/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl b/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl new file mode 100644 index 00000000000..d9d30c8e677 --- /dev/null +++ b/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl @@ -0,0 +1,23 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float size; + +in vec3 pos; +out vec4 radii; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_PointSize = size; + + // calculate concentric radii in pixels + float radius = 0.5 * size; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + radii[2] = radius - 1.0; + radii[3] = radius - 2.0; + + // convert to PointCoord units + radii /= size; +}