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/draw/engines/eevee/eevee_data.c15
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c78
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c51
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h13
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c3
-rw-r--r--source/blender/draw/intern/draw_common.h5
-rw-r--r--source/blender/draw/intern/draw_hair.c137
9 files changed, 237 insertions, 69 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index ee70cebcfd2..b846480182b 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -160,7 +160,7 @@ EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb
{
if (mb_data->hair_data == NULL) {
/* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */
- int psys_len = (ob->type != OB_CURVES) ? BLI_listbase_count(&ob->modifiers) : 1;
+ int psys_len = BLI_listbase_count(&ob->modifiers);
EEVEE_HairMotionData *hair_step = MEM_callocN(
sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, __func__);
hair_step->psys_len = psys_len;
@@ -170,6 +170,19 @@ EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb
return mb_data->hair_data;
}
+EEVEE_HairMotionData *EEVEE_motion_blur_curves_data_get(EEVEE_ObjectMotionData *mb_data,
+ Object *ob)
+{
+ if (mb_data->hair_data == NULL) {
+ EEVEE_HairMotionData *hair_step = MEM_callocN(
+ sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]), __func__);
+ hair_step->psys_len = 1;
+ hair_step->type = EEVEE_MOTION_DATA_HAIR;
+ mb_data->hair_data = hair_step;
+ }
+ return mb_data->hair_data;
+}
+
/* View Layer data. */
void EEVEE_view_layer_data_free(void *storage)
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 6cd1a31085f..0729b2078a8 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -111,7 +111,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
}
else if (ob->type == OB_CURVES) {
- EEVEE_object_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+ EEVEE_object_curves_cache_populate(vedata, sldata, ob, &cast_shadow);
}
else if (ob->type == OB_VOLUME) {
EEVEE_volumes_cache_object_add(sldata, vedata, draw_ctx->scene, ob);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 4b9ad693971..c3f9a606dd0 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -740,34 +740,6 @@ BLI_INLINE EeveeMaterialCache eevee_material_cache_get(
return matcache;
}
-static void eevee_hair_cache_populate(EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata,
- Object *ob,
- ParticleSystem *psys,
- ModifierData *md,
- int matnr,
- bool *cast_shadow)
-{
- EeveeMaterialCache matcache = eevee_material_cache_get(vedata, sldata, ob, matnr - 1, true);
-
- if (matcache.depth_grp) {
- *matcache.depth_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.depth_grp, NULL);
- DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat);
- }
- if (matcache.shading_grp) {
- *matcache.shading_grp_p = DRW_shgroup_hair_create_sub(
- ob, psys, md, matcache.shading_grp, matcache.shading_gpumat);
- DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat);
- }
- if (matcache.shadow_grp) {
- *matcache.shadow_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shadow_grp, NULL);
- DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat);
- *cast_shadow = true;
- }
-
- EEVEE_motion_blur_hair_cache_populate(sldata, vedata, ob, psys, md);
-}
-
#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) \
do { \
if (oedata) { \
@@ -899,18 +871,56 @@ void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
if (draw_as != PART_DRAW_PATH) {
continue;
}
- eevee_hair_cache_populate(vedata, sldata, ob, psys, md, part->omat, cast_shadow);
+ EeveeMaterialCache matcache = eevee_material_cache_get(
+ vedata, sldata, ob, part->omat - 1, true);
+
+ if (matcache.depth_grp) {
+ *matcache.depth_grp_p = DRW_shgroup_hair_create_sub(
+ ob, psys, md, matcache.depth_grp, NULL);
+ DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat);
+ }
+ if (matcache.shading_grp) {
+ *matcache.shading_grp_p = DRW_shgroup_hair_create_sub(
+ ob, psys, md, matcache.shading_grp, matcache.shading_gpumat);
+ DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat);
+ }
+ if (matcache.shadow_grp) {
+ *matcache.shadow_grp_p = DRW_shgroup_hair_create_sub(
+ ob, psys, md, matcache.shadow_grp, NULL);
+ DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat);
+ *cast_shadow = true;
+ }
+
+ EEVEE_motion_blur_hair_cache_populate(sldata, vedata, ob, psys, md);
}
}
}
}
-void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata,
- Object *ob,
- bool *cast_shadow)
+void EEVEE_object_curves_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob,
+ bool *cast_shadow)
{
- eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, CURVES_MATERIAL_NR, cast_shadow);
+ EeveeMaterialCache matcache = eevee_material_cache_get(
+ vedata, sldata, ob, CURVES_MATERIAL_NR - 1, true);
+
+ if (matcache.depth_grp) {
+ *matcache.depth_grp_p = DRW_shgroup_curves_create_sub(ob, matcache.depth_grp, NULL);
+ DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat);
+ }
+ if (matcache.shading_grp) {
+ *matcache.shading_grp_p = DRW_shgroup_curves_create_sub(
+ ob, matcache.shading_grp, matcache.shading_gpumat);
+ DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat);
+ }
+ if (matcache.shadow_grp) {
+ *matcache.shadow_grp_p = DRW_shgroup_curves_create_sub(ob, matcache.shadow_grp, NULL);
+ DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat);
+ *cast_shadow = true;
+ }
+
+ EEVEE_motion_blur_curves_cache_populate(sldata, vedata, ob);
}
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index fbc19a01a8b..0ef2e11131e 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -270,6 +270,57 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
}
}
+void EEVEE_motion_blur_curves_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ Object *ob)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ if (!DRW_state_is_scene_render() || psl->velocity_hair == NULL) {
+ return;
+ }
+
+ /* For now we assume curves objects are always moving. */
+ EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
+ if (mb_data == NULL) {
+ return;
+ }
+
+ int mb_step = effects->motion_blur_step;
+ /* Store transform. */
+ copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
+
+ EEVEE_HairMotionData *mb_curves = EEVEE_motion_blur_curves_data_get(mb_data, ob);
+
+ if (mb_step == MB_CURR) {
+ /* Fill missing matrices if the object was hidden in previous or next frame. */
+ if (is_zero_m4(mb_data->obmat[MB_PREV])) {
+ copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_CURR]);
+ }
+ if (is_zero_m4(mb_data->obmat[MB_NEXT])) {
+ copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]);
+ }
+
+ GPUTexture *tex_prev = mb_curves->psys[0].step_data[MB_PREV].hair_pos_tx;
+ GPUTexture *tex_next = mb_curves->psys[0].step_data[MB_NEXT].hair_pos_tx;
+
+ DRWShadingGroup *grp = DRW_shgroup_curves_create_sub(ob, effects->motion_blur.hair_grp, NULL);
+ DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
+ DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mb_data->obmat[MB_CURR]);
+ DRW_shgroup_uniform_mat4(grp, "nextModelMatrix", mb_data->obmat[MB_NEXT]);
+ DRW_shgroup_uniform_texture(grp, "prvBuffer", tex_prev);
+ DRW_shgroup_uniform_texture(grp, "nxtBuffer", tex_next);
+ DRW_shgroup_uniform_bool(grp, "useDeform", &mb_curves->use_deform, 1);
+ }
+ else {
+ /* Store vertex position buffer. */
+ mb_curves->psys[0].step_data[mb_step].hair_pos = DRW_curves_pos_buffer_get(ob);
+ mb_curves->use_deform = true;
+ }
+}
+
void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
Object *ob)
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 5220bac4e3f..f58c2339c82 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -1095,6 +1095,8 @@ EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob);
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob);
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data);
EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob);
+EEVEE_HairMotionData *EEVEE_motion_blur_curves_data_get(EEVEE_ObjectMotionData *mb_data,
+ Object *ob);
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob);
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob);
EEVEE_LightEngineData *EEVEE_light_data_get(Object *ob);
@@ -1120,10 +1122,10 @@ void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow);
-void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata,
- Object *ob,
- bool *cast_shadow);
+void EEVEE_object_curves_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob,
+ bool *cast_shadow);
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_materials_free(void);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
@@ -1463,6 +1465,9 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *sldata,
Object *ob,
struct ParticleSystem *psys,
struct ModifierData *md);
+void EEVEE_motion_blur_curves_cache_populate(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ Object *ob);
void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata);
void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata);
void EEVEE_motion_blur_draw(EEVEE_Data *vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index e971edbaa44..47e2b95f367 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -230,7 +230,7 @@ void EEVEE_render_cache(void *vedata,
}
}
else if (ob->type == OB_CURVES) {
- EEVEE_object_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+ EEVEE_object_curves_cache_populate(vedata, sldata, ob, &cast_shadow);
if (do_cryptomatte) {
EEVEE_cryptomatte_object_curves_cache_populate(data, sldata, ob);
}
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 85c8f9c420a..566fd30096d 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -425,7 +425,8 @@ void workbench_cache_populate(void *ved, Object *ob)
}
else if (ob->type == OB_CURVES) {
int color_type = workbench_color_type_get(wpd, ob, NULL, NULL, NULL);
- workbench_cache_hair_populate(wpd, ob, NULL, NULL, color_type, false, CURVES_MATERIAL_NR);
+ DRWShadingGroup *grp = workbench_material_hair_setup(wpd, ob, CURVES_MATERIAL_NR, color_type);
+ DRW_shgroup_curves_create_sub(ob, grp, NULL);
}
else if (ob->type == OB_VOLUME) {
if (wpd->shading.type != OB_WIRE) {
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 34b930ae9c8..d302140d9ac 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -53,12 +53,17 @@ struct DRWShadingGroup *DRW_shgroup_hair_create_sub(struct Object *object,
struct ModifierData *md,
struct DRWShadingGroup *shgrp,
struct GPUMaterial *gpu_material);
+
+struct DRWShadingGroup *DRW_shgroup_curves_create_sub(struct Object *object,
+ struct DRWShadingGroup *shgrp,
+ struct GPUMaterial *gpu_material);
/**
* \note Only valid after #DRW_hair_update().
*/
struct GPUVertBuf *DRW_hair_pos_buffer_get(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md);
+struct GPUVertBuf *DRW_curves_pos_buffer_get(struct Object *object);
void DRW_hair_duplimat_get(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md,
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index e06df334d23..0a447bf7041 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -164,17 +164,28 @@ static ParticleHairCache *drw_hair_particle_cache_get(Object *object,
int subdiv,
int thickness_res)
{
- bool update;
ParticleHairCache *cache;
- if (psys) {
- /* Old particle hair. */
- update = particles_ensure_procedural_data(
- object, psys, md, &cache, gpu_material, subdiv, thickness_res);
- }
- else {
- /* New curves object. */
- update = curves_ensure_procedural_data(object, &cache, gpu_material, subdiv, thickness_res);
+ bool update = particles_ensure_procedural_data(
+ object, psys, md, &cache, gpu_material, subdiv, thickness_res);
+
+ if (update) {
+ if (drw_hair_shader_type_get() == PART_REFINE_SHADER_COMPUTE) {
+ drw_hair_particle_cache_update_compute(cache, subdiv);
+ }
+ else {
+ drw_hair_particle_cache_update_transform_feedback(cache, subdiv);
+ }
}
+ return cache;
+}
+
+static ParticleHairCache *drw_curves_cache_get(Object *object,
+ GPUMaterial *gpu_material,
+ int subdiv,
+ int thickness_res)
+{
+ ParticleHairCache *cache;
+ bool update = curves_ensure_procedural_data(object, &cache, gpu_material, subdiv, thickness_res);
if (update) {
if (drw_hair_shader_type_get() == PART_REFINE_SHADER_COMPUTE) {
@@ -201,37 +212,44 @@ GPUVertBuf *DRW_hair_pos_buffer_get(Object *object, ParticleSystem *psys, Modifi
return cache->final[subdiv].proc_buf;
}
+GPUVertBuf *DRW_curves_pos_buffer_get(Object *object)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+
+ int subdiv = scene->r.hair_subdiv;
+ int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2;
+
+ ParticleHairCache *cache = drw_curves_cache_get(object, NULL, subdiv, thickness_res);
+
+ return cache->final[subdiv].proc_buf;
+}
+
void DRW_hair_duplimat_get(Object *object,
- ParticleSystem *psys,
+ ParticleSystem *UNUSED(psys),
ModifierData *UNUSED(md),
float (*dupli_mat)[4])
{
Object *dupli_parent = DRW_object_get_dupli_parent(object);
DupliObject *dupli_object = DRW_object_get_dupli(object);
- if (psys) {
- if ((dupli_parent != NULL) && (dupli_object != NULL)) {
- if (dupli_object->type & OB_DUPLICOLLECTION) {
- unit_m4(dupli_mat);
- Collection *collection = dupli_parent->instance_collection;
- if (collection != NULL) {
- sub_v3_v3(dupli_mat[3], collection->instance_offset);
- }
- mul_m4_m4m4(dupli_mat, dupli_parent->obmat, dupli_mat);
- }
- else {
- copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
- invert_m4(dupli_mat);
- mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
+ if ((dupli_parent != NULL) && (dupli_object != NULL)) {
+ if (dupli_object->type & OB_DUPLICOLLECTION) {
+ unit_m4(dupli_mat);
+ Collection *collection = dupli_parent->instance_collection;
+ if (collection != NULL) {
+ sub_v3_v3(dupli_mat[3], collection->instance_offset);
}
+ mul_m4_m4m4(dupli_mat, dupli_parent->obmat, dupli_mat);
}
else {
- unit_m4(dupli_mat);
+ copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
+ invert_m4(dupli_mat);
+ mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
}
}
else {
- /* New curves object. */
- copy_m4_m4(dupli_mat, object->obmat);
+ unit_m4(dupli_mat);
}
}
@@ -317,6 +335,71 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
return shgrp;
}
+DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object,
+ DRWShadingGroup *shgrp_parent,
+ GPUMaterial *gpu_material)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+
+ int subdiv = scene->r.hair_subdiv;
+ int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2;
+
+ ParticleHairCache *curves_cache = drw_curves_cache_get(
+ object, gpu_material, subdiv, thickness_res);
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent);
+
+ /* TODO: optimize this. Only bind the ones GPUMaterial needs. */
+ for (int i = 0; i < curves_cache->num_uv_layers; i++) {
+ for (int n = 0; n < MAX_LAYER_NAME_CT && curves_cache->uv_layer_names[i][n][0] != '\0'; n++) {
+ DRW_shgroup_uniform_texture(
+ shgrp, curves_cache->uv_layer_names[i][n], curves_cache->uv_tex[i]);
+ }
+ }
+ for (int i = 0; i < curves_cache->num_col_layers; i++) {
+ for (int n = 0; n < MAX_LAYER_NAME_CT && curves_cache->col_layer_names[i][n][0] != '\0'; n++) {
+ DRW_shgroup_uniform_texture(
+ shgrp, curves_cache->col_layer_names[i][n], curves_cache->col_tex[i]);
+ }
+ }
+
+ /* Fix issue with certain driver not drawing anything if there is no texture bound to
+ * "ac", "au", "u" or "c". */
+ if (curves_cache->num_uv_layers == 0) {
+ DRW_shgroup_uniform_texture(shgrp, "u", g_dummy_texture);
+ DRW_shgroup_uniform_texture(shgrp, "au", g_dummy_texture);
+ }
+ if (curves_cache->num_col_layers == 0) {
+ DRW_shgroup_uniform_texture(shgrp, "c", g_dummy_texture);
+ DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture);
+ }
+
+ /* TODO: Generalize radius implementation for curves data type. */
+ float hair_rad_shape = 1.0f;
+ float hair_rad_root = 0.005f;
+ float hair_rad_tip = 0.0f;
+ bool hair_close_tip = true;
+
+ DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", curves_cache->final[subdiv].proc_tex);
+ if (curves_cache->length_tex) {
+ DRW_shgroup_uniform_texture(shgrp, "hairLen", curves_cache->length_tex);
+ }
+ DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &curves_cache->final[subdiv].strands_res, 1);
+ DRW_shgroup_uniform_int_copy(shgrp, "hairThicknessRes", thickness_res);
+ DRW_shgroup_uniform_float_copy(shgrp, "hairRadShape", hair_rad_shape);
+ DRW_shgroup_uniform_mat4_copy(shgrp, "hairDupliMatrix", object->obmat);
+ DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", hair_rad_root);
+ DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip);
+ DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip);
+ /* TODO(fclem): Until we have a better way to cull the curves and render with orco, bypass
+ * culling test. */
+ GPUBatch *geom = curves_cache->final[subdiv].proc_hairs[thickness_res - 1];
+ DRW_shgroup_call_no_cull(shgrp, geom, object);
+
+ return shgrp;
+}
+
void DRW_hair_update(void)
{
#ifndef USE_TRANSFORM_FEEDBACK