[Bf-blender-cvs] [42804d49b54] blender2.8: Implement particle drawing with draw manager

Luca Rood noreply at git.blender.org
Fri May 19 17:24:17 CEST 2017


Commit: 42804d49b54a4522423849c402b6d55521b18512
Author: Luca Rood
Date:   Fri May 19 17:13:48 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB42804d49b54a4522423849c402b6d55521b18512

Implement particle drawing with draw manager

This still has a couple of issues:
* Instancing is not working when multiple particle systems use the same
primitive. Only the last particle system to be drawn with a particular
primitive shows up.

* Because of colors being passed as uniforms with static variables, the
color of the collection of the last object to be evauluated is used for
all particles being displayed.

Also, note that while this is being drawn in the clay engine, this might
be moved to the object mode later intead.

Part of T51378

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/clay/clay_engine.c
A	source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl
A	source/blender/draw/engines/clay/shaders/particle_prim_vert.glsl
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_particles.c

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 45c52187f72..ac648fe1e5b 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -111,6 +111,8 @@ data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
 data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
 data_to_c_simple(engines/clay/shaders/particle_vert.glsl SRC)
 data_to_c_simple(engines/clay/shaders/particle_strand_frag.glsl SRC)
+data_to_c_simple(engines/clay/shaders/particle_prim_vert.glsl SRC)
+data_to_c_simple(engines/clay/shaders/particle_prim_frag.glsl SRC)
 
 data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index 8e66b287fda..4bb8920a2f9 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -31,6 +31,8 @@
 #include "BLI_dynstr.h"
 #include "BLI_rand.h"
 
+#include "GPU_shader.h"
+
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
@@ -56,6 +58,8 @@ extern char datatoc_clay_vert_glsl[];
 extern char datatoc_ssao_alchemy_glsl[];
 extern char datatoc_particle_vert_glsl[];
 extern char datatoc_particle_strand_frag_glsl[];
+extern char datatoc_particle_prim_vert_glsl[];
+extern char datatoc_particle_prim_frag_glsl[];
 
 /* *********** LISTS *********** */
 
