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:
authorClément Foucault <foucault.clem@gmail.com>2020-06-23 14:59:55 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-06-23 15:04:41 +0300
commit439b40e601f8cdae9a12fc3f503e9e6acdd596d5 (patch)
tree9a485ec18d1c9dd030ffdfe9309193adc96dc515 /source/blender/draw/intern
parentcc3e808ab47887c002faaa8a28318a2b4f47e02a (diff)
EEVEE: Motion Blur: Add accumulation motion blur for better precision
This revisit the render pipeline to support time slicing for better motion blur. We support accumulation with or without the Post-process motion blur. If using the post-process, we reuse last step next motion data to avoid another scene reevaluation. This also adds support for hair motion blur which is handled in a similar way as mesh motion blur. The total number of samples is distributed evenly accross all timesteps to avoid sampling weighting issues. For this reason, the sample count is (internally) rounded up to the next multiple of the step count. Only FX Motion BLur: {F8632258} FX Motion Blur + 4 time steps: {F8632260} FX Motion Blur + 32 time steps: {F8632261} Reviewed By: jbakker Differential Revision: https://developer.blender.org/D8079
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_common.h7
-rw-r--r--source/blender/draw/intern/draw_hair.c157
-rw-r--r--source/blender/draw/intern/draw_manager.c13
4 files changed, 114 insertions, 65 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 7f5b4f5e42b..555043ab408 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -630,6 +630,8 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
void (*callback)(void *vedata, void *user_data),
void *user_data);
+void DRW_cache_restart(void);
+
/* ViewLayers */
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
void **DRW_view_layer_engine_data_ensure_ex(struct ViewLayer *view_layer,
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 656d72b2808..81c0e97a1a8 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -176,6 +176,13 @@ struct DRWShadingGroup *DRW_shgroup_hair_create_sub(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md,
struct DRWShadingGroup *shgrp);
+struct GPUVertBuf *DRW_hair_pos_buffer_get(struct Object *object,
+ struct ParticleSystem *psys,
+ struct ModifierData *md);
+void DRW_hair_duplimat_get(struct Object *object,
+ struct ParticleSystem *psys,
+ struct ModifierData *md,
+ float (*dupli_mat)[4]);
void DRW_hair_init(void);
void DRW_hair_update(void);
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 2fdaf0d5345..6cfba0e2a78 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -124,32 +124,109 @@ void DRW_hair_init(void)
}
}
-DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
- ParticleSystem *psys,
- ModifierData *md,
- DRWShadingGroup *shgrp_parent)
+static ParticleHairCache *drw_hair_particle_cache_get(
+ Object *object, ParticleSystem *psys, ModifierData *md, int subdiv, int thickness_res)
+{
+ bool update;
+ ParticleHairCache *cache;
+ if (psys) {
+ /* Old particle hair. */
+ update = particles_ensure_procedural_data(object, psys, md, &cache, subdiv, thickness_res);
+ }
+ else {
+ /* New hair object. */
+ update = hair_ensure_procedural_data(object, &cache, subdiv, thickness_res);
+ }
+
+ if (update) {
+ int final_points_len = cache->final[subdiv].strands_res * cache->strands_len;
+ if (final_points_len > 0) {
+ GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
+
+#ifdef USE_TRANSFORM_FEEDBACK
+ DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
+ tf_shader, g_tf_pass, cache->final[subdiv].proc_buf);
+#else
+ DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
+
+ ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
+ pr_call->next = g_tf_calls;
+ pr_call->vbo = cache->final[subdiv].proc_buf;
+ pr_call->shgrp = tf_shgrp;
+ pr_call->vert_len = final_points_len;
+ g_tf_calls = pr_call;
+ DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
+ DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
+ DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
+#endif
+
+ DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", cache->point_tex);
+ DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", cache->strand_tex);
+ DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", cache->strand_seg_tex);
+ DRW_shgroup_uniform_int(tf_shgrp, "hairStrandsRes", &cache->final[subdiv].strands_res, 1);
+ DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
+ }
+ }
+ return cache;
+}
+
+/* Note: Only valid after DRW_hair_update(). */
+GPUVertBuf *DRW_hair_pos_buffer_get(Object *object, ParticleSystem *psys, ModifierData *md)
{
- /* TODO(fclem): Pass the scene as parameter */
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
- float dupli_mat[4][4];
- Object *dupli_parent = DRW_object_get_dupli_parent(object);
- DupliObject *dupli_object = DRW_object_get_dupli(object);
int subdiv = scene->r.hair_subdiv;
int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2;
- ParticleHairCache *hair_cache;
- bool need_ft_update;
+ ParticleHairCache *cache = drw_hair_particle_cache_get(object, psys, md, subdiv, thickness_res);
+
+ return cache->final[subdiv].proc_buf;
+}
+
+void DRW_hair_duplimat_get(Object *object,
+ ParticleSystem *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) {
- /* Old particle hair. */
- need_ft_update = particles_ensure_procedural_data(
- object, psys, md, &hair_cache, subdiv, thickness_res);
+ if ((dupli_parent != NULL) && (dupli_object != NULL)) {
+ if (dupli_object->type & OB_DUPLICOLLECTION) {
+ copy_m4_m4(dupli_mat, dupli_parent->obmat);
+ }
+ else {
+ copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
+ invert_m4(dupli_mat);
+ mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
+ }
+ }
+ else {
+ unit_m4(dupli_mat);
+ }
}
else {
/* New hair object. */
- need_ft_update = hair_ensure_procedural_data(object, &hair_cache, subdiv, thickness_res);
+ copy_m4_m4(dupli_mat, object->obmat);
}
+}
+
+DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
+ ParticleSystem *psys,
+ ModifierData *md,
+ DRWShadingGroup *shgrp_parent)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ float dupli_mat[4][4];
+
+ int subdiv = scene->r.hair_subdiv;
+ int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2;
+
+ ParticleHairCache *hair_cache = drw_hair_particle_cache_get(
+ object, psys, md, subdiv, thickness_res);
DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent);
@@ -177,25 +254,7 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture);
}
- if (psys) {
- if ((dupli_parent != NULL) && (dupli_object != NULL)) {
- if (dupli_object->type & OB_DUPLICOLLECTION) {
- copy_m4_m4(dupli_mat, dupli_parent->obmat);
- }
- else {
- copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
- invert_m4(dupli_mat);
- mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
- }
- }
- else {
- unit_m4(dupli_mat);
- }
- }
- else {
- /* New hair object. */
- copy_m4_m4(dupli_mat, object->obmat);
- }
+ DRW_hair_duplimat_get(object, psys, md, dupli_mat);
/* Get hair shape parameters. */
float hair_rad_shape, hair_rad_root, hair_rad_tip;
@@ -229,38 +288,6 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
GPUBatch *geom = hair_cache->final[subdiv].proc_hairs[thickness_res - 1];
DRW_shgroup_call_no_cull(shgrp, geom, object);
- /* Transform Feedback subdiv. */
- if (need_ft_update) {
- int final_points_len = hair_cache->final[subdiv].strands_res * hair_cache->strands_len;
- if (final_points_len) {
- GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
-
-#ifdef USE_TRANSFORM_FEEDBACK
- DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
- tf_shader, g_tf_pass, hair_cache->final[subdiv].proc_buf);
-#else
- DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
-
- ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
- pr_call->next = g_tf_calls;
- pr_call->vbo = hair_cache->final[subdiv].proc_buf;
- pr_call->shgrp = tf_shgrp;
- pr_call->vert_len = final_points_len;
- g_tf_calls = pr_call;
- DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
- DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
- DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
-#endif
-
- 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(tf_shgrp, NULL, final_points_len);
- }
- }
-
return shgrp;
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 55dc1d6c5d7..5b1276d0d6b 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1942,6 +1942,19 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
#endif
}
+/* Used when the render engine want to redo another cache populate inside the same render frame. */
+void DRW_cache_restart(void)
+{
+ /* Force cache to reset. */
+ drw_viewport_cache_resize();
+
+ drw_viewport_var_init();
+
+ DST.buffer_finish_called = false;
+
+ DRW_hair_init();
+}
+
static struct DRWSelectBuffer {
struct GPUFrameBuffer *framebuffer_depth_only;
struct GPUTexture *texture_depth;