From 7ad71174fe9a55227cbcdfdbd793248a416d59c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Sat, 30 Jun 2018 15:07:03 +0100 Subject: Remove the parent interpolation hair shader and use the transform-feedback shader instead. --- .../draw/intern/draw_cache_impl_particles.c | 31 ---------------------- 1 file changed, 31 deletions(-) (limited to 'source/blender/draw/intern/draw_cache_impl_particles.c') diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 28693b47c89..69b30dc7f17 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -162,37 +162,6 @@ static void particle_batch_cache_clear_point(ParticlePointCache *point_cache) GWN_VERTBUF_DISCARD_SAFE(point_cache->pos); } -static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache) -{ - /* TODO more granular update tagging. */ - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_point_buf); - DRW_TEXTURE_FREE_SAFE(hair_cache->point_tex); - - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_buf); - DRW_TEXTURE_FREE_SAFE(hair_cache->strand_tex); - - for (int i = 0; i < MAX_MTFACE; ++i) { - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_uv_buf[i]); - DRW_TEXTURE_FREE_SAFE(hair_cache->uv_tex[i]); - } - for (int i = 0; i < MAX_MCOL; ++i) { - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_col_buf[i]); - DRW_TEXTURE_FREE_SAFE(hair_cache->col_tex[i]); - } - for (int i = 0; i < MAX_HAIR_SUBDIV; ++i) { - GWN_VERTBUF_DISCARD_SAFE(hair_cache->final[i].proc_buf); - DRW_TEXTURE_FREE_SAFE(hair_cache->final[i].proc_tex); - for (int j = 0; j < MAX_THICKRES; ++j) { - GWN_BATCH_DISCARD_SAFE(hair_cache->final[i].proc_hairs[j]); - } - } - - /* "Normal" legacy hairs */ - GWN_BATCH_DISCARD_SAFE(hair_cache->hairs); - GWN_VERTBUF_DISCARD_SAFE(hair_cache->pos); - GWN_INDEXBUF_DISCARD_SAFE(hair_cache->indices); -} - static void particle_batch_cache_clear(ParticleSystem *psys) { ParticleBatchCache *cache = psys->batch_cache; -- cgit v1.2.3 From 47912ef922651697013f1d0db31884d83b667b2b Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Sun, 15 Jul 2018 09:12:33 +0100 Subject: Rename proc_buf to proc_point_buf to make it consistent with the main control point buffer. --- source/blender/draw/intern/draw_cache_impl_particles.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source/blender/draw/intern/draw_cache_impl_particles.c') diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 56464b008ed..7181e36c4bf 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -726,16 +726,16 @@ static void particle_batch_cache_ensure_procedural_final_points( Gwn_VertFormat format = { 0 }; GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - cache->final[subdiv].proc_buf = GWN_vertbuf_create_with_format(&format); + cache->final[subdiv].proc_point_buf = GWN_vertbuf_create_with_format(&format); /* Create a destination buffer for the tranform feedback. Sized appropriately */ /* Thoses are points! not line segments. */ - GWN_vertbuf_data_alloc(cache->final[subdiv].proc_buf, cache->final[subdiv].strands_res * cache->strands_len); + GWN_vertbuf_data_alloc(cache->final[subdiv].proc_point_buf, cache->final[subdiv].strands_res * cache->strands_len); /* Create vbo immediatly to bind to texture buffer. */ - GWN_vertbuf_use(cache->final[subdiv].proc_buf); + GWN_vertbuf_use(cache->final[subdiv].proc_point_buf); - cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf(cache->final[subdiv].proc_buf); + cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf(cache->final[subdiv].proc_point_buf); } static void particle_batch_cache_ensure_procedural_strand_data( @@ -1543,7 +1543,7 @@ bool particles_ensure_procedural_data( } /* Refreshed only on subdiv count change. */ - if ((*r_hair_cache)->final[subdiv].proc_buf == NULL) { + if ((*r_hair_cache)->final[subdiv].proc_point_buf == NULL) { particle_batch_cache_ensure_procedural_final_points(&cache->hair, subdiv); need_ft_update = true; } -- cgit v1.2.3 From 8915d9ed0d804dbd68f93751a17bde7794a81b54 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Sun, 15 Jul 2018 11:14:10 +0100 Subject: Change the uniform strand_res value to strands_len, point_len and elem_len counts. --- .../draw/intern/draw_cache_impl_particles.c | 46 ++++++++++++++++------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'source/blender/draw/intern/draw_cache_impl_particles.c') diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 7181e36c4bf..f62384cbae8 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -623,19 +623,26 @@ static void particle_batch_cache_fill_segments_proc_pos( } static int particle_batch_cache_fill_segments_indices( + const ParticleSystem *psys, ParticleCacheKey **path_cache, const int start_index, const int num_path_keys, - const int res, + const int subdiv, + const int thickness_res, Gwn_IndexBufBuilder *elb) { + const ParticleSettings *part = psys->part; + const int strands_res = 1 << (part->draw_step + subdiv); + const int verts_per_hair = strands_res * thickness_res; + int curr_point = start_index; for (int i = 0; i < num_path_keys; i++) { ParticleCacheKey *path = path_cache[i]; if (path->segments <= 0) { continue; } - for (int k = 0; k < res; k++) { + + for (int k = 0; k < verts_per_hair; k++) { GWN_indexbuf_add_generic_vert(elb, curr_point++); } GWN_indexbuf_add_primitive_restart(elb); @@ -718,6 +725,25 @@ static int particle_batch_cache_fill_strands_data( return curr_point; } +static void ensure_seg_pt_final_count( + const ParticleSystem *psys, + ParticleHairCache *hair_cache, + int subdiv, + int thickness_res) +{ + ParticleHairFinalCache *final_cache = &hair_cache->final[subdiv]; + + const ParticleSettings *part = psys->part; + const int strands_res = 1 << (part->draw_step + subdiv); + + final_cache->strands_len = hair_cache->strands_len; + final_cache->point_len = strands_res * final_cache->strands_len; + + const int verts_per_hair = strands_res * thickness_res; + /* +1 for primitive restart */ + final_cache->elems_len = (verts_per_hair + 1) * final_cache->strands_len; +} + static void particle_batch_cache_ensure_procedural_final_points( ParticleHairCache *cache, int subdiv) @@ -730,7 +756,7 @@ static void particle_batch_cache_ensure_procedural_final_points( /* Create a destination buffer for the tranform feedback. Sized appropriately */ /* Thoses are points! not line segments. */ - GWN_vertbuf_data_alloc(cache->final[subdiv].proc_point_buf, cache->final[subdiv].strands_res * cache->strands_len); + GWN_vertbuf_data_alloc(cache->final[subdiv].proc_point_buf, cache->final[subdiv].point_len); /* Create vbo immediatly to bind to texture buffer. */ GWN_vertbuf_use(cache->final[subdiv].proc_point_buf); @@ -909,9 +935,7 @@ static void particle_batch_cache_ensure_procedural_indices( return; } - int verts_per_hair = cache->final[subdiv].strands_res * thickness_res; - /* +1 for primitive restart */ - int element_count = (verts_per_hair + 1) * cache->strands_len; + int element_count = cache->final[subdiv].elems_len; Gwn_PrimType prim_type = (thickness_res == 1) ? GWN_PRIM_LINE_STRIP : GWN_PRIM_TRI_STRIP; static Gwn_VertFormat format = { 0 }; @@ -928,7 +952,7 @@ static void particle_batch_cache_ensure_procedural_indices( if (edit != NULL && edit->pathcache != NULL) { particle_batch_cache_fill_segments_indices( - edit->pathcache, 0, edit->totcached, verts_per_hair, &elb); + psys, edit->pathcache, 0, edit->totcached, subdiv, thickness_res, &elb); } else { int curr_point = 0; @@ -936,12 +960,12 @@ static void particle_batch_cache_ensure_procedural_indices( (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) { curr_point = particle_batch_cache_fill_segments_indices( - psys->pathcache, 0, psys->totpart, verts_per_hair, &elb); + psys, psys->pathcache, 0, psys->totpart, subdiv, thickness_res, &elb); } if (psys->childcache) { const int child_count = psys->totchild * psys->part->disp / 100; curr_point = particle_batch_cache_fill_segments_indices( - psys->childcache, curr_point, child_count, verts_per_hair, &elb); + psys, psys->childcache, curr_point, child_count, subdiv, thickness_res, &elb); } } @@ -1524,12 +1548,9 @@ bool particles_ensure_procedural_data( ParticleDrawSource source; drw_particle_get_hair_source(object, psys, md, NULL, &source); - ParticleSettings *part = source.psys->part; ParticleBatchCache *cache = particle_batch_cache_get(source.psys); *r_hair_cache = &cache->hair; - (*r_hair_cache)->final[subdiv].strands_res = 1 << (part->draw_step + subdiv); - /* Refreshed on combing and simulation. */ if ((*r_hair_cache)->proc_point_buf == NULL) { ensure_seg_pt_count(source.edit, source.psys, &cache->hair); @@ -1544,6 +1565,7 @@ bool particles_ensure_procedural_data( /* Refreshed only on subdiv count change. */ if ((*r_hair_cache)->final[subdiv].proc_point_buf == NULL) { + ensure_seg_pt_final_count(psys, &cache->hair, subdiv, thickness_res); particle_batch_cache_ensure_procedural_final_points(&cache->hair, subdiv); need_ft_update = true; } -- cgit v1.2.3 From 58979947bcd3c88c517580c9888dea74e16451e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Sun, 22 Jul 2018 12:46:26 +0100 Subject: Correct point and element counts for particle hair. --- source/blender/draw/intern/draw_cache_impl_particles.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source/blender/draw/intern/draw_cache_impl_particles.c') diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index f62384cbae8..0d29debfae1 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -632,8 +632,8 @@ static int particle_batch_cache_fill_segments_indices( Gwn_IndexBufBuilder *elb) { const ParticleSettings *part = psys->part; - const int strands_res = 1 << (part->draw_step + subdiv); - const int verts_per_hair = strands_res * thickness_res; + const int points_per_curve = (1 << (part->draw_step + subdiv)) + 1; + const int points_per_hair = points_per_curve * thickness_res; int curr_point = start_index; for (int i = 0; i < num_path_keys; i++) { @@ -642,7 +642,7 @@ static int particle_batch_cache_fill_segments_indices( continue; } - for (int k = 0; k < verts_per_hair; k++) { + for (int k = 0; k < points_per_hair; k++) { GWN_indexbuf_add_generic_vert(elb, curr_point++); } GWN_indexbuf_add_primitive_restart(elb); @@ -734,14 +734,13 @@ static void ensure_seg_pt_final_count( ParticleHairFinalCache *final_cache = &hair_cache->final[subdiv]; const ParticleSettings *part = psys->part; - const int strands_res = 1 << (part->draw_step + subdiv); - + const int points_per_curve = (1 << (part->draw_step + subdiv)) + 1; + final_cache->strands_len = hair_cache->strands_len; - final_cache->point_len = strands_res * final_cache->strands_len; + final_cache->point_len = points_per_curve * final_cache->strands_len; - const int verts_per_hair = strands_res * thickness_res; /* +1 for primitive restart */ - final_cache->elems_len = (verts_per_hair + 1) * final_cache->strands_len; + final_cache->elems_len = (points_per_curve * thickness_res + 1) * final_cache->strands_len; } static void particle_batch_cache_ensure_procedural_final_points( -- cgit v1.2.3 From f854fefa1796429907c2574ba414335eb5519714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Sun, 12 Aug 2018 10:33:21 +0100 Subject: Separate buffer texture for hair index for each vertex. This is needed for allowing variable length hair strands, where the hair index can not simply be calculated from the vertex index based on a fixed-length strand. --- .../draw/intern/draw_cache_impl_particles.c | 54 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'source/blender/draw/intern/draw_cache_impl_particles.c') diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 0d29debfae1..da360f89051 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -743,13 +743,23 @@ static void ensure_seg_pt_final_count( final_cache->elems_len = (points_per_curve * thickness_res + 1) * final_cache->strands_len; } +#define USE_POSITION_HAIR_INDEX + static void particle_batch_cache_ensure_procedural_final_points( + const ParticleSystem *psys, ParticleHairCache *cache, int subdiv) { + /* Same format as point_tex. */ +#ifdef USE_POSITION_HAIR_INDEX + static Gwn_VertFormat format = { 0 }; + GWN_vertformat_clear(&format); + uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); +#else Gwn_VertFormat format = { 0 }; GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); +#endif cache->final[subdiv].proc_point_buf = GWN_vertbuf_create_with_format(&format); @@ -757,12 +767,53 @@ static void particle_batch_cache_ensure_procedural_final_points( /* Thoses are points! not line segments. */ GWN_vertbuf_data_alloc(cache->final[subdiv].proc_point_buf, cache->final[subdiv].point_len); +#ifdef USE_POSITION_HAIR_INDEX + Gwn_VertBufRaw data_step; + GWN_vertbuf_attr_get_raw_data(cache->final[subdiv].proc_point_buf, pos_id, &data_step); + const int points_per_curve = (1 << (psys->part->draw_step + subdiv)) + 1; + for (int i = 0; i < cache->final[subdiv].strands_len; i++) { + for (int j = 0; j < points_per_curve; ++j) { + uint *data = (uint *)GWN_vertbuf_raw_step(&data_step); + *data = (uint)i; + } + } +#endif + /* Create vbo immediatly to bind to texture buffer. */ GWN_vertbuf_use(cache->final[subdiv].proc_point_buf); cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf(cache->final[subdiv].proc_point_buf); } +static void particle_batch_cache_ensure_procedural_final_hair_index( + const ParticleSystem *psys, + ParticleHairCache *cache, + int subdiv) +{ + /* Same format as point_tex. */ + Gwn_VertFormat format = { 0 }; + uint hair_index_id = GWN_vertformat_attr_add(&format, "hair_index", GWN_COMP_U32, 1, GWN_FETCH_INT); + + cache->final[subdiv].proc_hair_index_buf = GWN_vertbuf_create_with_format(&format); + + GWN_vertbuf_data_alloc(cache->final[subdiv].proc_hair_index_buf, cache->final[subdiv].point_len); + + Gwn_VertBufRaw data_step; + GWN_vertbuf_attr_get_raw_data(cache->final[subdiv].proc_hair_index_buf, hair_index_id, &data_step); + const int points_per_curve = (1 << (psys->part->draw_step + subdiv)) + 1; + for (int i = 0; i < cache->final[subdiv].strands_len; i++) { + for (int j = 0; j < points_per_curve; ++j) { + uint *data = (uint *)GWN_vertbuf_raw_step(&data_step); + *data = (uint)i; + } + } + + /* Create vbo immediatly to bind to texture buffer. */ + GWN_vertbuf_use(cache->final[subdiv].proc_hair_index_buf); + + cache->final[subdiv].hair_index_tex = GPU_texture_create_from_vertbuf(cache->final[subdiv].proc_hair_index_buf); +} + static void particle_batch_cache_ensure_procedural_strand_data( PTCacheEdit *edit, ParticleSystem *psys, @@ -1565,7 +1616,8 @@ bool particles_ensure_procedural_data( /* Refreshed only on subdiv count change. */ if ((*r_hair_cache)->final[subdiv].proc_point_buf == NULL) { ensure_seg_pt_final_count(psys, &cache->hair, subdiv, thickness_res); - particle_batch_cache_ensure_procedural_final_points(&cache->hair, subdiv); + particle_batch_cache_ensure_procedural_final_points(psys, &cache->hair, subdiv); + particle_batch_cache_ensure_procedural_final_hair_index(psys, &cache->hair, subdiv); need_ft_update = true; } if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == NULL) { -- cgit v1.2.3