@@ -128,6 +132,7 @@ typedef struct CLAY_PassList {
 	struct DRWPass *clay_pass;
 	struct DRWPass *clay_pass_flat;
 	struct DRWPass *hair_pass;
+	struct DRWPass *part_pass;
 } CLAY_PassList;
 
 typedef struct CLAY_Data {
@@ -147,6 +152,8 @@ static struct {
 	struct GPUShader *clay_sh;
 	struct GPUShader *clay_flat_sh;
 	struct GPUShader *hair_sh;
+	struct GPUShader *part_dot_sh;
+	struct GPUShader *part_prim_sh;
 
 	/* Matcap textures */
 	struct GPUTexture *matcap_array;
@@ -175,7 +182,10 @@ typedef struct CLAY_PrivateData {
 	DRWShadingGroup *depth_shgrp_cull;
 	DRWShadingGroup *depth_shgrp_cull_select;
 	DRWShadingGroup *depth_shgrp_cull_active;
-	DRWShadingGroup *hair;
+	DRWShadingGroup *part_dot_shgrp;
+	DRWShadingGroup *part_cross_shgrp;
+	DRWShadingGroup *part_circle_shgrp;
+	DRWShadingGroup *part_axis_shgrp;
 } CLAY_PrivateData; /* Transient data */
 
 /* Functions */
@@ -364,6 +374,14 @@ static void CLAY_engine_init(void *vedata)
 		e_data.hair_sh = DRW_shader_create(datatoc_particle_vert_glsl, NULL, datatoc_particle_strand_frag_glsl, "#define MAX_MATERIAL 512\n");
 	}
 
+	if (!e_data.part_prim_sh) {
+		e_data.part_prim_sh = DRW_shader_create(datatoc_particle_prim_vert_glsl, NULL, datatoc_particle_prim_frag_glsl, NULL);
+	}
+
+	if (!e_data.part_dot_sh) {
+		e_data.part_dot_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+	}
+
 	if (!stl->storage) {
 		stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage");
 	}
@@ -712,6 +730,32 @@ static void CLAY_cache_init(void *vedata)
 		stl->storage->hair_ubo_current_id = 0;
 		memset(stl->storage->hair_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
 	}
+
+	{
+		psl->part_pass = DRW_pass_create("Particle Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_POINT | DRW_STATE_BLEND);
+
+		static int screen_space[2] = {0, 1};
+
+		stl->g_data->part_dot_shgrp = DRW_shgroup_create(e_data.part_dot_sh, psl->part_pass);
+
+		stl->g_data->part_cross_shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->part_pass, DRW_cache_particles_get_prim(PART_DRAW_CROSS));
+		DRW_shgroup_uniform_int(stl->g_data->part_cross_shgrp, "screen_space", &screen_space[0], 1);
+		DRW_shgroup_uniform_float(stl->g_data->part_cross_shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
+		DRW_shgroup_attrib_float(stl->g_data->part_cross_shgrp, "pos", 3);
+		DRW_shgroup_attrib_float(stl->g_data->part_cross_shgrp, "rot", 4);
+
+		stl->g_data->part_circle_shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->part_pass, DRW_cache_particles_get_prim(PART_DRAW_CIRC));
+		DRW_shgroup_uniform_int(stl->g_data->part_circle_shgrp, "screen_space", &screen_space[1], 1);
+		DRW_shgroup_uniform_float(stl->g_data->part_circle_shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
+		DRW_shgroup_attrib_float(stl->g_data->part_circle_shgrp, "pos", 3);
+		DRW_shgroup_attrib_float(stl->g_data->part_circle_shgrp, "rot", 4);
+
+		stl->g_data->part_axis_shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->part_pass, DRW_cache_particles_get_prim(PART_DRAW_AXIS));
+		DRW_shgroup_uniform_int(stl->g_data->part_axis_shgrp, "screen_space", &screen_space[0], 1);
+		DRW_shgroup_uniform_float(stl->g_data->part_axis_shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
+		DRW_shgroup_attrib_float(stl->g_data->part_axis_shgrp, "pos", 3);
+		DRW_shgroup_attrib_float(stl->g_data->part_axis_shgrp, "rot", 4);
+	}
 }
 
 static void CLAY_cache_populate(void *vedata, Object *ob)
@@ -780,21 +824,67 @@ static void CLAY_cache_populate(void *vedata, Object *ob)
 						draw_as = PART_DRAW_DOT;
 					}
 
-					switch (draw_as) {
-						case PART_DRAW_PATH:
-							geom = DRW_cache_particles_get_hair(psys);
-							break;
-						default:
-							geom = NULL;
-							break;
-					}
+					static float mat[4][4];
+					unit_m4(mat);
 
