Blender  V3.3
eevee_sync.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2021 Blender Foundation.
3  */
4 
11 #include "eevee_engine.h"
12 
13 #include "BKE_gpencil.h"
14 #include "BKE_object.h"
15 #include "DEG_depsgraph_query.h"
16 #include "DNA_curves_types.h"
17 #include "DNA_gpencil_types.h"
18 #include "DNA_modifier_types.h"
19 #include "DNA_particle_types.h"
20 
21 #include "eevee_instance.hh"
22 
23 namespace blender::eevee {
24 
25 /* -------------------------------------------------------------------- */
30 static void draw_data_init_cb(struct DrawData *dd)
31 {
32  /* Object has just been created or was never evaluated by the engine. */
33  dd->recalc = ID_RECALC_ALL;
34 }
35 
37 {
39  struct DrawData *dd = DRW_drawdata_ensure(
40  (ID *)ob, owner, sizeof(eevee::ObjectHandle), draw_data_init_cb, nullptr);
41  ObjectHandle &eevee_dd = *reinterpret_cast<ObjectHandle *>(dd);
42 
43  if (eevee_dd.object_key.ob == nullptr) {
44  eevee_dd.object_key = ObjectKey(ob);
45  }
46 
49  if ((eevee_dd.recalc & recalc_flags) != 0) {
50  inst_.sampling.reset();
51  UNUSED_VARS(inst_);
52  }
53 
54  return eevee_dd;
55 }
56 
58 {
60  struct DrawData *dd = DRW_drawdata_ensure(
61  (ID *)world, owner, sizeof(eevee::WorldHandle), draw_data_init_cb, nullptr);
62  WorldHandle &eevee_dd = *reinterpret_cast<WorldHandle *>(dd);
63 
64  const int recalc_flags = ID_RECALC_ALL;
65  if ((eevee_dd.recalc & recalc_flags) != 0) {
66  inst_.sampling.reset();
67  }
68  return eevee_dd;
69 }
70 
73 /* -------------------------------------------------------------------- */
77 static inline void shgroup_geometry_call(DRWShadingGroup *grp,
78  Object *ob,
79  GPUBatch *geom,
80  int v_first = -1,
81  int v_count = -1,
82  bool use_instancing = false)
83 {
84  if (grp == nullptr) {
85  return;
86  }
87 
88  if (v_first == -1) {
89  DRW_shgroup_call(grp, geom, ob);
90  }
91  else if (use_instancing) {
92  DRW_shgroup_call_instance_range(grp, ob, geom, v_first, v_count);
93  }
94  else {
95  DRW_shgroup_call_range(grp, ob, geom, v_first, v_count);
96  }
97 }
98 
101 /* -------------------------------------------------------------------- */
106 {
107  bool has_motion = inst_.velocity.step_object_sync(ob, ob_handle.object_key, ob_handle.recalc);
108 
109  MaterialArray &material_array = inst_.materials.material_array_get(ob, has_motion);
110 
112  ob, material_array.gpu_materials.data(), material_array.gpu_materials.size());
113 
114  if (mat_geom == nullptr) {
115  return;
116  }
117 
118  bool is_shadow_caster = false;
119  bool is_alpha_blend = false;
120  for (auto i : material_array.gpu_materials.index_range()) {
121  GPUBatch *geom = mat_geom[i];
122  if (geom == nullptr) {
123  continue;
124  }
125  Material *material = material_array.materials[i];
126  shgroup_geometry_call(material->shading.shgrp, ob, geom);
127  shgroup_geometry_call(material->prepass.shgrp, ob, geom);
128  shgroup_geometry_call(material->shadow.shgrp, ob, geom);
129 
130  is_shadow_caster = is_shadow_caster || material->shadow.shgrp != nullptr;
131  is_alpha_blend = is_alpha_blend || material->is_alpha_blend_transparent;
132  }
133 
134  // shadows.sync_object(ob, ob_handle, is_shadow_caster, is_alpha_blend);
135 }
136 
139 /* -------------------------------------------------------------------- */
143 #define DO_BATCHING true
144 
145 struct gpIterData {
149  int cfra;
150 
151  /* Drawcall batching. */
152  GPUBatch *geom = nullptr;
153  Material *material = nullptr;
154  int vfirst = 0;
155  int vcount = 0;
156  bool instancing = false;
157 
158  gpIterData(Instance &inst_, Object *ob_, ObjectHandle &ob_handle)
159  : inst(inst_),
160  ob(ob_),
161  material_array(inst_.materials.material_array_get(
162  ob_, inst_.velocity.step_object_sync(ob, ob_handle.object_key, ob_handle.recalc)))
163  {
165  };
166 };
167 
169 {
170  if (iter.geom != nullptr) {
172  iter.ob,
173  iter.geom,
174  iter.vfirst,
175  iter.vcount,
176  iter.instancing);
178  iter.ob,
179  iter.geom,
180  iter.vfirst,
181  iter.vcount,
182  iter.instancing);
184  iter.ob,
185  iter.geom,
186  iter.vfirst,
187  iter.vcount,
188  iter.instancing);
189  }
190  iter.geom = nullptr;
191  iter.vfirst = -1;
192  iter.vcount = 0;
193 }
194 
195 /* Group draw-calls that are consecutive and with the same type. Reduces GPU driver overhead. */
197  GPUBatch *geom,
199  int v_first,
200  int v_count,
201  bool instancing)
202 {
203  int last = iter.vfirst + iter.vcount;
204  /* Interrupt draw-call grouping if the sequence is not consecutive. */
205  if (!DO_BATCHING || (geom != iter.geom) || (material != iter.material) || (v_first - last > 3)) {
207  }
208  iter.geom = geom;
209  iter.material = material;
210  iter.instancing = instancing;
211  if (iter.vfirst == -1) {
212  iter.vfirst = v_first;
213  }
214  iter.vcount = v_first + v_count - iter.vfirst;
215 }
216 
218  bGPDframe *UNUSED(gpf),
219  bGPDstroke *gps,
220  void *thunk)
221 {
222  gpIterData &iter = *(gpIterData *)thunk;
223 
225  MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(iter.ob, gps->mat_nr + 1);
226 
227  bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
228  bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0) ||
229  (!DRW_state_is_image_render() && ((gps->flag & GP_STROKE_NOFILL) != 0));
230  bool show_fill = (gps->tot_triangles > 0) && ((gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0);
231 
232  if (hide_material) {
233  return;
234  }
235 
236  if (show_fill) {
237  GPUBatch *geom = DRW_cache_gpencil_fills_get(iter.ob, iter.cfra);
238  int vfirst = gps->runtime.fill_start * 3;
239  int vcount = gps->tot_triangles * 3;
240  gpencil_drawcall_add(iter, geom, material, vfirst, vcount, false);
241  }
242 
243  if (show_stroke) {
244  GPUBatch *geom = DRW_cache_gpencil_strokes_get(iter.ob, iter.cfra);
245  /* Start one vert before to have gl_InstanceID > 0 (see shader). */
246  int vfirst = gps->runtime.stroke_start - 1;
247  /* Include "potential" cyclic vertex and start adj vertex (see shader). */
248  int vcount = gps->totpoints + 1 + 1;
249  gpencil_drawcall_add(iter, geom, material, vfirst, vcount, true);
250  }
251 }
252 
254 {
255  /* TODO(fclem): Waiting for a user option to use the render engine instead of gpencil engine. */
256  if (true) {
257  inst_.gpencil_engine_enabled = true;
258  return;
259  }
260 
261  gpIterData iter(inst_, ob, ob_handle);
262 
264 
266 
267  // bool is_caster = true; /* TODO material.shadow.shgrp. */
268  // bool is_alpha_blend = true; /* TODO material.is_alpha_blend. */
269  // shadows.sync_object(ob, ob_handle, is_caster, is_alpha_blend);
270 }
271 
274 /* -------------------------------------------------------------------- */
278 static void shgroup_curves_call(MaterialPass &matpass,
279  Object *ob,
280  ParticleSystem *part_sys = nullptr,
281  ModifierData *modifier_data = nullptr)
282 {
283  if (matpass.shgrp == nullptr) {
284  return;
285  }
286  if (part_sys != nullptr) {
287  DRW_shgroup_hair_create_sub(ob, part_sys, modifier_data, matpass.shgrp, matpass.gpumat);
288  }
289  else {
290  DRW_shgroup_curves_create_sub(ob, matpass.shgrp, matpass.gpumat);
291  }
292 }
293 
294 void SyncModule::sync_curves(Object *ob, ObjectHandle &ob_handle, ModifierData *modifier_data)
295 {
296  int mat_nr = CURVES_MATERIAL_NR;
297 
298  ParticleSystem *part_sys = nullptr;
299  if (modifier_data != nullptr) {
300  part_sys = reinterpret_cast<ParticleSystemModifierData *>(modifier_data)->psys;
302  return;
303  }
304  ParticleSettings *part_settings = part_sys->part;
305  const int draw_as = (part_settings->draw_as == PART_DRAW_REND) ? part_settings->ren_as :
306  part_settings->draw_as;
307  if (draw_as != PART_DRAW_PATH) {
308  return;
309  }
310  mat_nr = part_settings->omat;
311  }
312 
313  bool has_motion = inst_.velocity.step_object_sync(ob, ob_handle.object_key, ob_handle.recalc);
314  Material &material = inst_.materials.material_get(ob, has_motion, mat_nr - 1, MAT_GEOM_CURVES);
315 
316  shgroup_curves_call(material.shading, ob, part_sys, modifier_data);
317  shgroup_curves_call(material.prepass, ob, part_sys, modifier_data);
318  shgroup_curves_call(material.shadow, ob, part_sys, modifier_data);
319 
320  /* TODO(fclem) Hair velocity. */
321  // shading_passes.velocity.gpencil_add(ob, ob_handle);
322 
323  // bool is_caster = material.shadow.shgrp != nullptr;
324  // bool is_alpha_blend = material.is_alpha_blend_transparent;
325  // shadows.sync_object(ob, ob_handle, is_caster, is_alpha_blend);
326 }
327 
330 } // namespace blender::eevee
void BKE_gpencil_visible_stroke_iter(struct bGPdata *gpd, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk)
Definition: gpencil.c:2389
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
Definition: material.c:805
General operations, lookup, etc. for blender objects.
#define UNUSED_VARS(...)
#define UNUSED(x)
float DEG_get_ctime(const Depsgraph *graph)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_SHADING
Definition: DNA_ID.h:811
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ ID_RECALC_ALL
Definition: DNA_ID.h:891
#define CURVES_MATERIAL_NR
@ GP_STROKE_NOFILL
@ GP_MATERIAL_HIDE
@ GP_MATERIAL_STROKE_SHOW
@ GP_MATERIAL_FILL_SHOW
#define PART_DRAW_PATH
#define PART_DRAW_REND
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
GPUBatch
Definition: GPU_batch.h:78
int64_t size() const
Definition: BLI_vector.hh:694
IndexRange index_range() const
Definition: BLI_vector.hh:920
A running instance of the engine.
Material & material_get(Object *ob, bool has_motion, int mat_nr, eMaterialGeometry geometry_type)
MaterialArray & material_array_get(Object *ob, bool has_motion)
ObjectHandle & sync_object(Object *ob)
Definition: eevee_sync.cc:36
void sync_gpencil(Object *ob, ObjectHandle &ob_handle)
Definition: eevee_sync.cc:253
WorldHandle & sync_world(::World *world)
Definition: eevee_sync.cc:57
void sync_mesh(Object *ob, ObjectHandle &ob_handle)
Definition: eevee_sync.cc:105
void sync_curves(Object *ob, ObjectHandle &ob_handle, ModifierData *modifier_data=nullptr)
Definition: eevee_sync.cc:294
bool step_object_sync(Object *ob, ObjectKey &object_key, int recalc=0)
World world
Material material
GPUBatch ** DRW_cache_object_surface_material_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
Definition: draw_cache.c:971
struct GPUBatch * DRW_cache_gpencil_strokes_get(struct Object *ob, int cfra)
struct GPUBatch * DRW_cache_gpencil_fills_get(struct Object *ob, int cfra)
struct DRWShadingGroup * DRW_shgroup_curves_create_sub(struct Object *object, struct DRWShadingGroup *shgrp, struct GPUMaterial *gpu_material)
Definition: draw_curves.cc:303
struct DRWShadingGroup * DRW_shgroup_hair_create_sub(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md, struct DRWShadingGroup *shgrp, struct GPUMaterial *gpu_material)
Definition: draw_hair.cc:235
DrawData * DRW_drawdata_ensure(ID *id, DrawEngineType *engine_type, size_t size, DrawDataInitCb init_cb, DrawDataFreeCb free_cb)
Definition: draw_manager.c:866
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
Definition: draw_manager.c:234
bool DRW_state_is_image_render(void)
void DRW_shgroup_call_instance_range(DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_num)
void DRW_shgroup_call_range(DRWShadingGroup *shgroup, struct Object *ob, GPUBatch *geom, uint v_sta, uint v_num)
RenderEngineType DRW_engine_viewport_eevee_next_type
#define DO_BATCHING
Definition: eevee_sync.cc:143
smooth(Type::VEC4, "color_mul") .smooth(Type gpFillTexture gpSceneDepthTexture materials[GPENCIL_MATERIAL_BUFFER_LEN]
Definition: gpencil_info.hh:29
static void draw_data_init_cb(struct DrawData *dd)
Definition: eevee_sync.cc:30
static void shgroup_geometry_call(DRWShadingGroup *grp, Object *ob, GPUBatch *geom, int v_first=-1, int v_count=-1, bool use_instancing=false)
Definition: eevee_sync.cc:77
static void gpencil_stroke_sync(bGPDlayer *UNUSED(gpl), bGPDframe *UNUSED(gpf), bGPDstroke *gps, void *thunk)
Definition: eevee_sync.cc:217
static void gpencil_drawcall_flush(gpIterData &iter)
Definition: eevee_sync.cc:168
static void shgroup_curves_call(MaterialPass &matpass, Object *ob, ParticleSystem *part_sys=nullptr, ModifierData *modifier_data=nullptr)
Definition: eevee_sync.cc:278
static void gpencil_drawcall_add(gpIterData &iter, GPUBatch *geom, Material *material, int v_first, int v_count, bool instancing)
Definition: eevee_sync.cc:196
int recalc
Definition: DNA_ID.h:40
Definition: DNA_ID.h:368
void * data
ParticleSettings * part
bGPDstroke_Runtime runtime
Vector< Material * > materials
Vector< GPUMaterial * > gpu_materials
MaterialArray & material_array
Definition: eevee_sync.cc:148
gpIterData(Instance &inst_, Object *ob_, ObjectHandle &ob_handle)
Definition: eevee_sync.cc:158