Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_editstrands.h10
-rw-r--r--source/blender/blenkernel/intern/editstrands.c98
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c54
-rw-r--r--source/blender/draw/intern/draw_cache.c6
-rw-r--r--source/blender/draw/intern/draw_cache.h3
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_strands.c208
7 files changed, 9 insertions, 372 deletions
diff --git a/source/blender/blenkernel/BKE_editstrands.h b/source/blender/blenkernel/BKE_editstrands.h
index 991776deda3..be04edb9fc6 100644
--- a/source/blender/blenkernel/BKE_editstrands.h
+++ b/source/blender/blenkernel/BKE_editstrands.h
@@ -51,8 +51,6 @@ typedef struct BMEditStrands {
/* Scalp mesh for fixing root vertices */
struct DerivedMesh *root_dm;
- struct HairPattern *hair_pattern;
- struct HairGroup *hair_group;
int flag;
@@ -60,7 +58,6 @@ typedef struct BMEditStrands {
unsigned int elem_glbuf; // legacy gpu code
unsigned int dot_glbuf; // legacy gpu code
void *batch_cache;
- void *texture;
} BMEditStrands;
/* BMEditStrands->flag */
@@ -76,13 +73,6 @@ struct BMEditStrands *BKE_editstrands_from_object(struct Object *ob);
void BKE_editstrands_update_linked_customdata(struct BMEditStrands *es);
void BKE_editstrands_free(struct BMEditStrands *es);
-/* === Hair Fibers === */
-
-int* BKE_editstrands_hair_get_fiber_lengths(struct BMEditStrands *es, int subdiv);
-void BKE_editstrands_hair_get_texture_buffer_size(struct BMEditStrands *es, int subdiv, int *r_size,
- int *r_strand_map_start, int *r_strand_vertex_start, int *r_fiber_start);
-void BKE_editstrands_hair_get_texture_buffer(struct BMEditStrands *es, int subdiv, void *texbuffer);
-
/* === Constraints === */
/* Stores vertex locations for temporary reference:
diff --git a/source/blender/blenkernel/intern/editstrands.c b/source/blender/blenkernel/intern/editstrands.c
index adbb4b707aa..74d300751d3 100644
--- a/source/blender/blenkernel/intern/editstrands.c
+++ b/source/blender/blenkernel/intern/editstrands.c
@@ -131,104 +131,6 @@ void BKE_editstrands_free(BMEditStrands *es)
es->root_dm->release(es->root_dm);
}
-/* === Hair fibers === */
-
-typedef struct EditStrandsView {
- HairDrawDataInterface base;
- BMEditStrands *edit;
-} EditStrandsView;
-
-static int get_num_strands(const HairDrawDataInterface *hairdata_)
-{
- const EditStrandsView *strands = (EditStrandsView *)hairdata_;
- BMesh *bm = strands->edit->base.bm;
- return BM_strands_count(bm);
-}
-
-static int get_num_verts(const HairDrawDataInterface *hairdata_)
-{
- const EditStrandsView *strands = (EditStrandsView *)hairdata_;
- BMesh *bm = strands->edit->base.bm;
- return bm->totvert;
-}
-
-static void get_strand_lengths(const HairDrawDataInterface* hairdata_, int *r_lengths)
-{
- const EditStrandsView *strands = (EditStrandsView *)hairdata_;
- BMesh *bm = strands->edit->base.bm;
- BMVert *v;
- BMIter iter;
- int i;
-
- int *length = r_lengths;
- BM_ITER_STRANDS_INDEX(v, &iter, bm, BM_STRANDS_OF_MESH, i) {
- *length = BM_strands_keys_count(v);
- ++length;
- }
-}
-
-static void get_strand_roots(const HairDrawDataInterface* hairdata_, struct MeshSample *r_roots)
-{
- const EditStrandsView *strands = (EditStrandsView *)hairdata_;
- BMesh *bm = strands->edit->base.bm;
- BMVert *v;
- BMIter iter;
- int i;
-
- MeshSample *root = r_roots;
- BM_ITER_STRANDS_INDEX(v, &iter, bm, BM_STRANDS_OF_MESH, i) {
- BM_elem_meshsample_data_named_get(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, root);
- ++root;
- }
-}
-
-static void get_strand_vertices(const HairDrawDataInterface* hairdata_, float (*r_verts)[3])
-{
- const EditStrandsView *strands = (EditStrandsView *)hairdata_;
- BMesh *bm = strands->edit->base.bm;
- BMVert *vert;
- BMIter iter;
-
- float (*co)[3] = r_verts;
- BM_ITER_MESH(vert, &iter, bm, BM_VERTS_OF_MESH) {
- copy_v3_v3(*co, vert->co);
- ++co;
- }
-}
-
-static EditStrandsView editstrands_get_view(BMEditStrands *edit)
-{
- EditStrandsView hairdata;
- hairdata.base.group = edit->hair_group;
- hairdata.base.get_num_strands = get_num_strands;
- hairdata.base.get_num_verts = get_num_verts;
- hairdata.base.get_strand_lengths = get_strand_lengths;
- hairdata.base.get_strand_roots = get_strand_roots;
- hairdata.base.get_strand_vertices = get_strand_vertices;
- hairdata.edit = edit;
- return hairdata;
-}
-
-int* BKE_editstrands_hair_get_fiber_lengths(BMEditStrands *es, int subdiv)
-{
- EditStrandsView strands = editstrands_get_view(es);
- return BKE_hair_strands_get_fiber_lengths(&strands.base, subdiv);
-}
-
-void BKE_editstrands_hair_get_texture_buffer_size(BMEditStrands *es, int subdiv, int *r_size,
- int *r_strand_map_start, int *r_strand_vertex_start, int *r_fiber_start)
-{
- EditStrandsView strands = editstrands_get_view(es);
- BKE_hair_strands_get_texture_buffer_size(&strands.base, subdiv,
- r_size, r_strand_map_start, r_strand_vertex_start, r_fiber_start);
-}
-
-void BKE_editstrands_hair_get_texture_buffer(BMEditStrands *es, int subdiv, void *texbuffer)
-{
- EditStrandsView strands = editstrands_get_view(es);
- BKE_hair_strands_get_texture_buffer(&strands.base, subdiv, es->root_dm, texbuffer);
-}
-
/* === Constraints === */
BMEditStrandsLocations BKE_editstrands_get_locations(BMEditStrands *edit)
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 3cc6ca81171..836f111d977 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1021,35 +1021,15 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
}
ParticleSettings *part = psys->part;
- bool use_hair = false;
- bool use_fibers = false;
float mat[4][4];
- struct Gwn_Batch *hair_geom = NULL;
- const DRWHairFiberTextureBuffer *fiber_buffer = NULL;
- GPUTexture **fiber_texture = NULL;
+ unit_m4(mat);
- if (ob->mode & OB_MODE_HAIR_EDIT) {
- BMEditStrands *edit = psys->hairedit;
- const HairEditSettings *tsettings = &scene->toolsettings->hair_edit;
- if (edit &&tsettings->hair_draw_mode == HAIR_DRAW_FIBERS && edit->hair_group) {
- use_hair = true;
- use_fibers = true;
- copy_m4_m4(mat, ob->obmat);
-
- hair_geom = DRW_cache_editstrands_get_hair_fibers(edit, true, tsettings->hair_draw_subdiv, &fiber_buffer);
-
- if (!edit->texture) {
- edit->texture = DRW_texture_create_2D(fiber_buffer->width, fiber_buffer->height,
- DRW_TEX_RG_32, 0, fiber_buffer->data);
- }
- fiber_texture = (GPUTexture **)(&edit->texture);
- }
- }
- else {
+ bool use_hair = false;
+ struct Gwn_Batch *hair_geom = NULL;
+ if ((ob->mode & OB_MODE_HAIR_EDIT) == 0) {
int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
if (draw_as == PART_DRAW_PATH && (psys->pathcache || psys->childcache)) {
use_hair = true;
- unit_m4(mat);
hair_geom = DRW_cache_particles_get_hair(psys, md);
}
}
@@ -1060,19 +1040,8 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
ma = &defmaterial;
}
- if (!use_fibers) {
- DRW_shgroup_call_add(stl->g_data->depth_shgrp, hair_geom, mat);
- DRW_shgroup_call_add(stl->g_data->depth_shgrp_clip, hair_geom, mat);
- }
- else {
- DRW_shgroup_call_add(stl->g_data->depth_shgrp_hair_fibers, hair_geom, mat);
- DRW_hair_shader_uniforms(stl->g_data->depth_shgrp_hair_fibers, scene,
- fiber_texture, fiber_buffer);
-
- DRW_shgroup_call_add(stl->g_data->depth_shgrp_hair_fibers_clip, hair_geom, mat);
- DRW_hair_shader_uniforms(stl->g_data->depth_shgrp_hair_fibers_clip, scene,
- fiber_texture, fiber_buffer);
- }
+ DRW_shgroup_call_add(stl->g_data->depth_shgrp, hair_geom, mat);
+ DRW_shgroup_call_add(stl->g_data->depth_shgrp_clip, hair_geom, mat);
DRWShadingGroup *shgrp = BLI_ghash_lookup(material_hash, (const void *)ma);
if (!shgrp) {
@@ -1083,7 +1052,7 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
if (ma->use_nodes && ma->nodetree) {
struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma,
- use_fibers, stl->effects->use_ao, stl->effects->use_bent_normals);
+ false, stl->effects->use_ao, stl->effects->use_bent_normals);
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
if (shgrp) {
@@ -1103,8 +1072,8 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
/* Fallback to default shader */
if (shgrp == NULL) {
- shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, use_fibers,
- false, stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
+ shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false,
+ false, stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
@@ -1116,11 +1085,6 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
if (shgrp) {
DRW_shgroup_call_add(shgrp, hair_geom, mat);
-
- if (use_fibers) {
- DRW_hair_shader_uniforms(shgrp, scene,
- fiber_texture, fiber_buffer);
- }
}
}
}
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 9a4000cc0f2..fb7773d4b71 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -2610,12 +2610,6 @@ Gwn_Batch *DRW_cache_editstrands_get_wires(struct BMEditStrands *es)
return DRW_editstrands_batch_cache_get_wires(es);
}
-Gwn_Batch *DRW_cache_editstrands_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons, int subdiv,
- const struct DRWHairFiberTextureBuffer **r_buffer)
-{
- return DRW_editstrands_batch_cache_get_hair_fibers(es, use_ribbons, subdiv, r_buffer);
-}
-
/* -------------------------------------------------------------------- */
/** \name Hair */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index b6853c1fd3c..5e4dc14fc2e 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -166,9 +166,6 @@ struct Gwn_Batch *DRW_cache_editstrands_get_roots(struct BMEditStrands *es);
struct Gwn_Batch *DRW_cache_editstrands_get_points(struct BMEditStrands *es);
struct Gwn_Batch *DRW_cache_editstrands_get_wires(struct BMEditStrands *es);
-struct Gwn_Batch *DRW_cache_editstrands_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons, int subdiv,
- const struct DRWHairFiberTextureBuffer **r_buffer);
-
/* Hair */
struct Gwn_Batch *DRW_cache_hair_get_fibers(struct HairGroup *group, int subdiv, struct DerivedMesh *scalp,
const struct DRWHairFiberTextureBuffer **r_buffer);
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index f026b7452df..31ffb3e5a91 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -117,8 +117,6 @@ struct Gwn_Batch *DRW_editstrands_batch_cache_get_wires(struct BMEditStrands *es
struct Gwn_Batch *DRW_editstrands_batch_cache_get_tips(struct BMEditStrands *es);
struct Gwn_Batch *DRW_editstrands_batch_cache_get_roots(struct BMEditStrands *es);
struct Gwn_Batch *DRW_editstrands_batch_cache_get_points(struct BMEditStrands *es);
-struct Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons, int subdiv,
- const struct DRWHairFiberTextureBuffer **r_buffer);
/* Hair */
struct Gwn_Batch *DRW_hair_batch_cache_get_fibers(struct HairGroup *group, int subdiv, struct DerivedMesh *scalp,
diff --git a/source/blender/draw/intern/draw_cache_impl_strands.c b/source/blender/draw/intern/draw_cache_impl_strands.c
index fdf401c3641..94803a9512c 100644
--- a/source/blender/draw/intern/draw_cache_impl_strands.c
+++ b/source/blender/draw/intern/draw_cache_impl_strands.c
@@ -83,16 +83,6 @@ typedef struct StrandsBatchCache {
Gwn_Batch *roots;
Gwn_Batch *points;
- struct {
- Gwn_VertBuf *verts;
- Gwn_IndexBuf *segments;
-
- Gwn_Batch *fibers;
- bool use_ribbons;
-
- DRWHairFiberTextureBuffer texbuffer;
- } hair;
-
int segment_count;
int point_count;
@@ -158,41 +148,10 @@ void DRW_editstrands_batch_cache_dirty(BMEditStrands *es, int mode)
}
}
-static void editstrands_batch_cache_clear_hair(BMEditStrands *es)
-{
- StrandsBatchCache *cache = es->batch_cache;
-
- if (es->texture) {
- GPU_texture_free(es->texture);
- es->texture = NULL;
- }
-
- if (cache) {
- GWN_BATCH_DISCARD_SAFE(cache->hair.fibers);
- GWN_VERTBUF_DISCARD_SAFE(cache->hair.verts);
- GWN_INDEXBUF_DISCARD_SAFE(cache->hair.segments);
-
- {
- DRWHairFiberTextureBuffer *buffer = &cache->hair.texbuffer;
- if (buffer->data) {
- MEM_freeN(buffer->data);
- buffer->data = NULL;
- }
- buffer->fiber_start = 0;
- buffer->strand_map_start = 0;
- buffer->strand_vertex_start = 0;
- buffer->width = 0;
- buffer->height = 0;
- }
- }
-}
-
static void editstrands_batch_cache_clear(BMEditStrands *es)
{
StrandsBatchCache *cache = es->batch_cache;
- editstrands_batch_cache_clear_hair(es);
-
if (cache) {
GWN_BATCH_DISCARD_SAFE(cache->wires);
GWN_BATCH_DISCARD_SAFE(cache->points);
@@ -380,170 +339,3 @@ Gwn_Batch *DRW_editstrands_batch_cache_get_points(BMEditStrands *es)
return cache->points;
}
-
-/* ---------------------------------------------------------------------- */
-/* EditStrands Fibers Gwn_Batch Cache */
-
-static void editstrands_batch_cache_ensure_hair_fibers(BMEditStrands *es, StrandsBatchCache *cache, bool use_ribbons, int subdiv)
-{
- TIMEIT_START(editstrands_batch_cache_ensure_hair_fibers);
-
- GWN_VERTBUF_DISCARD_SAFE(cache->hair.verts);
- GWN_INDEXBUF_DISCARD_SAFE(cache->hair.segments);
-
- const int totfibers = es->hair_group->num_follicles;
- int *fiber_lengths = BKE_editstrands_hair_get_fiber_lengths(es, subdiv);
- int totpoint = 0;
- for (int i = 0; i < totfibers; ++i) {
- totpoint += fiber_lengths[i];
- }
- const int totseg = totpoint - totfibers;
-
- static Gwn_VertFormat format = { 0 };
- static unsigned curve_param_id, fiber_index_id;
-
- /* initialize vertex format */
- if (format.attrib_ct == 0) {
- fiber_index_id = GWN_vertformat_attr_add(&format, "fiber_index", GWN_COMP_I32, 1, GWN_FETCH_INT);
- curve_param_id = GWN_vertformat_attr_add(&format, "curve_param", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
- }
-
- cache->hair.verts = GWN_vertbuf_create_with_format(&format);
-
- Gwn_IndexBufBuilder elb;
- {
- TIMEIT_START(data_alloc);
- Gwn_PrimType prim_type;
- unsigned prim_ct, vert_ct;
- if (use_ribbons) {
- prim_type = GWN_PRIM_TRIS;
- prim_ct = 2 * totseg;
- vert_ct = 2 * totpoint;
- }
- else {
- prim_type = GWN_PRIM_LINES;
- prim_ct = totseg;
- vert_ct = totpoint;
- }
-
- GWN_vertbuf_data_alloc(cache->hair.verts, vert_ct);
- GWN_indexbuf_init(&elb, prim_type, prim_ct, vert_ct);
- TIMEIT_END(data_alloc);
- }
-
- TIMEIT_START(data_fill);
- TIMEIT_BLOCK_INIT(GWN_vertbuf_attr_set);
- TIMEIT_BLOCK_INIT(GWN_indexbuf_add_tri_verts);
- int vi = 0;
- for (int i = 0; i < totfibers; ++i) {
- const int fiblen = fiber_lengths[i];
- const float da = fiblen > 1 ? 1.0f / (fiblen-1) : 0.0f;
-
- float a = 0.0f;
- for (int k = 0; k < fiblen; ++k) {
- if (use_ribbons) {
- TIMEIT_BLOCK_START(GWN_vertbuf_attr_set);
- GWN_vertbuf_attr_set(cache->hair.verts, fiber_index_id, vi, &i);
- GWN_vertbuf_attr_set(cache->hair.verts, curve_param_id, vi, &a);
- GWN_vertbuf_attr_set(cache->hair.verts, fiber_index_id, vi+1, &i);
- GWN_vertbuf_attr_set(cache->hair.verts, curve_param_id, vi+1, &a);
- TIMEIT_BLOCK_END(GWN_vertbuf_attr_set);
-
- if (k > 0) {
- TIMEIT_BLOCK_START(GWN_indexbuf_add_tri_verts);
- GWN_indexbuf_add_tri_verts(&elb, vi-2, vi-1, vi+1);
- GWN_indexbuf_add_tri_verts(&elb, vi+1, vi, vi-2);
- TIMEIT_BLOCK_END(GWN_indexbuf_add_tri_verts);
- }
-
- vi += 2;
- }
- else {
- GWN_vertbuf_attr_set(cache->hair.verts, fiber_index_id, vi, &i);
- GWN_vertbuf_attr_set(cache->hair.verts, curve_param_id, vi, &a);
-
- if (k > 0) {
- GWN_indexbuf_add_line_verts(&elb, vi-1, vi);
- }
-
- vi += 1;
- }
-
- a += da;
- }
- }
- TIMEIT_BLOCK_STATS(GWN_vertbuf_attr_set);
- TIMEIT_BLOCK_STATS(GWN_indexbuf_add_tri_verts);
-#ifdef DEBUG_TIME
- printf("Total GWN time: %f\n", _timeit_var_GWN_vertbuf_attr_set + _timeit_var_GWN_indexbuf_add_tri_verts);
-#endif
- fflush(stdout);
- TIMEIT_END(data_fill);
-
- MEM_freeN(fiber_lengths);
-
- TIMEIT_BENCH(cache->hair.segments = GWN_indexbuf_build(&elb), indexbuf_build);
-
- TIMEIT_END(editstrands_batch_cache_ensure_hair_fibers);
-}
-
-static void editstrands_batch_cache_ensure_hair_fiber_texbuffer(BMEditStrands *es, StrandsBatchCache *cache, bool UNUSED(use_ribbons), int subdiv)
-{
- DRWHairFiberTextureBuffer *buffer = &cache->hair.texbuffer;
- static const int elemsize = 8;
- const int width = GPU_max_texture_size();
- const int align = width * elemsize;
-
- // Offsets in bytes
- int b_size, b_strand_map_start, b_strand_vertex_start, b_fiber_start;
- BKE_editstrands_hair_get_texture_buffer_size(es, subdiv, &b_size,
- &b_strand_map_start, &b_strand_vertex_start, &b_fiber_start);
- // Pad for alignment
- b_size += align - b_size % align;
-
- // Convert to element size as texture offsets
- const int size = b_size / elemsize;
- const int height = size / width;
-
- buffer->data = MEM_mallocN(b_size, "hair fiber texture buffer");
- BKE_editstrands_hair_get_texture_buffer(es, subdiv, buffer->data);
-
- buffer->width = width;
- buffer->height = height;
- buffer->strand_map_start = b_strand_map_start / elemsize;
- buffer->strand_vertex_start = b_strand_vertex_start / elemsize;
- buffer->fiber_start = b_fiber_start / elemsize;
-}
-
-Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(BMEditStrands *es, bool use_ribbons, int subdiv,
- const DRWHairFiberTextureBuffer **r_buffer)
-{
- StrandsBatchCache *cache = editstrands_batch_cache_get(es);
-
- TIMEIT_START(DRW_editstrands_batch_cache_get_hair_fibers);
-
- if (cache->hair.use_ribbons != use_ribbons) {
- TIMEIT_BENCH(editstrands_batch_cache_clear_hair(es), editstrands_batch_cache_clear_hair);
- }
-
- if (cache->hair.fibers == NULL) {
- TIMEIT_BENCH(editstrands_batch_cache_ensure_hair_fibers(es, cache, use_ribbons, subdiv),
- editstrands_batch_cache_ensure_hair_fibers);
-
- Gwn_PrimType prim_type = use_ribbons ? GWN_PRIM_TRIS : GWN_PRIM_LINES;
- TIMEIT_BENCH(cache->hair.fibers = GWN_batch_create(prim_type, cache->hair.verts, cache->hair.segments),
- GWN_batch_create);
- cache->hair.use_ribbons = use_ribbons;
-
- TIMEIT_BENCH(editstrands_batch_cache_ensure_hair_fiber_texbuffer(es, cache, use_ribbons, subdiv),
- editstrands_batch_cache_ensure_hair_fiber_texbuffer);
- }
-
- if (r_buffer) {
- *r_buffer = &cache->hair.texbuffer;
- }
-
- TIMEIT_END(DRW_editstrands_batch_cache_get_hair_fibers);
-
- return cache->hair.fibers;
-}