-					if (geom) {
-						static float mat[4][4];
-						unit_m4(mat);
+					if (draw_as == PART_DRAW_PATH) {
+						geom = DRW_cache_particles_get_hair(psys);
 						hair_shgrp = CLAY_hair_shgrp_get(ob, stl, psl);
 						DRW_shgroup_call_add(hair_shgrp, geom, mat);
 					}
+					else {
+						IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
+						int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon");
+						float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue");
+						float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation");
+						float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value");
+						static float size;
+						static float axis_size;
+						static float col[4];
+						float hsv[3];
+
+						size = (float)part->draw_size;
+						axis_size = size * 2.0f;
+
+						copy_v3_v3(col, e_data.matcap_colors[matcap_to_index(matcap_icon)]);
+						rgb_to_hsv_v(col, hsv);
+
+						hsv[0] = fmod(hsv[0] + matcap_hue - 0.5f, 1.0f);
+						hsv[1] *= matcap_sat * 2.0f;
+						CLAMP(hsv[1], 0.0f, 1.0f);
+						hsv[2] *= matcap_val * 2.0f;
+						CLAMP(hsv[2], 0.0f, 1.0f);
+
+						hsv_to_rgb_v(hsv, col);
+						col[3] = 1.0f;
+
+						geom = DRW_cache_particles_get_dots(psys);
+
+						switch (draw_as) {
+							case PART_DRAW_DOT:
+								DRW_shgroup_uniform_vec4(stl->g_data->part_dot_shgrp, "color", col, 1);
+								DRW_shgroup_uniform_float(stl->g_data->part_dot_shgrp, "size", &size, 1);
+								DRW_shgroup_call_add(stl->g_data->part_dot_shgrp, geom, mat);
+								break;
+							case PART_DRAW_CROSS:
+								DRW_shgroup_uniform_vec4(stl->g_data->part_cross_shgrp, "color", col, 1);
+								DRW_shgroup_uniform_float(stl->g_data->part_cross_shgrp, "draw_size", &size, 1);
+								DRW_shgroup_instance_batch(stl->g_data->part_cross_shgrp, geom);
+								break;
+							case PART_DRAW_CIRC:
+								DRW_shgroup_uniform_vec4(stl->g_data->part_circle_shgrp, "color", col, 1);
+								DRW_shgroup_uniform_float(stl->g_data->part_circle_shgrp, "draw_size", &size, 1);
+								DRW_shgroup_instance_batch(stl->g_data->part_circle_shgrp, geom);
+								break;
+							case PART_DRAW_AXIS:
+								DRW_shgroup_uniform_vec4(stl->g_data->part_axis_shgrp, "color", col, 1);
+								DRW_shgroup_uniform_float(stl->g_data->part_axis_shgrp, "draw_size", &axis_size, 1);
+								DRW_shgroup_instance_batch(stl->g_data->part_axis_shgrp, geom);
+								break;
+							default:
+								break;
+						}
+					}
 				}
 			}
 		}
@@ -839,6 +929,7 @@ static void CLAY_draw_scene(void *vedata)
 	DRW_draw_pass(psl->clay_pass);
 	DRW_draw_pass(psl->clay_pass_flat);
 	DRW_draw_pass(psl->hair_pass);
+	DRW_draw_pass(psl->part_pass);
 }
 
 static void CLAY_layer_collection_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
@@ -874,6 +965,7 @@ static void CLAY_engine_free(void)
 	DRW_SHADER_FREE_SAFE(e_data.clay_sh);
 	DRW_SHADER_FREE_SAFE(e_data.clay_flat_sh);
 	DRW_SHADER_FREE_SAFE(e_data.hair_sh);
+	DRW_SHADER_FREE_SAFE(e_data.part_prim_sh);
 	DRW_TEXTURE_FREE_SAFE(e_data.matcap_array);
 	DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
 	DRW_TEXTURE_FREE_SAFE(e_data.sampling_tx);
diff --git a/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl b/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl
new file mode 100644
index 00000000000..50572f293d9
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl
@@ -0,0 +1,19 @@
+
+uniform vec4 color;
+
+flat in int finalAxis;
+
+out vec4 fragColor;
+
+void main()
+{
+	if (finalAxis == -1) {
+		fragColor = color;
+	}
+	else {
+		vec4 col = vec4(0.0);
+		col[finalAxis] = 1.0;
+		col.a = 1.0;
+		fragColor = col;
+	}
+}
diff --git a/source/blender/draw/engines/clay/shaders/particle_prim_vert.glsl b/source/blender/draw/engines/clay/shaders/particle_prim_vert.glsl
new file mode 100644
index 00000000000..2483ca5b2d2
--- /dev/null
+++ b/source/blender/draw/engines/clay/shaders/particle_prim_vert.glsl
@@ -0,0 +1,43 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ViewProjectionMatrix;
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform int screen_space;
+uniform float pixel_size;
+uniform float draw_size;
+
+in vec3 pos;
+in vec4 rot;
+in vec3 inst_pos;
+in int axis;
+
+flat out int finalAxis;
+
+vec3 rotate(vec3 vec, vec4 quat)
+{
+	/* The quaternion representation here stores the w component in the first index */
+	return vec + 2.0 * cross(quat.yzw, cross(quat.yzw, vec) + quat.x * vec);
+}
+
+float mul_project_m4_v3_zfac(in vec3 co)
+{
+	return (ViewProjectionMatrix[0][3] * co.x) +
+	       (ViewProjectionMatrix[1][3] * co.y) +
+	       (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatr

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list