From 103f2655ab6e670cacfbf695adafe667c24c43eb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 3 Feb 2017 11:03:47 +0100 Subject: Explode modifier: Don't tessellate DM if we are not going to apply modifier --- source/blender/modifiers/intern/MOD_explode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/modifiers') diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 38ffdaa709b..ca7b3ce8039 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1001,8 +1001,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, ExplodeModifierData *emd = (ExplodeModifierData *) md; ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ob, md); - DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ - if (psmd) { ParticleSystem *psys = psmd->psys; @@ -1010,6 +1008,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (psys->part == NULL || psys->particles == NULL) return derivedData; if (psmd->dm_final == NULL) return derivedData; + DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + /* 1. find faces to be exploded if needed */ if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars || -- cgit v1.2.3 From 89f3837d687c5b685fbea5e7e71242287a735b76 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Feb 2017 12:33:37 +0100 Subject: Displace modifier: Use special version of texture sampling This version will give less spin locks and now well-tested by render engines. This should reduce amount of threading overhead when having multiple objects with displace modifier enabled. In the future this will also help us threading the modifier. There are more modifiers which could benefit from this, but let's first investigate the new behavior with one of them. --- source/blender/modifiers/intern/MOD_displace.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source/blender/modifiers') diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 08d118a2026..48e5d34288d 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -42,6 +42,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_library.h" #include "BKE_library_query.h" +#include "BKE_image.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_texture.h" @@ -216,6 +217,7 @@ static void displaceModifier_do( float (*vert_clnors)[3] = NULL; float local_mat[4][4]; const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL; + struct ImagePool *pool = NULL; if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return; if (dmd->strength == 0.0f) return; @@ -259,6 +261,10 @@ static void displaceModifier_do( copy_m4_m4(local_mat, ob->obmat); } + if (dmd->texture != NULL) { + pool = BKE_image_pool_new(); + } + for (i = 0; i < numVerts; i++) { TexResult texres; float strength = dmd->strength; @@ -272,7 +278,7 @@ static void displaceModifier_do( if (dmd->texture) { texres.nor = NULL; - BKE_texture_get_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false); + BKE_texture_get_value_ex(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, pool, false); delta = texres.tin - dmd->midlevel; } else { @@ -336,6 +342,10 @@ static void displaceModifier_do( } } + if (pool != NULL) { + BKE_image_pool_free(pool); + } + if (tex_co) { MEM_freeN(tex_co); } -- cgit v1.2.3 From d0015cba02f4809e0812b92f5686deef76e754e2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Feb 2017 14:21:29 +0100 Subject: Multi-thread displace modifier The title says it all actually. Use BLI task to loop over vertices and distort their locations. Gives 2x FPS increase in a file with just time-dependent displace modifier on my desktop. --- source/blender/modifiers/intern/MOD_displace.c | 213 +++++++++++++++---------- 1 file changed, 129 insertions(+), 84 deletions(-) (limited to 'source/blender/modifiers') diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 48e5d34288d..f6acbef96e9 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -38,6 +38,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_task.h" #include "BKE_cdderivedmesh.h" #include "BKE_library.h" @@ -201,23 +202,131 @@ static void updateDepsgraph(ModifierData *md, } } +typedef struct DisplaceUserdata { + /*const*/ DisplaceModifierData *dmd; + struct ImagePool *pool; + MDeformVert *dvert; + float weight; + int defgrp_index; + int direction; + bool use_global_direction; + float (*tex_co)[3]; + float (*vertexCos)[3]; + float local_mat[4][4]; + MVert *mvert; + float (*vert_clnors)[3]; +} DisplaceUserdata; + +static void displaceModifier_do_task(void *userdata, const int iter) +{ + DisplaceUserdata *data = (DisplaceUserdata *)userdata; + DisplaceModifierData *dmd = data->dmd; + MDeformVert *dvert = data->dvert; + float weight = data->weight; + int defgrp_index = data->defgrp_index; + int direction = data->direction; + bool use_global_direction = data->use_global_direction; + float (*tex_co)[3] = data->tex_co; + float (*vertexCos)[3] = data->vertexCos; + MVert *mvert = data->mvert; + float (*vert_clnors)[3] = data->vert_clnors; + + const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */ + + TexResult texres; + float strength = dmd->strength; + float delta; + float local_vec[3]; + + if (dvert) { + weight = defvert_find_weight(dvert + iter, defgrp_index); + if (weight == 0.0f) { + return; + } + } + + if (dmd->texture) { + texres.nor = NULL; + BKE_texture_get_value_ex(dmd->modifier.scene, dmd->texture, tex_co[iter], &texres, data->pool, false); + delta = texres.tin - dmd->midlevel; + } + else { + delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */ + } + + if (dvert) { + strength *= weight; + } + + delta *= strength; + CLAMP(delta, -10000, 10000); + + switch (direction) { + case MOD_DISP_DIR_X: + if (use_global_direction) { + vertexCos[iter][0] += delta * data->local_mat[0][0]; + vertexCos[iter][1] += delta * data->local_mat[1][0]; + vertexCos[iter][2] += delta * data->local_mat[2][0]; + } + else { + vertexCos[iter][0] += delta; + } + break; + case MOD_DISP_DIR_Y: + if (use_global_direction) { + vertexCos[iter][0] += delta * data->local_mat[0][1]; + vertexCos[iter][1] += delta * data->local_mat[1][1]; + vertexCos[iter][2] += delta * data->local_mat[2][1]; + } + else { + vertexCos[iter][1] += delta; + } + break; + case MOD_DISP_DIR_Z: + if (use_global_direction) { + vertexCos[iter][0] += delta * data->local_mat[0][2]; + vertexCos[iter][1] += delta * data->local_mat[1][2]; + vertexCos[iter][2] += delta * data->local_mat[2][2]; + } + else { + vertexCos[iter][2] += delta; + } + break; + case MOD_DISP_DIR_RGB_XYZ: + local_vec[0] = texres.tr - dmd->midlevel; + local_vec[1] = texres.tg - dmd->midlevel; + local_vec[2] = texres.tb - dmd->midlevel; + if (use_global_direction) { + mul_transposed_mat3_m4_v3(data->local_mat, local_vec); + } + mul_v3_fl(local_vec, strength); + add_v3_v3(vertexCos[iter], local_vec); + break; + case MOD_DISP_DIR_NOR: + vertexCos[iter][0] += delta * (mvert[iter].no[0] / 32767.0f); + vertexCos[iter][1] += delta * (mvert[iter].no[1] / 32767.0f); + vertexCos[iter][2] += delta * (mvert[iter].no[2] / 32767.0f); + break; + case MOD_DISP_DIR_CLNOR: + madd_v3_v3fl(vertexCos[iter], vert_clnors[iter], delta); + break; + } +} + /* dm must be a CDDerivedMesh */ static void displaceModifier_do( DisplaceModifierData *dmd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { - int i; MVert *mvert; MDeformVert *dvert; int direction = dmd->direction; int defgrp_index; float (*tex_co)[3]; float weight = 1.0f; /* init value unused but some compilers may complain */ - const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */ float (*vert_clnors)[3] = NULL; - float local_mat[4][4]; + float local_mat[4][4] = {0}; const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL; - struct ImagePool *pool = NULL; if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return; if (dmd->strength == 0.0f) return; @@ -261,89 +370,25 @@ static void displaceModifier_do( copy_m4_m4(local_mat, ob->obmat); } + DisplaceUserdata data = {NULL}; + data.dmd = dmd; + data.dvert = dvert; + data.weight = weight; + data.defgrp_index = defgrp_index; + data.direction = direction; + data.use_global_direction = use_global_direction; + data.tex_co = tex_co; + data.vertexCos = vertexCos; + copy_m4_m4(data.local_mat, local_mat); + data.mvert = mvert; + data.vert_clnors = vert_clnors; if (dmd->texture != NULL) { - pool = BKE_image_pool_new(); - } - - for (i = 0; i < numVerts; i++) { - TexResult texres; - float strength = dmd->strength; - float delta; - float local_vec[3]; - - if (dvert) { - weight = defvert_find_weight(dvert + i, defgrp_index); - if (weight == 0.0f) continue; - } - - if (dmd->texture) { - texres.nor = NULL; - BKE_texture_get_value_ex(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, pool, false); - delta = texres.tin - dmd->midlevel; - } - else { - delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */ - } - - if (dvert) strength *= weight; - - delta *= strength; - CLAMP(delta, -10000, 10000); - - switch (direction) { - case MOD_DISP_DIR_X: - if (use_global_direction) { - vertexCos[i][0] += delta * local_mat[0][0]; - vertexCos[i][1] += delta * local_mat[1][0]; - vertexCos[i][2] += delta * local_mat[2][0]; - } - else { - vertexCos[i][0] += delta; - } - break; - case MOD_DISP_DIR_Y: - if (use_global_direction) { - vertexCos[i][0] += delta * local_mat[0][1]; - vertexCos[i][1] += delta * local_mat[1][1]; - vertexCos[i][2] += delta * local_mat[2][1]; - } - else { - vertexCos[i][1] += delta; - } - break; - case MOD_DISP_DIR_Z: - if (use_global_direction) { - vertexCos[i][0] += delta * local_mat[0][2]; - vertexCos[i][1] += delta * local_mat[1][2]; - vertexCos[i][2] += delta * local_mat[2][2]; - } - else { - vertexCos[i][2] += delta; - } - break; - case MOD_DISP_DIR_RGB_XYZ: - local_vec[0] = texres.tr - dmd->midlevel; - local_vec[1] = texres.tg - dmd->midlevel; - local_vec[2] = texres.tb - dmd->midlevel; - if (use_global_direction) { - mul_transposed_mat3_m4_v3(local_mat, local_vec); - } - mul_v3_fl(local_vec, strength); - add_v3_v3(vertexCos[i], local_vec); - break; - case MOD_DISP_DIR_NOR: - vertexCos[i][0] += delta * (mvert[i].no[0] / 32767.0f); - vertexCos[i][1] += delta * (mvert[i].no[1] / 32767.0f); - vertexCos[i][2] += delta * (mvert[i].no[2] / 32767.0f); - break; - case MOD_DISP_DIR_CLNOR: - madd_v3_v3fl(vertexCos[i], vert_clnors[i], delta); - break; - } + data.pool = BKE_image_pool_new(); } + BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, numVerts > 512); - if (pool != NULL) { - BKE_image_pool_free(pool); + if (data.pool != NULL) { + BKE_image_pool_free(data.pool); } if (tex_co) { -- cgit v1.2.3