Blender  V3.3
eevee_materials.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
8 #include "DRW_render.h"
9 
10 #include "BLI_alloca.h"
11 #include "BLI_ghash.h"
12 #include "BLI_listbase.h"
13 #include "BLI_math_bits.h"
14 #include "BLI_memblock.h"
15 #include "BLI_rand.h"
16 #include "BLI_string_utils.h"
17 
18 #include "BKE_paint.h"
19 #include "BKE_particle.h"
20 
21 #include "DNA_curves_types.h"
22 #include "DNA_modifier_types.h"
23 #include "DNA_view3d_types.h"
24 #include "DNA_world_types.h"
25 
26 #include "GPU_material.h"
27 
28 #include "DEG_depsgraph_query.h"
29 
30 #include "eevee_engine.h"
31 #include "eevee_lut.h"
32 #include "eevee_private.h"
33 
34 /* *********** STATIC *********** */
35 static struct {
36  /* 64*64 array texture containing all LUTs and other utilitarian arrays.
37  * Packing enables us to same precious textures slots. */
40 
41  float noise_offsets[3];
42 } e_data = {NULL}; /* Engine data */
43 
44 typedef struct EeveeMaterialCache {
49  /* Meh, Used by hair to ensure draw order when calling DRW_shgroup_create_sub.
50  * Pointers to ghash values. */
55 
56 /* *********** FUNCTIONS *********** */
57 
58 /* XXX TODO: define all shared resources in a shared place without duplication. */
60 {
61  return e_data.util_tex;
62 }
63 
65  GPUMaterial *gpumat,
66  EEVEE_ViewLayerData *sldata,
67  EEVEE_Data *vedata,
68  const int *ssr_id,
69  const float *refract_depth,
70  const float alpha_clip_threshold,
71  bool use_ssrefraction,
72  bool use_alpha_blend)
73 {
74  bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE);
75  bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY);
76  bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT);
77  bool use_ao = GPU_material_flag_get(gpumat, GPU_MATFLAG_AO);
78 
79 #ifdef __APPLE__
80  /* NOTE: Some implementation do not optimize out the unused samplers. */
81  use_diffuse = use_glossy = use_refract = use_ao = true;
82 #endif
83  LightCache *lcache = vedata->stl->g_data->light_cache;
84  EEVEE_EffectsInfo *effects = vedata->stl->effects;
85  EEVEE_PrivateData *pd = vedata->stl->g_data;
86 
87  DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
88  DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
89  DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
90  DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
91  DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
92  DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
93  DRW_shgroup_uniform_block_ref(shgrp, "renderpass_block", &pd->renderpass_ubo);
94 
95  DRW_shgroup_uniform_float_copy(shgrp, "alphaClipThreshold", alpha_clip_threshold);
96 
97  DRW_shgroup_uniform_int_copy(shgrp, "outputSssId", 1);
98  DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
99  if (use_diffuse || use_glossy || use_refract) {
100  DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool);
101  DRW_shgroup_uniform_texture_ref(shgrp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
102  }
103  if (use_diffuse || use_glossy || use_refract || use_ao) {
104  DRW_shgroup_uniform_texture_ref(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
105  }
106  if ((use_diffuse || use_glossy) && !use_ssrefraction) {
107  DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &effects->gtao_horizons);
108  }
109  if (use_diffuse) {
110  DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex);
111  }
112  if (use_glossy || use_refract) {
113  DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &lcache->cube_tx.tex);
114  }
115  if (use_glossy) {
116  DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool);
117  DRW_shgroup_uniform_int_copy(shgrp, "outputSsrId", ssr_id ? *ssr_id : 0);
118  }
119  else {
120  DRW_shgroup_uniform_int_copy(shgrp, "outputSsrId", 1);
121  }
122  if (use_refract) {
124  shgrp, "refractionDepth", (refract_depth) ? *refract_depth : 0.0);
125  if (use_ssrefraction) {
127  shgrp, "refractColorBuffer", &vedata->txl->filtered_radiance);
128  }
129  }
130  if (use_alpha_blend) {
131  DRW_shgroup_uniform_texture_ref(shgrp, "inScattering", &effects->volume_scatter);
132  DRW_shgroup_uniform_texture_ref(shgrp, "inTransmittance", &effects->volume_transmit);
133  }
134 }
135 
136 static void eevee_init_noise_texture(void)
137 {
138  e_data.noise_tex = DRW_texture_create_2d(64, 64, GPU_RGBA16F, 0, (float *)blue_noise);
139 }
140 
141 #define RUNTIME_LUT_CREATION 0
142 
143 static void eevee_init_util_texture(void)
144 {
145  const int layers = 4 + 16;
146  float(*texels)[4] = MEM_mallocN(sizeof(float[4]) * 64 * 64 * layers, "utils texels");
147  float(*texels_layer)[4] = texels;
148 #if RUNTIME_LUT_CREATION
149  float *bsdf_ggx_lut = EEVEE_lut_update_ggx_brdf(64);
150  float(*btdf_ggx_lut)[64 * 64 * 2] = (float(*)[64 * 64 * 2]) EEVEE_lut_update_ggx_btdf(64, 16);
151 #else
152  const float *bsdf_ggx_lut = bsdf_split_sum_ggx;
153  const float(*btdf_ggx_lut)[64 * 64 * 2] = btdf_split_sum_ggx;
154 #endif
155 
156  /* Copy ltc_mat_ggx into 1st layer */
157  memcpy(texels_layer, ltc_mat_ggx, sizeof(float[4]) * 64 * 64);
158  texels_layer += 64 * 64;
159 
160  /* Copy bsdf_split_sum_ggx into 2nd layer red and green channels.
161  * Copy ltc_mag_ggx into 2nd layer blue and alpha channel. */
162  for (int i = 0; i < 64 * 64; i++) {
163  texels_layer[i][0] = bsdf_ggx_lut[i * 2 + 0];
164  texels_layer[i][1] = bsdf_ggx_lut[i * 2 + 1];
165  texels_layer[i][2] = ltc_mag_ggx[i * 2 + 0];
166  texels_layer[i][3] = ltc_mag_ggx[i * 2 + 1];
167  }
168  texels_layer += 64 * 64;
169 
170  /* Copy blue noise in 3rd layer. */
171  for (int i = 0; i < 64 * 64; i++) {
172  texels_layer[i][0] = blue_noise[i][0];
173  texels_layer[i][1] = blue_noise[i][2];
174  texels_layer[i][2] = cosf(blue_noise[i][1] * 2.0f * M_PI);
175  texels_layer[i][3] = sinf(blue_noise[i][1] * 2.0f * M_PI);
176  }
177  texels_layer += 64 * 64;
178 
179  /* Copy ltc_disk_integral in 4th layer. */
180  for (int i = 0; i < 64 * 64; i++) {
181  texels_layer[i][0] = ltc_disk_integral[i];
182  texels_layer[i][1] = 0.0; /* UNUSED */
183  texels_layer[i][2] = 0.0; /* UNUSED */
184  texels_layer[i][3] = 0.0; /* UNUSED */
185  }
186  texels_layer += 64 * 64;
187 
188  /* Copy Refraction GGX LUT in layer 5 - 21 */
189  for (int j = 0; j < 16; j++) {
190  for (int i = 0; i < 64 * 64; i++) {
191  texels_layer[i][0] = btdf_ggx_lut[j][i * 2 + 0];
192  texels_layer[i][1] = btdf_ggx_lut[j][i * 2 + 1];
193  texels_layer[i][2] = 0.0; /* UNUSED */
194  texels_layer[i][3] = 0.0; /* UNUSED */
195  }
196  texels_layer += 64 * 64;
197  }
198 
200  64, 64, layers, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
201 
202  MEM_freeN(texels);
203 #if RUNTIME_LUT_CREATION
204  MEM_freeN(bsdf_ggx_lut);
205  MEM_freeN(btdf_ggx_lut);
206 #endif
207 }
208 
209 void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3])
210 {
211  e_data.noise_offsets[0] = offsets[0];
212  e_data.noise_offsets[1] = offsets[1];
213  e_data.noise_offsets[2] = offsets[2];
214 
217 }
218 
220  EEVEE_Data *vedata,
221  EEVEE_StorageList *stl,
223 {
224  const DRWContextState *draw_ctx = DRW_context_state_get();
226 
227  if (!e_data.util_tex) {
229 
232  }
233 
234  if (!DRW_state_is_image_render() && ((stl->effects->enabled_effects & EFFECT_TAA) == 0)) {
235  sldata->common_data.alpha_hash_offset = 0.0f;
236  sldata->common_data.alpha_hash_scale = 1.0f;
237  }
238  else {
239  double r;
240  BLI_halton_1d(5, 0.0, stl->effects->taa_current_sample - 1, &r);
242  sldata->common_data.alpha_hash_scale = 0.01f;
243  }
244 
245  {
246  /* Update noise Frame-buffer. */
247  GPU_framebuffer_ensure_config(
248  &fbl->update_noise_fb,
249  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(e_data.util_tex, 2)});
250  }
251 
252  {
253  /* Create RenderPass UBO */
254  if (sldata->renderpass_ubo.combined == NULL) {
256  data = (EEVEE_RenderPassData){true, true, true, true, true, false, false, false, 0};
258  sizeof(data), &data, "renderpass_ubo.combined");
259 
260  data = (EEVEE_RenderPassData){true, false, false, false, false, true, false, false, 0};
262  sizeof(data), &data, "renderpass_ubo.diff_color");
263 
264  data = (EEVEE_RenderPassData){true, true, false, false, false, false, false, false, 0};
266  sizeof(data), &data, "renderpass_ubo.diff_light");
267 
268  data = (EEVEE_RenderPassData){false, false, true, false, false, false, false, false, 0};
270  sizeof(data), &data, "renderpass_ubo.spec_color");
271 
272  data = (EEVEE_RenderPassData){false, false, true, true, false, false, false, false, 0};
274  sizeof(data), &data, "renderpass_ubo.spec_light");
275 
276  data = (EEVEE_RenderPassData){false, false, false, false, true, false, false, false, 0};
278  sizeof(data), &data, "renderpass_ubo.emit");
279 
280  data = (EEVEE_RenderPassData){true, true, true, true, true, false, true, false, 0};
282  sizeof(data), &data, "renderpass_ubo.environment");
283  }
284 
285  /* Used combined pass by default. */
286  g_data->renderpass_ubo = sldata->renderpass_ubo.combined;
287 
288  {
289  g_data->num_aovs_used = 0;
290  if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) {
291  EEVEE_RenderPassData data = {true, true, true, true, true, false, false, true, 0};
292  if (stl->g_data->aov_hash == EEVEE_AOV_HASH_ALL) {
293  ViewLayer *view_layer = draw_ctx->view_layer;
294  int aov_index = 0;
295  LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
296  if ((aov->flag & AOV_CONFLICT) != 0) {
297  continue;
298  }
299  if (aov_index == MAX_AOVS) {
300  break;
301  }
302  data.renderPassAOVActive = EEVEE_renderpasses_aov_hash(aov);
303  if (sldata->renderpass_ubo.aovs[aov_index]) {
304  GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[aov_index], &data);
305  }
306  else {
307  sldata->renderpass_ubo.aovs[aov_index] = GPU_uniformbuf_create_ex(
308  sizeof(data), &data, "renderpass_ubo.aovs");
309  }
310  aov_index++;
311  }
312  g_data->num_aovs_used = aov_index;
313  }
314  else {
315  /* Rendering a single AOV in the 3d viewport */
316  data.renderPassAOVActive = stl->g_data->aov_hash;
317  if (sldata->renderpass_ubo.aovs[0]) {
319  }
320  else {
322  sizeof(data), &data, "renderpass_ubo.aovs");
323  }
324  g_data->num_aovs_used = 1;
325  }
326  }
327  /* Free AOV UBO's that are not in use. */
328  for (int aov_index = g_data->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
329  DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]);
330  }
331  }
332 
333  /* HACK: EEVEE_material_get can create a new context. This can only be
334  * done when there is no active framebuffer. We do this here otherwise
335  * `EEVEE_renderpasses_output_init` will fail. It cannot be done in
336  * `EEVEE_renderpasses_init` as the `e_data.vertcode` can be uninitialized.
337  */
338  if (g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
339  struct Scene *scene = draw_ctx->scene;
340  struct World *wo = scene->world;
341  if (wo && wo->use_nodes) {
343  }
344  }
345  }
346 }
347 
349 {
350  EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
351  EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
352  const DRWContextState *draw_ctx = DRW_context_state_get();
353 
354  /* Create Material #GHash. */
355  {
356  stl->g_data->material_hash = BLI_ghash_ptr_new("Eevee_material ghash");
357 
358  if (sldata->material_cache == NULL) {
360  }
361  else {
363  }
364  }
365 
366  {
368 
369  DRWShadingGroup *grp = NULL;
370  EEVEE_lookdev_cache_init(vedata, sldata, psl->background_ps, NULL, &grp);
371 
372  if (grp == NULL) {
373  Scene *scene = draw_ctx->scene;
375 
376  const int options = VAR_WORLD_BACKGROUND;
377  struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
378 
379  grp = DRW_shgroup_material_create(gpumat, psl->background_ps);
380  DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
381  }
382 
383  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
384  DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
385  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
386  DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
387  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
388  DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
389  DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
390  DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex);
391  DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
392  DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
393  DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
394  DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &stl->g_data->light_cache->cube_tx.tex);
395  DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &stl->g_data->light_cache->grid_tx.tex);
396  DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &vedata->txl->maxzbuffer);
398  }
399 
400 #define EEVEE_PASS_CREATE(pass, state) \
401  do { \
402  DRW_PASS_CREATE(psl->pass##_ps, state); \
403  DRW_PASS_CREATE(psl->pass##_cull_ps, state | DRW_STATE_CULL_BACK); \
404  DRW_pass_link(psl->pass##_ps, psl->pass##_cull_ps); \
405  } while (0)
406 
407 #define EEVEE_CLIP_PASS_CREATE(pass, state) \
408  do { \
409  DRWState st = state | DRW_STATE_CLIP_PLANES; \
410  DRW_PASS_INSTANCE_CREATE(psl->pass##_clip_ps, psl->pass##_ps, st); \
411  DRW_PASS_INSTANCE_CREATE( \
412  psl->pass##_clip_cull_ps, psl->pass##_cull_ps, st | DRW_STATE_CULL_BACK); \
413  DRW_pass_link(psl->pass##_clip_ps, psl->pass##_clip_cull_ps); \
414  } while (0)
415 
416  {
420 
421  EEVEE_PASS_CREATE(depth, state_depth);
422  EEVEE_CLIP_PASS_CREATE(depth, state_depth);
423 
424  EEVEE_PASS_CREATE(depth_refract, state_depth);
425  EEVEE_CLIP_PASS_CREATE(depth_refract, state_depth);
426 
427  EEVEE_PASS_CREATE(material, state_shading);
428  EEVEE_PASS_CREATE(material_refract, state_shading);
429  EEVEE_PASS_CREATE(material_sss, state_shading | state_sss);
430  }
431  {
432  /* Renderpass accumulation. */
434  /* Create an instance of each of these passes and link them together. */
435  DRWPass *passes[] = {
436  psl->material_ps,
437  psl->material_cull_ps,
438  psl->material_sss_ps,
440  };
441  DRWPass *first = NULL, *last = NULL;
442  for (int i = 0; i < ARRAY_SIZE(passes); i++) {
443  DRWPass *pass = DRW_pass_create_instance("Renderpass Accumulation", passes[i], state);
444  if (first == NULL) {
445  first = last = pass;
446  }
447  else {
448  DRW_pass_link(last, pass);
449  last = pass;
450  }
451  }
452  psl->material_accum_ps = first;
453 
454  /* Same for background */
456  }
457  {
460  }
461  {
465  DRW_shgroup_uniform_texture(grp, "blueNoise", e_data.noise_tex);
466  DRW_shgroup_uniform_vec3(grp, "offsets", e_data.noise_offsets, 1);
468  }
469 }
470 
472  EEVEE_ViewLayerData *sldata,
473  Material *ma,
474  bool is_hair,
475  EeveeMaterialCache *emc)
476 {
477  EEVEE_PrivateData *pd = vedata->stl->g_data;
478  EEVEE_PassList *psl = vedata->psl;
479  const DRWContextState *draw_ctx = DRW_context_state_get();
480  Scene *scene = draw_ctx->scene;
481 
482  if (ma->blend_shadow != MA_BS_NONE) {
483  /* Shadow Pass */
484  const bool use_shadow_shader = ma->use_nodes && ma->nodetree &&
486  float alpha_clip_threshold = (ma->blend_shadow == MA_BS_CLIP) ? ma->alpha_threshold : -1.0f;
487 
488  int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
489  SET_FLAG_FROM_TEST(mat_options, use_shadow_shader, VAR_MAT_HASH);
490  SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
491  GPUMaterial *gpumat = (use_shadow_shader) ?
492  EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
493  EEVEE_material_default_get(scene, ma, mat_options);
494 
495  /* Avoid possible confusion with depth pre-pass options. */
496  int option = KEY_SHADOW;
497  SET_FLAG_FROM_TEST(option, is_hair, KEY_HAIR);
498 
499  /* Search for the same shaders usage in the pass. */
500  struct GPUShader *sh = GPU_material_get_shader(gpumat);
501  void *cache_key = (char *)sh + option;
502  DRWShadingGroup *grp, **grp_p;
503 
504  if (BLI_ghash_ensure_p(pd->material_hash, cache_key, (void ***)&grp_p)) {
505  /* This GPUShader has already been used by another material.
506  * Add new shading group just after to avoid shader switching cost. */
507  grp = DRW_shgroup_create_sub(*grp_p);
508  }
509  else {
510  *grp_p = grp = DRW_shgroup_create(sh, psl->shadow_pass);
512  grp, gpumat, sldata, vedata, NULL, NULL, alpha_clip_threshold, false, false);
513  }
514 
516 
517  emc->shadow_grp = grp;
518  emc->shadow_grp_p = grp_p;
519  }
520  else {
521  emc->shadow_grp = NULL;
522  emc->shadow_grp_p = NULL;
523  }
524 }
525 
527  EEVEE_ViewLayerData *sldata,
528  Material *ma,
529  const bool is_hair)
530 {
531  EEVEE_EffectsInfo *effects = vedata->stl->effects;
532  EEVEE_PrivateData *pd = vedata->stl->g_data;
533  EEVEE_PassList *psl = vedata->psl;
534  const DRWContextState *draw_ctx = DRW_context_state_get();
535  Scene *scene = draw_ctx->scene;
536 
537  const bool do_cull = !is_hair && (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
538  const bool use_gpumat = (ma->use_nodes && ma->nodetree);
539  const bool use_ssrefract = use_gpumat && ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
540  ((effects->enabled_effects & EFFECT_REFRACT) != 0);
541  const bool use_depth_shader = use_gpumat && ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED);
542  float alpha_clip_threshold = (ma->blend_method == MA_BM_CLIP) ? ma->alpha_threshold : -1.0f;
543 
544  /* HACK: Assume the struct will never be smaller than our variations.
545  * This allow us to only keep one ghash and avoid bigger keys comparisons/hashing. */
546  void *key = (char *)ma + is_hair;
547  /* Search for other material instances (sharing the same Material data-block). */
548  EeveeMaterialCache **emc_p, *emc;
549  if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) {
550  return **emc_p;
551  }
552 
553  *emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
554 
555  material_shadow(vedata, sldata, ma, is_hair, emc);
556 
557  {
558  /* Depth Pass */
559  int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
560  SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
561  SET_FLAG_FROM_TEST(mat_options, use_depth_shader, VAR_MAT_HASH);
562  SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
563  GPUMaterial *gpumat = (use_depth_shader) ?
564  EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
565  EEVEE_material_default_get(scene, ma, mat_options);
566 
567  int option = 0;
568  SET_FLAG_FROM_TEST(option, do_cull, KEY_CULL);
569  SET_FLAG_FROM_TEST(option, use_ssrefract, KEY_REFRACT);
570  DRWPass *depth_ps = (DRWPass *[]){
571  psl->depth_ps,
572  psl->depth_cull_ps,
573  psl->depth_refract_ps,
575  }[option];
576  /* Hair are rendered inside the non-cull pass but needs to have a separate cache key. */
577  SET_FLAG_FROM_TEST(option, is_hair, KEY_HAIR);
578 
579  /* Search for the same shaders usage in the pass. */
580  struct GPUShader *sh = GPU_material_get_shader(gpumat);
581  void *cache_key = (char *)sh + option;
582  DRWShadingGroup *grp, **grp_p;
583 
584  if (BLI_ghash_ensure_p(pd->material_hash, cache_key, (void ***)&grp_p)) {
585  /* This GPUShader has already been used by another material.
586  * Add new shading group just after to avoid shader switching cost. */
587  grp = DRW_shgroup_create_sub(*grp_p);
588  }
589  else {
590  *grp_p = grp = DRW_shgroup_create(sh, depth_ps);
592  grp, gpumat, sldata, vedata, NULL, NULL, alpha_clip_threshold, false, false);
593  }
594 
596 
597  emc->depth_grp = grp;
598  emc->depth_grp_p = grp_p;
599  }
600  {
601  /* Shading Pass */
602  int mat_options = VAR_MAT_MESH;
603  SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
604  SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
605  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
606  const bool use_sss = GPU_material_flag_get(gpumat, GPU_MATFLAG_SUBSURFACE);
607 
608  int ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_ssrefract) ? 1 : 0;
609  int option = (use_ssrefract ? 0 : (use_sss ? 1 : 2)) * 2 + do_cull;
610  DRWPass *shading_pass = (DRWPass *[]){
611  psl->material_refract_ps,
613  psl->material_sss_ps,
615  psl->material_ps,
616  psl->material_cull_ps,
617  }[option];
618  /* Hair are rendered inside the non-cull pass but needs to have a separate cache key */
619  option = option * 2 + is_hair;
620 
621  /* Search for the same shaders usage in the pass. */
622  /* HACK: Assume the struct will never be smaller than our variations.
623  * This allow us to only keep one ghash and avoid bigger keys comparisons/hashing. */
624  BLI_assert(option <= 16);
625  struct GPUShader *sh = GPU_material_get_shader(gpumat);
626  void *cache_key = (char *)sh + option;
627  DRWShadingGroup *grp, **grp_p;
628 
629  if (BLI_ghash_ensure_p(pd->material_hash, cache_key, (void ***)&grp_p)) {
630  /* This GPUShader has already been used by another material.
631  * Add new shading group just after to avoid shader switching cost. */
632  grp = DRW_shgroup_create_sub(*grp_p);
633 
634  /* Per material uniforms. */
635  if (use_ssrefract) {
636  DRW_shgroup_uniform_float_copy(grp, "refractionDepth", ma->refract_depth);
637  }
638  }
639  else {
640  *grp_p = grp = DRW_shgroup_create(sh, shading_pass);
642  gpumat,
643  sldata,
644  vedata,
645  &ssr_id,
646  &ma->refract_depth,
647  alpha_clip_threshold,
648  use_ssrefract,
649  false);
650  }
652 
653  if (use_sss) {
654  EEVEE_subsurface_add_pass(sldata, vedata, ma, grp, gpumat);
655  }
656 
657  emc->shading_grp = grp;
658  emc->shading_grp_p = grp_p;
659  emc->shading_gpumat = gpumat;
660  }
661  return *emc;
662 }
663 
665  EEVEE_ViewLayerData *sldata,
666  Material *ma)
667 {
668  const DRWContextState *draw_ctx = DRW_context_state_get();
669  Scene *scene = draw_ctx->scene;
670  EEVEE_PassList *psl = vedata->psl;
671  EEVEE_EffectsInfo *effects = vedata->stl->effects;
672  EeveeMaterialCache emc = {0};
673 
674  const bool do_cull = (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
675  const bool use_gpumat = ma->use_nodes && ma->nodetree;
676  const bool use_ssrefract = use_gpumat && ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
677  ((effects->enabled_effects & EFFECT_REFRACT) != 0);
678  const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKFACE) != 0);
679 
680  DRWState cur_state;
684 
685  material_shadow(vedata, sldata, ma, false, &emc);
686 
687  if (use_prepass) {
688  /* Depth prepass */
689  int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
690  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
691  struct GPUShader *sh = GPU_material_get_shader(gpumat);
692 
694 
695  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, -1.0f, false, true);
697 
699  cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
700 
701  DRW_shgroup_state_disable(grp, all_state);
702  DRW_shgroup_state_enable(grp, cur_state);
703 
704  emc.depth_grp = grp;
705  }
706  {
707  /* Shading */
708  int ssr_id = -1; /* TODO: transparent SSR. */
709  int mat_options = VAR_MAT_MESH | VAR_MAT_BLEND;
710  SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
711  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
712 
714  psl->transparent_pass);
715 
717  grp, gpumat, sldata, vedata, &ssr_id, &ma->refract_depth, -1.0f, use_ssrefract, true);
719 
721  cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL;
722  cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
723 
724  /* Disable other blend modes and use the one we want. */
725  DRW_shgroup_state_disable(grp, all_state);
726  DRW_shgroup_state_enable(grp, cur_state);
727 
728  emc.shading_grp = grp;
729  emc.shading_gpumat = gpumat;
730  }
731  return emc;
732 }
733 
734 /* Return correct material or empty default material if slot is empty. */
736 {
737  if (holdout) {
739  }
740  Material *ma = BKE_object_material_get_eval(ob, slot + 1);
741  if (ma == NULL) {
742  if (ob->type == OB_VOLUME) {
744  }
745  else {
747  }
748  }
749  return ma;
750 }
751 
753  EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, int slot, bool is_hair)
754 {
755  const bool holdout = ((ob->base_flag & BASE_HOLDOUT) != 0) ||
756  ((ob->visibility_flag & OB_HOLDOUT) != 0);
757  EeveeMaterialCache matcache;
758  Material *ma = eevee_object_material_get(ob, slot, holdout);
759  switch (ma->blend_method) {
760  case MA_BM_BLEND:
761  if (!is_hair) {
762  matcache = material_transparent(vedata, sldata, ma);
763  break;
764  }
766  case MA_BM_SOLID:
767  case MA_BM_CLIP:
768  case MA_BM_HASHED:
769  default:
770  matcache = material_opaque(vedata, sldata, ma, is_hair);
771  break;
772  }
773  return matcache;
774 }
775 
776 #define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) \
777  do { \
778  if (oedata) { \
779  DRW_shgroup_call_with_callback(shgrp, geom, ob, oedata); \
780  } \
781  else { \
782  DRW_shgroup_call(shgrp, geom, ob); \
783  } \
784  } while (0)
785 
786 #define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata) \
787  do { \
788  if (shgrp) { \
789  ADD_SHGROUP_CALL(shgrp, ob, geom, oedata); \
790  } \
791  } while (0)
792 
793 #define MATCACHE_AS_ARRAY(matcache, member, materials_len, output_array) \
794  for (int i = 0; i < materials_len; i++) { \
795  output_array[i] = matcache[i].member; \
796  }
797 
799  EEVEE_ViewLayerData *sldata,
800  Object *ob,
801  bool *cast_shadow)
802 {
803  const DRWContextState *draw_ctx = DRW_context_state_get();
804  Scene *scene = draw_ctx->scene;
805 
806  bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
808 
809  /* First get materials for this mesh. */
810  if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) {
811  const int materials_len = DRW_cache_object_material_count_get(ob);
812 
813  EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len);
814  for (int i = 0; i < materials_len; i++) {
815  matcache[i] = eevee_material_cache_get(vedata, sldata, ob, i, false);
816  }
817 
818  /* Only support single volume material for now. */
819  /* XXX We rely on the previously compiled surface shader
820  * to know if the material has a "volume nodetree".
821  */
822  bool use_volume_material = (matcache[0].shading_gpumat &&
823  GPU_material_has_volume_output(matcache[0].shading_gpumat));
824  if ((ob->dt >= OB_SOLID) || DRW_state_is_scene_render()) {
825  if (use_sculpt_pbvh) {
826  struct DRWShadingGroup **shgrps_array = BLI_array_alloca(shgrps_array, materials_len);
827 
828  MATCACHE_AS_ARRAY(matcache, shading_grp, materials_len, shgrps_array);
829  DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
830 
831  MATCACHE_AS_ARRAY(matcache, depth_grp, materials_len, shgrps_array);
832  DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
833 
834  MATCACHE_AS_ARRAY(matcache, shadow_grp, materials_len, shgrps_array);
835  DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
836  }
837  else {
838  struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
839  MATCACHE_AS_ARRAY(matcache, shading_gpumat, materials_len, gpumat_array);
840  /* Get per-material split surface */
842  ob, gpumat_array, materials_len);
843 
844  if (mat_geom) {
845  for (int i = 0; i < materials_len; i++) {
846  if (mat_geom[i] == NULL) {
847  continue;
848  }
849 
850  /* Do not render surface if we are rendering a volume object
851  * and do not have a surface closure. */
852  if (use_volume_material &&
853  (gpumat_array[i] && !GPU_material_has_surface_output(gpumat_array[i]))) {
854  continue;
855  }
856 
857  /* XXX TODO: rewrite this to include the dupli objects.
858  * This means we cannot exclude dupli objects from reflections!!! */
859  EEVEE_ObjectEngineData *oedata = NULL;
860  if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
861  oedata = EEVEE_object_data_ensure(ob);
862  oedata->ob = ob;
863  oedata->test_data = &sldata->probes->vis_data;
864  }
865 
866  ADD_SHGROUP_CALL(matcache[i].shading_grp, ob, mat_geom[i], oedata);
867  ADD_SHGROUP_CALL_SAFE(matcache[i].depth_grp, ob, mat_geom[i], oedata);
868  ADD_SHGROUP_CALL_SAFE(matcache[i].shadow_grp, ob, mat_geom[i], oedata);
869  *cast_shadow = *cast_shadow || (matcache[i].shadow_grp != NULL);
870  }
871  }
872  }
873 
874  /* Motion Blur Vectors. */
875  EEVEE_motion_blur_cache_populate(sldata, vedata, ob);
876  }
877 
878  /* Volumetrics */
879  if (use_volume_material) {
880  EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
881  }
882  }
883 }
884 
886  EEVEE_ViewLayerData *sldata,
887  Object *ob,
888  bool *cast_shadow)
889 {
890  const DRWContextState *draw_ctx = DRW_context_state_get();
891 
892  if (ob->type == OB_MESH) {
893  if (ob != draw_ctx->object_edit) {
894  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
895  if (md->type != eModifierType_ParticleSystem) {
896  continue;
897  }
898  ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
900  continue;
901  }
902  ParticleSettings *part = psys->part;
903  const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
904  if (draw_as != PART_DRAW_PATH) {
905  continue;
906  }
908  vedata, sldata, ob, part->omat - 1, true);
909 
910  if (matcache.depth_grp) {
912  ob, psys, md, matcache.depth_grp, NULL);
913  }
914  if (matcache.shading_grp) {
916  ob, psys, md, matcache.shading_grp, matcache.shading_gpumat);
917  }
918  if (matcache.shadow_grp) {
920  ob, psys, md, matcache.shadow_grp, NULL);
921  *cast_shadow = true;
922  }
923 
924  EEVEE_motion_blur_hair_cache_populate(sldata, vedata, ob, psys, md);
925  }
926  }
927  }
928 }
929 
931  EEVEE_ViewLayerData *sldata,
932  Object *ob,
933  bool *cast_shadow)
934 {
936  vedata, sldata, ob, CURVES_MATERIAL_NR - 1, true);
937 
938  if (matcache.depth_grp) {
939  *matcache.depth_grp_p = DRW_shgroup_curves_create_sub(ob, matcache.depth_grp, NULL);
940  }
941  if (matcache.shading_grp) {
943  ob, matcache.shading_grp, matcache.shading_gpumat);
944  }
945  if (matcache.shadow_grp) {
946  *matcache.shadow_grp_p = DRW_shgroup_curves_create_sub(ob, matcache.shadow_grp, NULL);
947  *cast_shadow = true;
948  }
949 
950  EEVEE_motion_blur_curves_cache_populate(sldata, vedata, ob);
951 }
952 
954 {
955  EEVEE_PrivateData *pd = vedata->stl->g_data;
956  EEVEE_EffectsInfo *effects = vedata->stl->effects;
957 
959  pd->material_hash = NULL;
960 
962 }
963 
965 {
966  DRW_TEXTURE_FREE_SAFE(e_data.util_tex);
967  DRW_TEXTURE_FREE_SAFE(e_data.noise_tex);
968 }
969 
970 /* -------------------------------------------------------------------- */
975 {
976  EEVEE_PrivateData *pd = vedata->stl->g_data;
977 
978  /* For diffuse and glossy we calculate the final light + color buffer where we extract the
979  * light from by dividing by the color buffer. When one the light is requested we also tag
980  * the color buffer to do the extraction. */
983  }
986  }
987 }
988 
990 {
992 }
993 
995 {
996  EEVEE_FramebufferList *fbl = vedata->fbl;
998  EEVEE_TextureList *txl = vedata->txl;
999  EEVEE_StorageList *stl = vedata->stl;
1000  EEVEE_EffectsInfo *effects = stl->effects;
1001  EEVEE_PrivateData *pd = stl->g_data;
1002 
1003  /* Should be enough precision for many samples. */
1004  const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
1005 
1006  /* Create FrameBuffer. */
1007  GPU_framebuffer_ensure_config(&fbl->material_accum_fb,
1008  {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_LEAVE});
1009 
1011  material_renderpass_init(&txl->env_accum, texture_format);
1012  }
1014  material_renderpass_init(&txl->emit_accum, texture_format);
1015  }
1017  material_renderpass_init(&txl->diff_color_accum, texture_format);
1018  }
1020  material_renderpass_init(&txl->diff_light_accum, texture_format);
1021  }
1023  material_renderpass_init(&txl->spec_color_accum, texture_format);
1024  }
1026  for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
1027  material_renderpass_init(&txl->aov_surface_accum[aov_index], texture_format);
1028  }
1029  }
1031  material_renderpass_init(&txl->spec_light_accum, texture_format);
1032 
1033  if (effects->enabled_effects & EFFECT_SSR) {
1034  EEVEE_reflection_output_init(sldata, vedata, tot_samples);
1035  }
1036  }
1037 }
1038 
1040  EEVEE_FramebufferList *fbl,
1041  DRWPass *renderpass,
1042  DRWPass *renderpass2,
1043  EEVEE_PrivateData *pd,
1044  GPUTexture *output_tx,
1045  struct GPUUniformBuf *renderpass_option_ubo)
1046 {
1047  GPU_framebuffer_texture_attach(fbl->material_accum_fb, output_tx, 0, 0);
1049 
1050  if (effects->taa_current_sample == 1) {
1051  const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1052  GPU_framebuffer_clear_color(fbl->material_accum_fb, clear);
1053  }
1054 
1055  pd->renderpass_ubo = renderpass_option_ubo;
1056  DRW_draw_pass(renderpass);
1057  if (renderpass2) {
1058  DRW_draw_pass(renderpass2);
1059  }
1060 
1062 }
1063 
1065 {
1066  EEVEE_FramebufferList *fbl = vedata->fbl;
1067  EEVEE_PassList *psl = vedata->psl;
1068  EEVEE_PrivateData *pd = vedata->stl->g_data;
1069  EEVEE_EffectsInfo *effects = vedata->stl->effects;
1070  EEVEE_TextureList *txl = vedata->txl;
1071 
1072  if (fbl->material_accum_fb != NULL) {
1073  DRWPass *material_accum_ps = psl->material_accum_ps;
1074  DRWPass *background_accum_ps = psl->background_accum_ps;
1077  fbl,
1078  background_accum_ps,
1079  NULL,
1080  pd,
1081  txl->env_accum,
1082  sldata->renderpass_ubo.environment);
1083  }
1086  effects, fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit);
1087  }
1090  fbl,
1091  material_accum_ps,
1092  NULL,
1093  pd,
1094  txl->diff_color_accum,
1095  sldata->renderpass_ubo.diff_color);
1096  }
1099  fbl,
1100  material_accum_ps,
1101  NULL,
1102  pd,
1103  txl->diff_light_accum,
1104  sldata->renderpass_ubo.diff_light);
1105 
1106  if (effects->enabled_effects & EFFECT_SSS) {
1107  EEVEE_subsurface_output_accumulate(sldata, vedata);
1108  }
1109  }
1111  bool prev_ssr = sldata->common_data.ssr_toggle;
1112  if (prev_ssr) {
1113  /* We need to disable ssr here so output radiance is not directed to the ssr buffer. */
1114  sldata->common_data.ssr_toggle = false;
1115  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1116  }
1118  fbl,
1119  material_accum_ps,
1120  NULL,
1121  pd,
1122  txl->spec_color_accum,
1123  sldata->renderpass_ubo.spec_color);
1124  if (prev_ssr) {
1125  sldata->common_data.ssr_toggle = prev_ssr;
1126  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1127  }
1128  }
1131  fbl,
1132  material_accum_ps,
1133  NULL,
1134  pd,
1135  txl->spec_light_accum,
1136  sldata->renderpass_ubo.spec_light);
1137 
1138  if (effects->enabled_effects & EFFECT_SSR) {
1139  EEVEE_reflection_output_accumulate(sldata, vedata);
1140  }
1141  }
1143  for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
1145  fbl,
1146  material_accum_ps,
1147  background_accum_ps,
1148  pd,
1149  txl->aov_surface_accum[aov_index],
1150  sldata->renderpass_ubo.aovs[aov_index]);
1151  }
1152  }
1153  /* Free unused aov textures. */
1154  for (int aov_index = pd->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
1155  DRW_TEXTURE_FREE_SAFE(txl->aov_surface_accum[aov_index]);
1156  }
1157 
1158  /* Restore default. */
1159  pd->renderpass_ubo = sldata->renderpass_ubo.combined;
1161  }
1162 }
1163 
typedef float(TangentPoint)[2]
struct Material * BKE_material_default_surface(void)
Definition: material.c:2051
struct Material * BKE_material_default_holdout(void)
Definition: material.c:2046
struct Material * BKE_object_material_get_eval(struct Object *ob, short act)
Definition: material.c:707
struct Material * BKE_material_default_volume(void)
Definition: material.c:2056
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct RegionView3D *rv3d)
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:22
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define ATTR_FALLTHROUGH
#define BLI_INLINE
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:755
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define M_PI
Definition: BLI_math_base.h:20
#define BLI_memblock_create(elem_size)
Definition: BLI_memblock.h:32
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_memblock.c:115
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:86
Random number functions.
void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
Definition: rand.cc:287
unsigned int uint
Definition: BLI_sys_types.h:67
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define CURVES_MATERIAL_NR
@ EEVEE_RENDER_PASS_DIFFUSE_LIGHT
@ EEVEE_RENDER_PASS_AOV
@ EEVEE_RENDER_PASS_DIFFUSE_COLOR
@ EEVEE_RENDER_PASS_ENVIRONMENT
@ EEVEE_RENDER_PASS_SPECULAR_LIGHT
@ EEVEE_RENDER_PASS_SPECULAR_COLOR
@ EEVEE_RENDER_PASS_EMIT
@ BASE_FROM_DUPLI
@ BASE_HOLDOUT
@ AOV_CONFLICT
@ MA_BS_HASHED
@ MA_BS_CLIP
@ MA_BS_NONE
@ MA_BM_CLIP
@ MA_BM_HASHED
@ MA_BM_SOLID
@ MA_BM_BLEND
@ MA_BL_CULL_BACKFACE
@ MA_BL_SS_REFRACTION
@ MA_BL_HIDE_BACKFACE
@ eModifierType_ParticleSystem
@ OB_SOLID
@ OB_HOLDOUT
@ OB_MBALL
@ OB_SURF
@ OB_MESH
@ OB_VOLUME
#define PART_DRAW_PATH
#define PART_DRAW_REND
@ DRW_TEX_WRAP
Definition: DRW_render.h:141
@ DRW_TEX_FILTER
Definition: DRW_render.h:140
#define DRW_PASS_INSTANCE_CREATE(pass, original, state)
Definition: DRW_render.h:691
DRWState
Definition: DRW_render.h:298
@ DRW_STATE_CLIP_PLANES
Definition: DRW_render.h:342
@ DRW_STATE_STENCIL_ALWAYS
Definition: DRW_render.h:319
@ DRW_STATE_DEPTH_EQUAL
Definition: DRW_render.h:312
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:302
@ DRW_STATE_BLEND_ADD_FULL
Definition: DRW_render.h:326
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:311
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:316
@ DRW_STATE_BLEND_CUSTOM
Definition: DRW_render.h:336
@ DRW_STATE_WRITE_STENCIL
Definition: DRW_render.h:305
#define DRW_UBO_FREE_SAFE(ubo)
Definition: DRW_render.h:191
#define DRW_shgroup_uniform_block_ref(shgroup, name, ubo)
Definition: DRW_render.h:653
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
Definition: DRW_render.h:651
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:183
GPUBatch
Definition: GPU_batch.h:78
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, struct GPUTexture *tex)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
struct GPUShader * GPU_material_get_shader(GPUMaterial *material)
Definition: gpu_material.c:191
bool GPU_material_has_surface_output(GPUMaterial *mat)
Definition: gpu_material.c:586
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag)
Definition: gpu_material.c:601
@ GPU_MATFLAG_GLOSSY
Definition: GPU_material.h:73
@ GPU_MATFLAG_AO
Definition: GPU_material.h:79
@ GPU_MATFLAG_REFRACT
Definition: GPU_material.h:74
@ GPU_MATFLAG_DIFFUSE
Definition: GPU_material.h:71
@ GPU_MATFLAG_SUBSURFACE
Definition: GPU_material.h:72
bool GPU_material_has_volume_output(GPUMaterial *mat)
Definition: gpu_material.c:591
struct GPUShader GPUShader
Definition: GPU_shader.h:20
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
eGPUTextureFormat
Definition: GPU_texture.h:83
@ GPU_RGBA32F
Definition: GPU_texture.h:90
struct GPUUniformBuf GPUUniformBuf
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
CCL_NAMESPACE_BEGIN struct Options options
Scene scene
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
GPUBatch * DRW_cache_fullscreen_quad_get(void)
Definition: draw_cache.c:356
int DRW_cache_object_material_count_get(struct Object *ob)
Definition: draw_cache.c:936
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
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
Definition: draw_manager.c:234
const DRWContextState * DRW_context_state_get(void)
bool DRW_state_is_image_render(void)
bool DRW_state_is_scene_render(void)
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:638
DRWShadingGroup * DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
void DRW_pass_link(DRWPass *first, DRWPass *second)
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
DRWPass * DRW_pass_create_instance(const char *name, DRWPass *original, DRWState state)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **shgroups, int num_shgroups, Object *ob)
void DRW_draw_pass(DRWPass *pass)
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex, eGPUTextureFormat format, DRWTextureFlag flags)
GPUTexture * DRW_texture_create_2d_array(int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
GPUTexture * DRW_texture_create_2d(int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
static struct @318 g_data
EEVEE_ObjectEngineData * EEVEE_object_data_ensure(Object *ob)
Definition: eevee_data.c:290
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, DRWPass *pass, EEVEE_LightProbesInfo *pinfo, DRWShadingGroup **r_shgrp)
const float blue_noise[64 *64][4]
Definition: eevee_lut.c:3491
const float btdf_split_sum_ggx[16][64 *64 *2]
Definition: eevee_lut.c:6569
const float bsdf_split_sum_ggx[64 *64 *2]
Definition: eevee_lut.c:5542
const float ltc_mag_ggx[64 *64 *2]
Definition: eevee_lut.c:2061
const float ltc_disk_integral[64 *64]
Definition: eevee_lut.c:2975
const float ltc_mat_ggx[64 *64 *4]
Definition: eevee_lut.c:10
float * EEVEE_lut_update_ggx_brdf(int lut_size)
Definition: eevee_lut_gen.c:23
float * EEVEE_lut_update_ggx_btdf(int lut_size, int lut_depth)
Definition: eevee_lut_gen.c:60
struct EeveeMaterialCache EeveeMaterialCache
float noise_offsets[3]
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3])
void EEVEE_material_bind_resources(DRWShadingGroup *shgrp, GPUMaterial *gpumat, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, const int *ssr_id, const float *refract_depth, const float alpha_clip_threshold, bool use_ssrefraction, bool use_alpha_blend)
BLI_INLINE void material_shadow(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Material *ma, bool is_hair, EeveeMaterialCache *emc)
#define EEVEE_CLIP_PASS_CREATE(pass, state)
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
static EeveeMaterialCache material_opaque(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Material *ma, const bool is_hair)
#define EEVEE_PASS_CREATE(pass, state)
struct GPUTexture * noise_tex
#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata)
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
static struct @202 e_data
struct GPUTexture * util_tex
static EeveeMaterialCache material_transparent(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Material *ma)
#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata)
static void material_renderpass_init(GPUTexture **output_tx, const eGPUTextureFormat format)
static void eevee_init_util_texture(void)
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
BLI_INLINE Material * eevee_object_material_get(Object *ob, int slot, bool holdout)
BLI_INLINE EeveeMaterialCache eevee_material_cache_get(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, int slot, bool is_hair)
void EEVEE_material_renderpasses_init(EEVEE_Data *vedata)
void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
static void eevee_init_noise_texture(void)
void EEVEE_materials_free(void)
void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
void EEVEE_object_curves_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
#define MATCACHE_AS_ARRAY(matcache, member, materials_len, output_array)
struct GPUTexture * EEVEE_materials_get_util_tex(void)
static void material_renderpass_accumulate(EEVEE_EffectsInfo *effects, EEVEE_FramebufferList *fbl, DRWPass *renderpass, DRWPass *renderpass2, EEVEE_PrivateData *pd, GPUTexture *output_tx, struct GPUUniformBuf *renderpass_option_ubo)
void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob)
void EEVEE_motion_blur_curves_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob)
void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob, ParticleSystem *psys, ModifierData *md)
#define MAX_AOVS
Definition: eevee_private.h:41
@ VAR_WORLD_BACKGROUND
@ VAR_MAT_BLEND
@ VAR_MAT_HASH
@ VAR_MAT_DEPTH
@ VAR_MAT_REFRACT
@ VAR_MAT_MESH
@ VAR_MAT_HAIR
World * EEVEE_world_default_get(void)
void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct Scene *scene, Object *ob)
void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_reflection_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Material *ma, DRWShadingGroup *shgrp, struct GPUMaterial *gpumat)
void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
struct GPUMaterial * EEVEE_material_default_get(struct Scene *scene, Material *ma, int options)
uint EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov)
@ EFFECT_SSS
@ EFFECT_REFRACT
@ EFFECT_SSR
@ EFFECT_TAA
struct GPUMaterial * EEVEE_material_get(EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options)
struct GPUShader * EEVEE_shaders_update_noise_sh_get(void)
struct EEVEE_RenderPassData EEVEE_RenderPassData
@ KEY_HAIR
@ KEY_CULL
@ KEY_SHADOW
@ KEY_REFRACT
#define EEVEE_AOV_HASH_ALL
void EEVEE_shaders_material_shaders_init(void)
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static void clear(Message *msg)
Definition: msgfmt.c:278
struct Scene * scene
Definition: DRW_render.h:979
struct ViewLayer * view_layer
Definition: DRW_render.h:980
struct Object * object_edit
Definition: DRW_render.h:1003
struct RegionView3D * rv3d
Definition: DRW_render.h:975
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUTexture * gtao_horizons
struct GPUTexture * volume_transmit
struct GPUTexture * volume_scatter
EEVEE_EffectsFlag enabled_effects
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * update_noise_fb
struct GPUFrameBuffer * material_accum_fb
EEVEE_LightProbeVisTest vis_data
EEVEE_LightProbeVisTest * test_data
struct DRWPass * material_sss_ps
struct DRWPass * transparent_pass
struct DRWPass * depth_cull_ps
struct DRWPass * depth_refract_ps
struct DRWPass * material_accum_ps
struct DRWPass * depth_ps
struct DRWPass * material_refract_ps
struct DRWPass * material_sss_cull_ps
struct DRWPass * depth_refract_cull_ps
struct DRWPass * material_ps
struct DRWPass * background_accum_ps
struct DRWPass * update_noise_pass
struct DRWPass * shadow_pass
struct DRWPass * material_cull_ps
struct DRWPass * material_refract_cull_ps
struct DRWPass * background_ps
struct GPUUniformBuf * renderpass_ubo
eViewLayerEEVEEPassType render_passes
struct LightCache * light_cache
struct GHash * material_hash
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
struct GPUTexture * filtered_radiance
struct GPUTexture * spec_color_accum
struct GPUTexture * maxzbuffer
struct GPUTexture * diff_light_accum
struct GPUTexture * emit_accum
struct GPUTexture * planar_pool
struct GPUTexture * diff_color_accum
struct GPUTexture * spec_light_accum
struct GPUTexture * env_accum
struct GPUTexture * aov_surface_accum[MAX_AOVS]
struct EEVEE_CommonUniformBuffer common_data
struct GPUTexture * shadow_cube_pool
struct GPUUniformBuf * combined
struct GPUUniformBuf * diff_light
struct GPUUniformBuf * shadow_ubo
struct GPUUniformBuf * probe_ubo
struct GPUUniformBuf * grid_ubo
struct GPUUniformBuf * emit
struct GPUUniformBuf * planar_ubo
struct EEVEE_ViewLayerData::@210 renderpass_ubo
struct GPUUniformBuf * spec_color
struct GPUUniformBuf * environment
struct GPUUniformBuf * diff_color
struct GPUUniformBuf * spec_light
struct GPUUniformBuf * common_ubo
struct BLI_memblock * material_cache
struct GPUUniformBuf * light_ubo
struct GPUUniformBuf * aovs[MAX_AOVS]
struct GPUTexture * shadow_cascade_pool
struct EEVEE_LightProbesInfo * probes
struct DRWShadingGroup * depth_grp
struct DRWShadingGroup * shading_grp
struct GPUMaterial * shading_gpumat
struct DRWShadingGroup ** shadow_grp_p
struct DRWShadingGroup * shadow_grp
struct DRWShadingGroup ** depth_grp_p
struct DRWShadingGroup ** shading_grp_p
Material * ma
Definition: gpu_material.c:71
GPUPass * pass
Definition: gpu_material.c:53
struct GPUTexture * tex
LightCacheTexture grid_tx
LightCacheTexture cube_tx
struct bNodeTree * nodetree
float alpha_threshold
short base_flag
ListBase modifiers
short visibility_flag
ParticleSettings * part
struct World * world
ListBase aovs
short use_nodes