diff options
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_particles.c | 30 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_hair.c | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_hair_private.h | 6 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/common_hair_lib.glsl | 18 |
4 files changed, 28 insertions, 27 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index def425e3c7c..b23d5e0fb9c 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -185,7 +185,9 @@ static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache) DRW_TEXTURE_FREE_SAFE(hair_cache->point_tex); GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_buf); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_seg_buf); DRW_TEXTURE_FREE_SAFE(hair_cache->strand_tex); + DRW_TEXTURE_FREE_SAFE(hair_cache->strand_seg_tex); for (int i = 0; i < MAX_MTFACE; ++i) { GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_uv_buf[i]); @@ -769,7 +771,7 @@ static int particle_batch_cache_fill_strands_data( const ParticleSource particle_source, const int start_index, const int num_path_keys, - GPUVertBufRaw *data_step, + GPUVertBufRaw *data_step, GPUVertBufRaw *seg_step, float (***r_parent_uvs)[2], GPUVertBufRaw *uv_step, MTFace **mtfaces, int num_uv_layers, MCol ***r_parent_mcol, GPUVertBufRaw *col_step, MCol **mcols, int num_col_layers) { @@ -793,12 +795,8 @@ static int particle_batch_cache_fill_strands_data( continue; } - /* XXX: We might need something more robust. - * Adjust shader code accordingly. (see unpack_strand_data() ) */ - BLI_assert((path->segments - 1) <= 0x3FF); - - uint *seg_data = (uint *)GPU_vertbuf_raw_step(data_step); - *seg_data = (curr_point & 0x3FFFFF) | ((path->segments - 1) << 22); + *(uint *)GPU_vertbuf_raw_step(data_step) = curr_point; + *(ushort *)GPU_vertbuf_raw_step(seg_step) = path->segments; curr_point += path->segments + 1; if (psmd != NULL) { @@ -883,7 +881,7 @@ static void particle_batch_cache_ensure_procedural_strand_data( } } - GPUVertBufRaw data_step; + GPUVertBufRaw data_step, seg_step; GPUVertBufRaw uv_step[MAX_MTFACE]; GPUVertBufRaw col_step[MAX_MCOL]; @@ -895,6 +893,9 @@ static void particle_batch_cache_ensure_procedural_strand_data( GPUVertFormat format_data = {0}; uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT); + GPUVertFormat format_seg = {0}; + uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT); + GPUVertFormat format_uv = {0}; uint uv_id = GPU_vertformat_attr_add(&format_uv, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -909,6 +910,10 @@ static void particle_batch_cache_ensure_procedural_strand_data( GPU_vertbuf_data_alloc(cache->proc_strand_buf, cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_strand_buf, data_id, &data_step); + cache->proc_strand_seg_buf = GPU_vertbuf_create_with_format(&format_seg); + GPU_vertbuf_data_alloc(cache->proc_strand_seg_buf, cache->strands_len); + GPU_vertbuf_attr_get_raw_data(cache->proc_strand_seg_buf, seg_id, &seg_step); + /* UV layers */ for (int i = 0; i < cache->num_uv_layers; i++) { cache->proc_uv_buf[i] = GPU_vertbuf_create_with_format(&format_uv); @@ -964,7 +969,7 @@ static void particle_batch_cache_ensure_procedural_strand_data( particle_batch_cache_fill_strands_data( psys, psmd, edit->pathcache, PARTICLE_SOURCE_PARENT, 0, edit->totcached, - &data_step, + &data_step, &seg_step, &parent_uvs, uv_step, (MTFace **)mtfaces, cache->num_uv_layers, &parent_mcol, col_step, (MCol **)mcols, cache->num_col_layers); } @@ -976,7 +981,7 @@ static void particle_batch_cache_ensure_procedural_strand_data( curr_point = particle_batch_cache_fill_strands_data( psys, psmd, psys->pathcache, PARTICLE_SOURCE_PARENT, 0, psys->totpart, - &data_step, + &data_step, &seg_step, &parent_uvs, uv_step, (MTFace **)mtfaces, cache->num_uv_layers, &parent_mcol, col_step, (MCol **)mcols, cache->num_col_layers); } @@ -985,7 +990,7 @@ static void particle_batch_cache_ensure_procedural_strand_data( curr_point = particle_batch_cache_fill_strands_data( psys, psmd, psys->childcache, PARTICLE_SOURCE_CHILDREN, curr_point, child_count, - &data_step, + &data_step, &seg_step, &parent_uvs, uv_step, (MTFace **)mtfaces, cache->num_uv_layers, &parent_mcol, col_step, (MCol **)mcols, cache->num_col_layers); } @@ -1009,6 +1014,9 @@ static void particle_batch_cache_ensure_procedural_strand_data( GPU_vertbuf_use(cache->proc_strand_buf); cache->strand_tex = GPU_texture_create_from_vertbuf(cache->proc_strand_buf); + GPU_vertbuf_use(cache->proc_strand_seg_buf); + cache->strand_seg_tex = GPU_texture_create_from_vertbuf(cache->proc_strand_seg_buf); + for (int i = 0; i < cache->num_uv_layers; i++) { GPU_vertbuf_use(cache->proc_uv_buf[i]); cache->uv_tex[i] = GPU_texture_create_from_vertbuf(cache->proc_uv_buf[i]); diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c index 1d0fb5cb2a8..6c1e44ac8e7 100644 --- a/source/blender/draw/intern/draw_hair.c +++ b/source/blender/draw/intern/draw_hair.c @@ -212,6 +212,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex( DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex); DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex); + DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex); DRW_shgroup_uniform_int(tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1); DRW_shgroup_call_procedural_points_add(tf_shgrp, final_points_len, NULL); } diff --git a/source/blender/draw/intern/draw_hair_private.h b/source/blender/draw/intern/draw_hair_private.h index c77f236e066..8f7cb1fe949 100644 --- a/source/blender/draw/intern/draw_hair_private.h +++ b/source/blender/draw/intern/draw_hair_private.h @@ -54,9 +54,13 @@ typedef struct ParticleHairCache { GPUVertBuf *proc_point_buf; /* Input control points */ GPUTexture *point_tex; - GPUVertBuf *proc_strand_buf; /* Infos of control points strands (segment count and base index) */ + /** Infos of control points strands (segment count and base index) */ + GPUVertBuf *proc_strand_buf; GPUTexture *strand_tex; + GPUVertBuf *proc_strand_seg_buf; + GPUTexture *strand_seg_tex; + GPUVertBuf *proc_uv_buf[MAX_MTFACE]; GPUTexture *uv_tex[MAX_MTFACE]; char uv_layer_names[MAX_MTFACE][MAX_LAYER_NAME_CT][MAX_LAYER_NAME_LEN]; diff --git a/source/blender/draw/modes/shaders/common_hair_lib.glsl b/source/blender/draw/modes/shaders/common_hair_lib.glsl index 9cda44c8f42..14df29f2e94 100644 --- a/source/blender/draw/modes/shaders/common_hair_lib.glsl +++ b/source/blender/draw/modes/shaders/common_hair_lib.glsl @@ -35,22 +35,12 @@ uniform samplerBuffer hairPointBuffer; /* RGBA32F */ /* -- Per strands data -- */ uniform usamplerBuffer hairStrandBuffer; /* R32UI */ +uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */ /* Not used, use one buffer per uv layer */ //uniform samplerBuffer hairUVBuffer; /* RG32F */ //uniform samplerBuffer hairColBuffer; /* RGBA16 linear color */ -void unpack_strand_data(uint data, out int strand_offset, out int strand_segments) -{ -#if 0 /* Pack point count */ - // strand_offset = (data & 0x1FFFFFFFu); - // strand_segments = 1u << (data >> 29u); /* We only need 3 bits to store subdivision level. */ -#else - strand_offset = int(data & 0x003FFFFFu); - strand_segments = int(data >> 22u) + 1; -#endif -} - /* -- Subdivision stage -- */ /** * We use a transform feedback to preprocess the strands and add more subdivision to it. @@ -76,10 +66,8 @@ void hair_get_interp_attrs(out vec4 data0, out vec4 data1, out vec4 data2, out v float local_time = float(gl_VertexID % hairStrandsRes) / float(hairStrandsRes - 1); int hair_id = gl_VertexID / hairStrandsRes; - uint strand_data = texelFetch(hairStrandBuffer, hair_id).x; - - int strand_offset, strand_segments; - unpack_strand_data(strand_data, strand_offset, strand_segments); + int strand_offset = int(texelFetch(hairStrandBuffer, hair_id).x); + int strand_segments = int(texelFetch(hairStrandSegBuffer, hair_id).x); int id = hair_get_base_id(local_time, strand_segments, interp_time); |