Implement particle velocity and acceleration visualization
authorLuca Rood <dev@lucarood.com>
Tue, 23 May 2017 14:56:53 +0000 (16:56 +0200)
committerLuca Rood <dev@lucarood.com>
Tue, 23 May 2017 16:39:22 +0000 (18:39 +0200)
source/blender/draw/intern/draw_cache_impl_particles.c
source/blender/draw/intern/draw_common.c
source/blender/draw/intern/draw_manager.c
source/blender/draw/modes/object_mode.c
source/blender/draw/modes/shaders/object_particle_dot_frag.glsl
source/blender/draw/modes/shaders/object_particle_dot_vert.glsl
source/blender/draw/modes/shaders/object_particle_prim_frag.glsl
source/blender/draw/modes/shaders/object_particle_prim_vert.glsl

index e51873ca9a5f71fe1f39452801e3cbdf88532921..f4b16f1873acb9079241d2a4e0095585e8dc2b0b 100644 (file)
@@ -272,7 +272,7 @@ static void particle_batch_cache_ensure_pos(ParticleSystem *psys, ParticleBatchC
 {
        if (cache->pos == NULL) {
                static VertexFormat format = { 0 };
-               static unsigned pos_id, rot_id;
+               static unsigned pos_id, rot_id, val_id;
                int i, curr_point;
                ParticleData *pa;
 
@@ -283,6 +283,7 @@ static void particle_batch_cache_ensure_pos(ParticleSystem *psys, ParticleBatchC
                        /* initialize vertex format */
                        pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
                        rot_id = VertexFormat_add_attrib(&format, "rot", COMP_F32, 4, KEEP_FLOAT);
+                       val_id = VertexFormat_add_attrib(&format, "val", COMP_F32, 1, KEEP_FLOAT);
                }
 
                cache->pos = VertexBuffer_create_with_format(&format);
@@ -292,9 +293,25 @@ static void particle_batch_cache_ensure_pos(ParticleSystem *psys, ParticleBatchC
                        if (pa->state.time >= pa->time && pa->state.time < pa->dietime &&
                            !(pa->flag & (PARS_NO_DISP | PARS_UNEXIST)))
                        {
+                               float val;
+
                                VertexBuffer_set_attrib(cache->pos, pos_id, curr_point, pa->state.co);
                                VertexBuffer_set_attrib(cache->pos, rot_id, curr_point, pa->state.rot);
 
+                               switch (psys->part->draw_col) {
+                                       case PART_DRAW_COL_VEL:
+                                               val = len_v3(pa->state.vel) / psys->part->color_vec_max;
+                                               break;
+                                       case PART_DRAW_COL_ACC:
+                                               val = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * psys->part->color_vec_max);
+                                               break;
+                                       default:
+                                               val = -1.0f;
+                                               break;
+                               }
+
+                               VertexBuffer_set_attrib(cache->pos, val_id, curr_point, &val);
+
                                curr_point++;
                        }
                }
index 6d6df8dc6f47bcb21b65d0476b2991740fd40d9e..69474fb1aedc11c422b775a700e1b970c6965fbf 100644 (file)
 #include "DRW_render.h"
 
 #include "GPU_shader.h"
+#include "GPU_texture.h"
 
 #include "UI_resources.h"
 
 #include "BKE_global.h"
+#include "BKE_texture.h"
 
 #include "draw_common.h"
 
@@ -44,6 +46,7 @@
 /* Colors & Constant */
 GlobalsUboStorage ts;
 struct GPUUniformBuffer *globals_ubo = NULL;
+struct GPUTexture *globals_ramp = NULL;
 
 void DRW_globals_update(void)
 {
@@ -110,6 +113,26 @@ void DRW_globals_update(void)
        }
 
        globals_ubo = DRW_uniformbuffer_create(sizeof(GlobalsUboStorage), &ts);
+
+       ColorBand ramp = {0};
+       float *colors;
+       int col_size;
+
+       ramp.tot = 3;
+       ramp.data[0].a = 1.0f;
+       ramp.data[0].b = 1.0f;
+       ramp.data[0].pos = 0.0f;
+       ramp.data[1].a = 1.0f;
+       ramp.data[1].g = 1.0f;
+       ramp.data[1].pos = 0.5f;
+       ramp.data[2].a = 1.0f;
+       ramp.data[2].r = 1.0f;
+       ramp.data[2].pos = 1.0f;
+
+       colorband_table_RGBA(&ramp, &colors, &col_size);
+       globals_ramp = GPU_texture_create_1D(col_size, colors, NULL);
+
+       MEM_freeN(colors);
 }
 
 /* ********************************* SHGROUP ************************************* */
index e561acca021a56d110276e859919a0a3443f292a..5765a5a7292ca67d89b98977bd9f56892d6784b6 100644 (file)
@@ -3265,6 +3265,7 @@ void DRW_engines_register(void)
 }
 
 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GPUTexture *globals_ramp; /* draw_common.c */
 void DRW_engines_free(void)
 {
        DRW_shape_cache_free();
@@ -3282,6 +3283,9 @@ void DRW_engines_free(void)
        if (globals_ubo)
                GPU_uniformbuffer_free(globals_ubo);
 
+       if (globals_ramp)
+               GPU_texture_free(globals_ramp);
+
 #ifdef WITH_CLAY_ENGINE
        BLI_remlink(&R_engines, &DRW_engine_viewport_clay_type);
 #endif
index 0259e1055afc23bd738e03aa94cb114e0165c259..05c9488ba821f1c2d73d5dcc8755c90628bab325 100644 (file)
@@ -43,6 +43,7 @@
 #include "BKE_global.h"
 #include "BKE_particle.h"
 #include "BKE_image.h"
+#include "BKE_texture.h"
 
 #include "ED_view3d.h"
 #include "ED_view3d.h"
@@ -57,6 +58,7 @@
 #include "draw_common.h"
 
 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GPUTexture *globals_ramp; /* draw_common.c */
 extern GlobalsUboStorage ts;
 
 extern char datatoc_object_outline_resolve_frag_glsl[];
@@ -1414,6 +1416,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
                                                                DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
                                                                DRW_shgroup_uniform_vec3(shgrp, "outlineColor", ma ? &ma->specr : def_sec_col, 1);
                                                                DRW_shgroup_uniform_short_to_int(shgrp, "size", &part->draw_size, 1);
+                                                               DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
                                                                DRW_shgroup_call_add(shgrp, geom, mat);
                                                                break;
                                                        case PART_DRAW_CROSS:
@@ -1435,9 +1438,11 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
                                                if (draw_as != PART_DRAW_DOT) {
                                                        DRW_shgroup_attrib_float(shgrp, "pos", 3);
                                                        DRW_shgroup_attrib_float(shgrp, "rot", 4);
+                                                       DRW_shgroup_attrib_float(shgrp, "val", 1);
                                                        DRW_shgroup_uniform_vec3(shgrp, "color", &ma->r, 1);
                                                        DRW_shgroup_uniform_short_to_int(shgrp, "draw_size", &part->draw_size, 1);
                                                        DRW_shgroup_uniform_float(shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
+                                                       DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
                                                        DRW_shgroup_instance_batch(shgrp, geom);
                                                }
                                        }
index 044a949ef98c6b959b15c32cd469767bfb180222..e8bf788470192fc2093575de24680f0f60b17639 100644 (file)
@@ -1,8 +1,11 @@
 
 uniform vec3 color;
 uniform vec3 outlineColor;
+uniform sampler1D ramp;
 
 in vec4 radii;
+flat in float finalVal;
+
 out vec4 fragColor;
 
 void main() {
@@ -23,11 +26,23 @@ void main() {
        float midStroke = 0.5 * (radii[1] + radii[2]);
 
        if (dist > midStroke) {
-               fragColor.rgb = outlineColor;
+               if (finalVal < 0.0) {
+                       fragColor.rgb = outlineColor;
+               }
+               else {
+                       fragColor.rgb = texture(ramp, finalVal).rgb;
+               }
+
                fragColor.a = mix(1.0, 0.0, smoothstep(radii[1], radii[0], dist));
        }
        else {
-               fragColor.rgb = mix(color, outlineColor, smoothstep(radii[3], radii[2], dist));
+               if (finalVal < 0.0) {
+                       fragColor.rgb = mix(color, outlineColor, smoothstep(radii[3], radii[2], dist));
+               }
+               else {
+                       fragColor.rgb = texture(ramp, finalVal).rgb;
+               }
+
                fragColor.a = 1.0;
        }
 
index 36b665173f15b8c925f544619ba008babac92a92..7b163dbdc31da137f0c698e0f2e07e2d97a821d6 100644 (file)
@@ -3,7 +3,10 @@ uniform mat4 ModelViewProjectionMatrix;
 uniform int size;
 
 in vec3 pos;
+in float val;
+
 out vec4 radii;
+flat out float finalVal;
 
 void main() {
        gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
@@ -20,4 +23,6 @@ void main() {
 
        // convert to PointCoord units
        radii /= size;
+
+       finalVal = val;
 }
index 791d38390a2001d2f9e1350c5adc40a7bb2721c1..0e58d70b69bf720395a3e044360cbe4aa7cfe6f1 100644 (file)
@@ -1,14 +1,21 @@
 
 uniform vec3 color;
+uniform sampler1D ramp;
 
 flat in int finalAxis;
+flat in float finalVal;
 
 out vec4 fragColor;
 
 void main()
 {
        if (finalAxis == -1) {
-               fragColor.rgb = color;
+               if (finalVal < 0.0) {
+                       fragColor.rgb = color;
+               }
+               else {
+                       fragColor.rgb = texture(ramp, finalVal).rgb;
+               }
        }
        else {
                fragColor.rgb = vec3(0.0);
index ff16f61b88479fb125f19559e3f81aeb73aaa37c..7b328c73de393fdbabc9d3bbe9a5f56b02861ce5 100644 (file)
@@ -9,10 +9,12 @@ uniform int draw_size;
 
 in vec3 pos;
 in vec4 rot;
+in float val;
 in vec3 inst_pos;
 in int axis;
 
 flat out int finalAxis;
+flat out float finalVal;
 
 vec3 rotate(vec3 vec, vec4 quat)
 {
@@ -46,4 +48,5 @@ void main()
        }
 
        finalAxis = axis;
+       finalVal = val;
 }