diff options
author | Hans Goudey <h.goudey@me.com> | 2022-04-14 06:07:31 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-04-14 06:07:31 +0300 |
commit | f31c3f8114616bb8964c8e7e67cbcb79e269ffef (patch) | |
tree | e7b52d08710a991226253245436fd1ba068d91c8 /source/blender/draw/intern | |
parent | f84f9eb8ed439e5d3409f15109bdb67cd87b7fcf (diff) |
Curves: Split curve EEVEE/workbench functions from particle hair
The GPU evaluation for curves will have to change significantly from the
current particle hair drawing code, due to its more general use cases
and support for more curve types. To simplify that process and avoid
introducing regressions for the rendering of hair particle systems,
this commit splits drawing functions for the curves object and
particle hair.
The changes are just inlining of functions and copying code
where necessary.
Differential Revision: https://developer.blender.org/D14576
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 5 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_hair.c | 137 |
2 files changed, 115 insertions, 27 deletions
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 |