Commit: 845732652fa7a3d3a053006d30a76ea39fdc3c47 Author: Luca Rood Date: Mon May 22 12:14:37 2017 +0200 Branches: blender2.8 https://developer.blender.org/rB845732652fa7a3d3a053006d30a76ea39fdc3c47
Implement UBOs for particles This fixes the issue where all particles were drawn with the colors and size of the last psys to be drawn. =================================================================== M source/blender/draw/CMakeLists.txt D source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl M source/blender/draw/modes/object_mode.c A source/blender/draw/modes/shaders/particle_dot_frag.glsl A source/blender/draw/modes/shaders/particle_dot_vert.glsl A source/blender/draw/modes/shaders/particle_prim_frag.glsl R080 source/blender/draw/engines/clay/shaders/particle_prim_vert.glsl source/blender/draw/modes/shaders/particle_prim_vert.glsl =================================================================== diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 3bfa9a15ce3..9bd208b823e 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -111,8 +111,6 @@ 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) @@ -167,6 +165,10 @@ data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC) data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC) +data_to_c_simple(modes/shaders/particle_prim_vert.glsl SRC) +data_to_c_simple(modes/shaders/particle_prim_frag.glsl SRC) +data_to_c_simple(modes/shaders/particle_dot_vert.glsl SRC) +data_to_c_simple(modes/shaders/particle_dot_frag.glsl SRC) list(APPEND INC ) diff --git a/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl b/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl deleted file mode 100644 index 50572f293d9..00000000000 --- a/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl +++ /dev/null @@ -1,19 +0,0 @@ - -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/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 21f5ad97b3d..fb105a8c7e5 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -56,6 +56,8 @@ #include "draw_manager_text.h" #include "draw_common.h" +#define MAX_OBJECT_MAT 512 /* 512 = 9 bit material id */ + extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ extern GlobalsUboStorage ts; @@ -68,9 +70,30 @@ extern char datatoc_object_empty_image_frag_glsl[]; extern char datatoc_object_empty_image_vert_glsl[]; extern char datatoc_particle_prim_vert_glsl[]; extern char datatoc_particle_prim_frag_glsl[]; +extern char datatoc_particle_dot_vert_glsl[]; +extern char datatoc_particle_dot_frag_glsl[]; extern char datatoc_common_globals_lib_glsl[]; /* *********** LISTS *********** */ + +/** + * UBOs data needs to be 16 byte aligned (size of vec4) + * + * Reminder: float, int, bool are 4 bytes + * + * \note struct is expected to be initialized with all pad-bits zero'd + * so we can use 'memcmp' to check for duplicates. Possibly hash data later. + */ +typedef struct OBJECT_PARTICLE_UBO_Material { + float prim_color[3]; + float pad1; + /* - 16 -*/ + float sec_color[3]; + float size; + /* - 16 -*/ +} OBJECT_PARTICLE_UBO_Material; /* 32 bytes */ +BLI_STATIC_ASSERT_ALIGN(OBJECT_PARTICLE_UBO_Material, 16) + typedef struct OBJECT_PassList { struct DRWPass *non_meshes; struct DRWPass *ob_center; @@ -95,7 +118,19 @@ typedef struct OBJECT_FramebufferList { struct GPUFrameBuffer *blur; } OBJECT_FramebufferList; +typedef struct OBJECT_Storage { + /* Materials Parameter UBO */ + OBJECT_PARTICLE_UBO_Material materials[MAX_OBJECT_MAT]; + int particle_ubo_current_id; + DRWShadingGroup *part_dot_shgrps[MAX_OBJECT_MAT]; + DRWShadingGroup *part_cross_shgrps[MAX_OBJECT_MAT]; + DRWShadingGroup *part_circle_shgrps[MAX_OBJECT_MAT]; + DRWShadingGroup *part_axis_shgrps[MAX_OBJECT_MAT]; +} OBJECT_Storage; + typedef struct OBJECT_StorageList { + struct OBJECT_Storage *storage; + struct GPUUniformBuffer *part_mat_ubo; struct OBJECT_PrivateData *g_data; } OBJECT_StorageList; @@ -186,12 +221,6 @@ typedef struct OBJECT_PrivateData{ DRWShadingGroup *wire_select; DRWShadingGroup *wire_select_group; DRWShadingGroup *wire_transform; - - /* Particles */ - DRWShadingGroup *part_dot_shgrp; - DRWShadingGroup *part_cross_shgrp; - DRWShadingGroup *part_circle_shgrp; - DRWShadingGroup *part_axis_shgrp; } OBJECT_PrivateData; /* Transient data */ static struct { @@ -216,6 +245,8 @@ static struct { struct GPUTexture *outlines_depth_tx; struct GPUTexture *outlines_color_tx; struct GPUTexture *outlines_blur_tx; + /* Just a serie of int from 0 to MAX_CLAY_MAT-1 */ + int ubo_mat_idxs[MAX_OBJECT_MAT]; } e_data = {NULL}; /* Engine data */ @@ -235,6 +266,7 @@ enum { static void OBJECT_engine_init(void *vedata) { + OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl; const float *viewport_size = DRW_viewport_size_get(); @@ -292,11 +324,26 @@ static void OBJECT_engine_init(void *vedata) } 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); + e_data.part_prim_sh = DRW_shader_create(datatoc_particle_prim_vert_glsl, NULL, datatoc_particle_prim_frag_glsl, "#define MAX_MATERIAL " STRINGIFY(MAX_OBJECT_MAT) "\n"); } 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_particle_dot_vert_glsl, NULL, datatoc_particle_dot_frag_glsl, "#define MAX_MATERIAL " STRINGIFY(MAX_OBJECT_MAT) "\n"); + } + + if (e_data.ubo_mat_idxs[1] == 0) { + /* Just int to have pointers to them */ + for (int i = 0; i < MAX_OBJECT_MAT; ++i) { + e_data.ubo_mat_idxs[i] = i; + } + } + + if (!stl->storage) { + stl->storage = MEM_callocN(sizeof(OBJECT_Storage), "OBJECT_Storage"); + } + + if (!stl->part_mat_ubo) { + stl->part_mat_ubo = DRW_uniformbuffer_create(sizeof(OBJECT_PARTICLE_UBO_Material) * MAX_OBJECT_MAT, NULL); } { @@ -444,6 +491,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) @@ -989,29 +1037,15 @@ static void OBJECT_cache_init(void *vedata) { /* Particle Pass */ - psl->particle = 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->particle); - - stl->g_data->part_cross_shgrp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, 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->particle, 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->particle, 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); + psl->particle = DRW_pass_create( + "Particle Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_POINT | DRW_STATE_BLEND); + + stl->storage->particle_ubo_current_id = 0; + memset(stl->storage->part_dot_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT); + memset(stl->storage->part_cross_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT); + memset(stl->storage->part_circle_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT); + memset(stl->storage->part_axis_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT); } } @@ -1382,6 +1416,120 @@ static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob) DRW_shgroup_call_dynamic_add(shgroup, ob->obmat[3]); } +static DRWShadingGroup *OBJECT_particle_shgroup_create(DRWPass *pass, int *material_id, OBJECT_PassList *psl, int part_type) +{ + DRWShadingGroup *grp; + + if (part_type == PART_DRAW_DOT) { + grp = DRW_shgroup_create(e_data.part_dot_sh, pass); + } + else { + static int screen_space[2] = {0, 1}; + + grp = DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(part_type)); + DRW_shgroup_uniform_int(grp, "screen_space", &screen_space[part_type == PART_DRAW_CIRC ? 1 : 0], 1); + DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1); + DRW_shgroup_attrib_float(grp, "pos", 3); + DRW_shgroup_attrib_float(grp, "rot", 4); + } + + DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1); + + return grp; +} + +static int search_particle_mat_to_ubo(OBJECT_Storage *storage, const OBJECT_PARTICLE_UBO_Material *particle_mat_ubo_test) +{ + for (int i = 0; i < storage->particle_ubo_current_id; i++) { + OBJECT_PARTICLE_UBO_Material *ubo = &storage->materials[i]; + if (memcmp(ubo, particle_mat_ubo_test, sizeof(*particle_mat_ubo_test)) == 0) { + return i; + } + } + + return -1; +} + +static int push_particle_mat_to_ubo(OBJEC @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs