Blender  V2.93
eevee_materials.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18 
23 #include "DRW_render.h"
24 
25 #include "BLI_alloca.h"
26 #include "BLI_ghash.h"
27 #include "BLI_listbase.h"
28 #include "BLI_math_bits.h"
29 #include "BLI_memblock.h"
30 #include "BLI_rand.h"
31 #include "BLI_string_utils.h"
32 
33 #include "BKE_paint.h"
34 #include "BKE_particle.h"
35 
36 #include "DNA_hair_types.h"
37 #include "DNA_modifier_types.h"
38 #include "DNA_view3d_types.h"
39 #include "DNA_world_types.h"
40 
41 #include "GPU_material.h"
42 
43 #include "DEG_depsgraph_query.h"
44 
45 #include "eevee_engine.h"
46 #include "eevee_lut.h"
47 #include "eevee_private.h"
48 
49 /* *********** STATIC *********** */
50 static struct {
51  /* 64*64 array texture containing all LUTs and other utilitarian arrays.
52  * Packing enables us to same precious textures slots. */
55 
56  float noise_offsets[3];
57 } e_data = {NULL}; /* Engine data */
58 
59 typedef struct EeveeMaterialCache {
64  /* Meh, Used by hair to ensure draw order when calling DRW_shgroup_create_sub.
65  * Pointers to ghash values. */
70 
71 /* *********** FUNCTIONS *********** */
72 
73 /* XXX TODO define all shared resources in a shared place without duplication */
75 {
76  return e_data.util_tex;
77 }
78 
83  GPUMaterial *gpumat,
84  EEVEE_ViewLayerData *sldata,
85  EEVEE_Data *vedata,
86  const int *ssr_id,
87  const float *refract_depth,
88  bool use_ssrefraction,
89  bool use_alpha_blend)
90 {
91  bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE);
92  bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY);
93  bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT);
94 
95  LightCache *lcache = vedata->stl->g_data->light_cache;
96  EEVEE_EffectsInfo *effects = vedata->stl->effects;
97  EEVEE_PrivateData *pd = vedata->stl->g_data;
98 
99  DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
100  DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
101  DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
102  DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
103  DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
104  DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
105  DRW_shgroup_uniform_block_ref(shgrp, "renderpass_block", &pd->renderpass_ubo);
106 
107  DRW_shgroup_uniform_int_copy(shgrp, "outputSssId", 1);
108  DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
109  if (use_diffuse || use_glossy || use_refract) {
110  DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool);
111  DRW_shgroup_uniform_texture_ref(shgrp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
112  DRW_shgroup_uniform_texture_ref(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
113  }
114  if ((use_diffuse || use_glossy) && !use_ssrefraction) {
115  DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &effects->gtao_horizons);
116  }
117  if (use_diffuse) {
118  DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex);
119  }
120  if (use_glossy || use_refract) {
121  DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &lcache->cube_tx.tex);
122  }
123  if (use_glossy) {
124  DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool);
125  DRW_shgroup_uniform_int_copy(shgrp, "outputSsrId", ssr_id ? *ssr_id : 0);
126  }
127  if (use_refract) {
129  shgrp, "refractionDepth", (refract_depth) ? *refract_depth : 0.0);
130  if (use_ssrefraction) {
132  shgrp, "refractColorBuffer", &vedata->txl->filtered_radiance);
133  }
134  }
135  if (use_alpha_blend) {
136  DRW_shgroup_uniform_texture_ref(shgrp, "inScattering", &effects->volume_scatter);
137  DRW_shgroup_uniform_texture_ref(shgrp, "inTransmittance", &effects->volume_transmit);
138  }
139 }
140 
141 static void eevee_init_noise_texture(void)
142 {
143  e_data.noise_tex = DRW_texture_create_2d(64, 64, GPU_RGBA16F, 0, (float *)blue_noise);
144 }
145 
146 #define RUNTIME_LUT_CREATION 0
147 
148 static void eevee_init_util_texture(void)
149 {
150  const int layers = 4 + 16;
151  float(*texels)[4] = MEM_mallocN(sizeof(float[4]) * 64 * 64 * layers, "utils texels");
152  float(*texels_layer)[4] = texels;
153 #if RUNTIME_LUT_CREATION
154  float *bsdf_ggx_lut = EEVEE_lut_update_ggx_brdf(64);
155  float(*btdf_ggx_lut)[64 * 64 * 2] = (float(*)[64 * 64 * 2]) EEVEE_lut_update_ggx_btdf(64, 16);
156 #else
157  const float *bsdf_ggx_lut = bsdf_split_sum_ggx;
158  const float(*btdf_ggx_lut)[64 * 64 * 2] = btdf_split_sum_ggx;
159 #endif
160 
161  /* Copy ltc_mat_ggx into 1st layer */
162  memcpy(texels_layer, ltc_mat_ggx, sizeof(float[4]) * 64 * 64);
163  texels_layer += 64 * 64;
164 
165  /* Copy bsdf_split_sum_ggx into 2nd layer red and green channels.
166  * Copy ltc_mag_ggx into 2nd layer blue and alpha channel. */
167  for (int i = 0; i < 64 * 64; i++) {
168  texels_layer[i][0] = bsdf_ggx_lut[i * 2 + 0];
169  texels_layer[i][1] = bsdf_ggx_lut[i * 2 + 1];
170  texels_layer[i][2] = ltc_mag_ggx[i * 2 + 0];
171  texels_layer[i][3] = ltc_mag_ggx[i * 2 + 1];
172  }
173  texels_layer += 64 * 64;
174 
175  /* Copy blue noise in 3rd layer */
176  for (int i = 0; i < 64 * 64; i++) {
177  texels_layer[i][0] = blue_noise[i][0];
178  texels_layer[i][1] = blue_noise[i][2];
179  texels_layer[i][2] = cosf(blue_noise[i][1] * 2.0f * M_PI);
180  texels_layer[i][3] = sinf(blue_noise[i][1] * 2.0f * M_PI);
181  }
182  texels_layer += 64 * 64;
183 
184  /* Copy ltc_disk_integral in 4th layer */
185  for (int i = 0; i < 64 * 64; i++) {
186  texels_layer[i][0] = ltc_disk_integral[i];
187  texels_layer[i][1] = 0.0; /* UNUSED */
188  texels_layer[i][2] = 0.0; /* UNUSED */
189  texels_layer[i][3] = 0.0; /* UNUSED */
190  }
191  texels_layer += 64 * 64;
192 
193  /* Copy Refraction GGX LUT in layer 5 - 21 */
194  for (int j = 0; j < 16; j++) {
195  for (int i = 0; i < 64 * 64; i++) {
196  texels_layer[i][0] = btdf_ggx_lut[j][i * 2 + 0];
197  texels_layer[i][1] = btdf_ggx_lut[j][i * 2 + 1];
198  texels_layer[i][2] = 0.0; /* UNUSED */
199  texels_layer[i][3] = 0.0; /* UNUSED */
200  }
201  texels_layer += 64 * 64;
202  }
203 
205  64, 64, layers, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
206 
207  MEM_freeN(texels);
208 #if RUNTIME_LUT_CREATION
209  MEM_freeN(bsdf_ggx_lut);
210  MEM_freeN(btdf_ggx_lut);
211 #endif
212 }
213 
214 void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3])
215 {
216  e_data.noise_offsets[0] = offsets[0];
217  e_data.noise_offsets[1] = offsets[1];
218  e_data.noise_offsets[2] = offsets[2];
219 
222 }
223 
225  EEVEE_Data *vedata,
226  EEVEE_StorageList *stl,
228 {
229  const DRWContextState *draw_ctx = DRW_context_state_get();
230  EEVEE_PrivateData *g_data = stl->g_data;
231 
232  if (!e_data.util_tex) {
234 
237  }
238 
239  if (!DRW_state_is_image_render() && ((stl->effects->enabled_effects & EFFECT_TAA) == 0)) {
240  sldata->common_data.alpha_hash_offset = 0.0f;
241  sldata->common_data.alpha_hash_scale = 1.0f;
242  }
243  else {
244  double r;
245  BLI_halton_1d(5, 0.0, stl->effects->taa_current_sample - 1, &r);
247  sldata->common_data.alpha_hash_scale = 0.01f;
248  }
249 
250  {
251  /* Update noise Frame-buffer. */
252  GPU_framebuffer_ensure_config(
253  &fbl->update_noise_fb,
254  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(e_data.util_tex, 2)});
255  }
256 
257  {
258  /* Create RenderPass UBO */
259  if (sldata->renderpass_ubo.combined == NULL) {
261  data = (EEVEE_RenderPassData){true, true, true, true, true, false, false, false, 0};
263  sizeof(data), &data, "renderpass_ubo.combined");
264 
265  data = (EEVEE_RenderPassData){true, false, false, false, false, true, false, false, 0};
267  sizeof(data), &data, "renderpass_ubo.diff_color");
268 
269  data = (EEVEE_RenderPassData){true, true, false, false, false, false, false, false, 0};
271  sizeof(data), &data, "renderpass_ubo.diff_light");
272 
273  data = (EEVEE_RenderPassData){false, false, true, false, false, false, false, false, 0};
275  sizeof(data), &data, "renderpass_ubo.spec_color");
276 
277  data = (EEVEE_RenderPassData){false, false, true, true, false, false, false, false, 0};
279  sizeof(data), &data, "renderpass_ubo.spec_light");
280 
281  data = (EEVEE_RenderPassData){false, false, false, false, true, false, false, false, 0};
283  sizeof(data), &data, "renderpass_ubo.emit");
284 
285  data = (EEVEE_RenderPassData){true, true, true, true, true, false, true, false, 0};
287  sizeof(data), &data, "renderpass_ubo.environment");
288  }
289 
290  /* Used combined pass by default. */
291  g_data->renderpass_ubo = sldata->renderpass_ubo.combined;
292 
293  {
294  g_data->num_aovs_used = 0;
295  if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) {
296  EEVEE_RenderPassData data = {true, true, true, true, true, false, false, true, 0};
297  if (stl->g_data->aov_hash == EEVEE_AOV_HASH_ALL) {
298  ViewLayer *view_layer = draw_ctx->view_layer;
299  int aov_index = 0;
300  LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
301  if ((aov->flag & AOV_CONFLICT) != 0) {
302  continue;
303  }
304  if (aov_index == MAX_AOVS) {
305  break;
306  }
307  data.renderPassAOVActive = EEVEE_renderpasses_aov_hash(aov);
308  if (sldata->renderpass_ubo.aovs[aov_index]) {
309  GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[aov_index], &data);
310  }
311  else {
312  sldata->renderpass_ubo.aovs[aov_index] = GPU_uniformbuf_create_ex(
313  sizeof(data), &data, "renderpass_ubo.aovs");
314  }
315  aov_index++;
316  }
317  g_data->num_aovs_used = aov_index;
318  }
319  else {
320  /* Rendering a single AOV in the 3d viewport */
321  data.renderPassAOVActive = stl->g_data->aov_hash;
322  if (sldata->renderpass_ubo.aovs[0]) {
324  }
325  else {
327  sizeof(data), &data, "renderpass_ubo.aovs");
328  }
329  g_data->num_aovs_used = 1;
330  }
331  }
332  /* Free AOV UBO's that are not in use. */
333  for (int aov_index = g_data->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
334  DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]);
335  }
336  }
337 
338  /* HACK: EEVEE_material_get can create a new context. This can only be
339  * done when there is no active framebuffer. We do this here otherwise
340  * `EEVEE_renderpasses_output_init` will fail. It cannot be done in
341  * `EEVEE_renderpasses_init` as the `e_data.vertcode` can be uninitialized.
342  */
344  struct Scene *scene = draw_ctx->scene;
345  struct World *wo = scene->world;
346  if (wo && wo->use_nodes) {
348  }
349  }
350  }
351 }
352 
354 {
355  EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
356  EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
357  const DRWContextState *draw_ctx = DRW_context_state_get();
358 
359  /* Create Material Ghash */
360  {
361  stl->g_data->material_hash = BLI_ghash_ptr_new("Eevee_material ghash");
362 
363  if (sldata->material_cache == NULL) {
365  }
366  else {
368  }
369  }
370 
371  {
373 
374  DRWShadingGroup *grp = NULL;
375  EEVEE_lookdev_cache_init(vedata, sldata, psl->background_ps, NULL, &grp);
376 
377  if (grp == NULL) {
378  Scene *scene = draw_ctx->scene;
380 
381  const int options = VAR_WORLD_BACKGROUND;
382  struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
383 
384  grp = DRW_shgroup_material_create(gpumat, psl->background_ps);
385  DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
386  }
387 
388  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
389  DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
390  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
391  DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
392  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
393  DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
394  DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
396  }
397 
398 #define EEVEE_PASS_CREATE(pass, state) \
399  do { \
400  DRW_PASS_CREATE(psl->pass##_ps, state); \
401  DRW_PASS_CREATE(psl->pass##_cull_ps, state | DRW_STATE_CULL_BACK); \
402  DRW_pass_link(psl->pass##_ps, psl->pass##_cull_ps); \
403  } while (0)
404 
405 #define EEVEE_CLIP_PASS_CREATE(pass, state) \
406  do { \
407  DRWState st = state | DRW_STATE_CLIP_PLANES; \
408  DRW_PASS_INSTANCE_CREATE(psl->pass##_clip_ps, psl->pass##_ps, st); \
409  DRW_PASS_INSTANCE_CREATE( \
410  psl->pass##_clip_cull_ps, psl->pass##_cull_ps, st | DRW_STATE_CULL_BACK); \
411  DRW_pass_link(psl->pass##_clip_ps, psl->pass##_clip_cull_ps); \
412  } while (0)
413 
414  {
418 
419  EEVEE_PASS_CREATE(depth, state_depth);
420  EEVEE_CLIP_PASS_CREATE(depth, state_depth);
421 
422  EEVEE_PASS_CREATE(depth_refract, state_depth);
423  EEVEE_CLIP_PASS_CREATE(depth_refract, state_depth);
424 
425  EEVEE_PASS_CREATE(material, state_shading);
426  EEVEE_PASS_CREATE(material_refract, state_shading);
427  EEVEE_PASS_CREATE(material_sss, state_shading | state_sss);
428  }
429  {
430  /* Renderpass accumulation. */
432  /* Create an instance of each of these passes and link them together. */
433  DRWPass *passes[] = {
434  psl->material_ps,
435  psl->material_cull_ps,
436  psl->material_sss_ps,
438  };
439  DRWPass *first = NULL, *last = NULL;
440  for (int i = 0; i < ARRAY_SIZE(passes); i++) {
441  DRWPass *pass = DRW_pass_create_instance("Renderpass Accumulation", passes[i], state);
442  if (first == NULL) {
443  first = last = pass;
444  }
445  else {
446  DRW_pass_link(last, pass);
447  last = pass;
448  }
449  }
450  psl->material_accum_ps = first;
451 
452  /* Same for background */
454  }
455  {
458  }
459  {
463  DRW_shgroup_uniform_texture(grp, "blueNoise", e_data.noise_tex);
464  DRW_shgroup_uniform_vec3(grp, "offsets", e_data.noise_offsets, 1);
466  }
467 }
468 
470  EEVEE_ViewLayerData *sldata,
471  Material *ma,
472  bool is_hair,
473  EeveeMaterialCache *emc)
474 {
475  EEVEE_PrivateData *pd = vedata->stl->g_data;
476  EEVEE_PassList *psl = vedata->psl;
477  const DRWContextState *draw_ctx = DRW_context_state_get();
478  Scene *scene = draw_ctx->scene;
479 
480  if (ma->blend_shadow != MA_BS_NONE) {
481  /* Shadow Pass */
482  const bool use_shadow_shader = ma->use_nodes && ma->nodetree &&
484  int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
485  SET_FLAG_FROM_TEST(mat_options, use_shadow_shader, VAR_MAT_HASH);
486  SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
487  GPUMaterial *gpumat = (use_shadow_shader) ?
488  EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
489  EEVEE_material_default_get(scene, ma, mat_options);
490 
491  /* Avoid possible confusion with depth pre-pass options. */
492  int option = KEY_SHADOW;
493  SET_FLAG_FROM_TEST(option, is_hair, KEY_HAIR);
494 
495  /* Search for the same shaders usage in the pass. */
496  struct GPUShader *sh = GPU_material_get_shader(gpumat);
497  void *cache_key = (char *)sh + option;
498  DRWShadingGroup *grp, **grp_p;
499 
500  if (BLI_ghash_ensure_p(pd->material_hash, cache_key, (void ***)&grp_p)) {
501  /* This GPUShader has already been used by another material.
502  * Add new shading group just after to avoid shader switching cost. */
503  grp = DRW_shgroup_create_sub(*grp_p);
504  }
505  else {
506  *grp_p = grp = DRW_shgroup_create(sh, psl->shadow_pass);
507  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, false);
508  }
509 
511 
512  emc->shadow_grp = grp;
513  emc->shadow_grp_p = grp_p;
514  }
515  else {
516  emc->shadow_grp = NULL;
517  emc->shadow_grp_p = NULL;
518  }
519 }
520 
522  EEVEE_ViewLayerData *sldata,
523  Material *ma,
524  const bool is_hair)
525 {
526  EEVEE_EffectsInfo *effects = vedata->stl->effects;
527  EEVEE_PrivateData *pd = vedata->stl->g_data;
528  EEVEE_PassList *psl = vedata->psl;
529  const DRWContextState *draw_ctx = DRW_context_state_get();
530  Scene *scene = draw_ctx->scene;
531 
532  const bool do_cull = !is_hair && (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
533  const bool use_gpumat = (ma->use_nodes && ma->nodetree);
534  const bool use_ssrefract = use_gpumat && ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
535  ((effects->enabled_effects & EFFECT_REFRACT) != 0);
536  const bool use_depth_shader = use_gpumat && ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED);
537 
538  /* HACK: Assume the struct will never be smaller than our variations.
539  * This allow us to only keep one ghash and avoid bigger keys comparisons/hashing. */
540  void *key = (char *)ma + is_hair;
541  /* Search for other material instances (sharing the same Material data-block). */
542  EeveeMaterialCache **emc_p, *emc;
543  if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) {
544  return **emc_p;
545  }
546 
547  *emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
548 
549  material_shadow(vedata, sldata, ma, is_hair, emc);
550 
551  {
552  /* Depth Pass */
553  int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
554  SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
555  SET_FLAG_FROM_TEST(mat_options, use_depth_shader, VAR_MAT_HASH);
556  SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
557  GPUMaterial *gpumat = (use_depth_shader) ?
558  EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
559  EEVEE_material_default_get(scene, ma, mat_options);
560 
561  int option = 0;
562  SET_FLAG_FROM_TEST(option, do_cull, KEY_CULL);
563  SET_FLAG_FROM_TEST(option, use_ssrefract, KEY_REFRACT);
564  DRWPass *depth_ps = (DRWPass *[]){
565  psl->depth_ps,
566  psl->depth_cull_ps,
567  psl->depth_refract_ps,
569  }[option];
570  /* Hair are rendered inside the non-cull pass but needs to have a separate cache key. */
571  SET_FLAG_FROM_TEST(option, is_hair, KEY_HAIR);
572 
573  /* Search for the same shaders usage in the pass. */
574  struct GPUShader *sh = GPU_material_get_shader(gpumat);
575  void *cache_key = (char *)sh + option;
576  DRWShadingGroup *grp, **grp_p;
577 
578  if (BLI_ghash_ensure_p(pd->material_hash, cache_key, (void ***)&grp_p)) {
579  /* This GPUShader has already been used by another material.
580  * Add new shading group just after to avoid shader switching cost. */
581  grp = DRW_shgroup_create_sub(*grp_p);
582  }
583  else {
584  *grp_p = grp = DRW_shgroup_create(sh, depth_ps);
585  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, false);
586  }
587 
589 
590  emc->depth_grp = grp;
591  emc->depth_grp_p = grp_p;
592  }
593  {
594  /* Shading Pass */
595  int mat_options = VAR_MAT_MESH;
596  SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
597  SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
598  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
599  const bool use_sss = GPU_material_flag_get(gpumat, GPU_MATFLAG_SSS);
600 
601  int ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_ssrefract) ? 1 : 0;
602  int option = (use_ssrefract ? 0 : (use_sss ? 1 : 2)) * 2 + do_cull;
603  DRWPass *shading_pass = (DRWPass *[]){
604  psl->material_refract_ps,
606  psl->material_sss_ps,
608  psl->material_ps,
609  psl->material_cull_ps,
610  }[option];
611  /* Hair are rendered inside the non-cull pass but needs to have a separate cache key */
612  option = option * 2 + is_hair;
613 
614  /* Search for the same shaders usage in the pass. */
615  /* HACK: Assume the struct will never be smaller than our variations.
616  * This allow us to only keep one ghash and avoid bigger keys comparisons/hashing. */
617  BLI_assert(option <= 16);
618  struct GPUShader *sh = GPU_material_get_shader(gpumat);
619  void *cache_key = (char *)sh + option;
620  DRWShadingGroup *grp, **grp_p;
621 
622  if (BLI_ghash_ensure_p(pd->material_hash, cache_key, (void ***)&grp_p)) {
623  /* This GPUShader has already been used by another material.
624  * Add new shading group just after to avoid shader switching cost. */
625  grp = DRW_shgroup_create_sub(*grp_p);
626 
627  /* Per material uniforms. */
628  if (use_ssrefract) {
629  DRW_shgroup_uniform_float_copy(grp, "refractionDepth", ma->refract_depth);
630  }
631  }
632  else {
633  *grp_p = grp = DRW_shgroup_create(sh, shading_pass);
635  grp, gpumat, sldata, vedata, &ssr_id, &ma->refract_depth, use_ssrefract, false);
636  }
638 
639  if (use_sss) {
640  EEVEE_subsurface_add_pass(sldata, vedata, ma, grp, gpumat);
641  }
642 
643  emc->shading_grp = grp;
644  emc->shading_grp_p = grp_p;
645  emc->shading_gpumat = gpumat;
646  }
647  return *emc;
648 }
649 
651  EEVEE_ViewLayerData *sldata,
652  Material *ma)
653 {
654  const DRWContextState *draw_ctx = DRW_context_state_get();
655  Scene *scene = draw_ctx->scene;
656  EEVEE_PassList *psl = vedata->psl;
657  EEVEE_EffectsInfo *effects = vedata->stl->effects;
658  EeveeMaterialCache emc = {0};
659 
660  const bool do_cull = (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
661  const bool use_gpumat = ma->use_nodes && ma->nodetree;
662  const bool use_ssrefract = use_gpumat && ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
663  ((effects->enabled_effects & EFFECT_REFRACT) != 0);
664  const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKFACE) != 0);
665 
666  DRWState cur_state;
670 
671  material_shadow(vedata, sldata, ma, false, &emc);
672 
673  if (use_prepass) {
674  /* Depth prepass */
675  int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
676  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
677  struct GPUShader *sh = GPU_material_get_shader(gpumat);
678 
680 
681  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, true);
683 
685  cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
686 
687  DRW_shgroup_state_disable(grp, all_state);
688  DRW_shgroup_state_enable(grp, cur_state);
689 
690  emc.depth_grp = grp;
691  }
692  {
693  /* Shading */
694  int ssr_id = -1; /* TODO transparent SSR */
695  int mat_options = VAR_MAT_MESH | VAR_MAT_BLEND;
696  SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
697  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
698 
700  psl->transparent_pass);
701 
703  grp, gpumat, sldata, vedata, &ssr_id, &ma->refract_depth, use_ssrefract, true);
705 
707  cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL;
708  cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
709 
710  /* Disable other blend modes and use the one we want. */
711  DRW_shgroup_state_disable(grp, all_state);
712  DRW_shgroup_state_enable(grp, cur_state);
713 
714  emc.shading_grp = grp;
715  emc.shading_gpumat = gpumat;
716  }
717  return emc;
718 }
719 
720 /* Return correct material or empty default material if slot is empty. */
722 {
723  if (holdout) {
725  }
726  Material *ma = BKE_object_material_get(ob, slot + 1);
727  if (ma == NULL) {
728  if (ob->type == OB_VOLUME) {
730  }
731  else {
733  }
734  }
735  return ma;
736 }
737 
739  EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, int slot, bool is_hair)
740 {
741  const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
742  EeveeMaterialCache matcache;
743  Material *ma = eevee_object_material_get(ob, slot, holdout);
744  switch (ma->blend_method) {
745  case MA_BM_BLEND:
746  if (!is_hair) {
747  matcache = material_transparent(vedata, sldata, ma);
748  break;
749  }
751  case MA_BM_SOLID:
752  case MA_BM_CLIP:
753  case MA_BM_HASHED:
754  default:
755  matcache = material_opaque(vedata, sldata, ma, is_hair);
756  break;
757  }
758  return matcache;
759 }
760 
762  EEVEE_ViewLayerData *sldata,
763  Object *ob,
764  ParticleSystem *psys,
765  ModifierData *md,
766  int matnr,
767  bool *cast_shadow)
768 {
769  EeveeMaterialCache matcache = eevee_material_cache_get(vedata, sldata, ob, matnr - 1, true);
770 
771  if (matcache.depth_grp) {
772  *matcache.depth_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.depth_grp);
774  }
775  if (matcache.shading_grp) {
776  *matcache.shading_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shading_grp);
778  }
779  if (matcache.shadow_grp) {
780  *matcache.shadow_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shadow_grp);
782  *cast_shadow = true;
783  }
784 
785  EEVEE_motion_blur_hair_cache_populate(sldata, vedata, ob, psys, md);
786 }
787 
788 #define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) \
789  do { \
790  if (oedata) { \
791  DRW_shgroup_call_with_callback(shgrp, geom, ob, oedata); \
792  } \
793  else { \
794  DRW_shgroup_call(shgrp, geom, ob); \
795  } \
796  } while (0)
797 
798 #define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata) \
799  do { \
800  if (shgrp) { \
801  ADD_SHGROUP_CALL(shgrp, ob, geom, oedata); \
802  } \
803  } while (0)
804 
805 #define MATCACHE_AS_ARRAY(matcache, member, materials_len, output_array) \
806  for (int i = 0; i < materials_len; i++) { \
807  output_array[i] = matcache[i].member; \
808  }
809 
811  EEVEE_ViewLayerData *sldata,
812  Object *ob,
813  bool *cast_shadow)
814 {
815  const DRWContextState *draw_ctx = DRW_context_state_get();
816  Scene *scene = draw_ctx->scene;
817 
818  bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
820 
821  /* First get materials for this mesh. */
822  if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
823  const int materials_len = DRW_cache_object_material_count_get(ob);
824 
825  EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len);
826  for (int i = 0; i < materials_len; i++) {
827  matcache[i] = eevee_material_cache_get(vedata, sldata, ob, i, false);
828  }
829 
830  /* Only support single volume material for now. */
831  /* XXX We rely on the previously compiled surface shader
832  * to know if the material has a "volume nodetree".
833  */
834  bool use_volume_material = (matcache[0].shading_gpumat &&
835  GPU_material_has_volume_output(matcache[0].shading_gpumat));
836  if ((ob->dt >= OB_SOLID) || DRW_state_is_scene_render()) {
837  if (use_sculpt_pbvh) {
838  struct DRWShadingGroup **shgrps_array = BLI_array_alloca(shgrps_array, materials_len);
839 
840  MATCACHE_AS_ARRAY(matcache, shading_grp, materials_len, shgrps_array);
841  DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
842 
843  MATCACHE_AS_ARRAY(matcache, depth_grp, materials_len, shgrps_array);
844  DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
845 
846  MATCACHE_AS_ARRAY(matcache, shadow_grp, materials_len, shgrps_array);
847  DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
848  }
849  else {
850  struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
851  MATCACHE_AS_ARRAY(matcache, shading_gpumat, materials_len, gpumat_array);
852  /* Get per-material split surface */
854  ob, gpumat_array, materials_len);
855 
856  if (mat_geom) {
857  for (int i = 0; i < materials_len; i++) {
858  if (mat_geom[i] == NULL) {
859  continue;
860  }
861 
862  /* Do not render surface if we are rendering a volume object
863  * and do not have a surface closure. */
864  if (use_volume_material &&
865  (gpumat_array[i] && !GPU_material_has_surface_output(gpumat_array[i]))) {
866  continue;
867  }
868 
869  /* XXX TODO rewrite this to include the dupli objects.
870  * This means we cannot exclude dupli objects from reflections!!! */
871  EEVEE_ObjectEngineData *oedata = NULL;
872  if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
873  oedata = EEVEE_object_data_ensure(ob);
874  oedata->ob = ob;
875  oedata->test_data = &sldata->probes->vis_data;
876  }
877 
878  ADD_SHGROUP_CALL(matcache[i].shading_grp, ob, mat_geom[i], oedata);
879  ADD_SHGROUP_CALL_SAFE(matcache[i].depth_grp, ob, mat_geom[i], oedata);
880  ADD_SHGROUP_CALL_SAFE(matcache[i].shadow_grp, ob, mat_geom[i], oedata);
881  *cast_shadow = *cast_shadow || (matcache[i].shadow_grp != NULL);
882  }
883  }
884  }
885 
886  /* Motion Blur Vectors. */
887  EEVEE_motion_blur_cache_populate(sldata, vedata, ob);
888  }
889 
890  /* Volumetrics */
891  if (use_volume_material) {
892  EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
893  }
894  }
895 }
896 
898  EEVEE_ViewLayerData *sldata,
899  Object *ob,
900  bool *cast_shadow)
901 {
902  const DRWContextState *draw_ctx = DRW_context_state_get();
903 
904  if (ob->type == OB_MESH) {
905  if (ob != draw_ctx->object_edit) {
906  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
907  if (md->type != eModifierType_ParticleSystem) {
908  continue;
909  }
910  ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
912  continue;
913  }
914  ParticleSettings *part = psys->part;
915  const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
916  if (draw_as != PART_DRAW_PATH) {
917  continue;
918  }
919  eevee_hair_cache_populate(vedata, sldata, ob, psys, md, part->omat, cast_shadow);
920  }
921  }
922  }
923 }
924 
926  EEVEE_ViewLayerData *sldata,
927  Object *ob,
928  bool *cast_shadow)
929 {
930  eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, HAIR_MATERIAL_NR, cast_shadow);
931 }
932 
934 {
935  EEVEE_PrivateData *pd = vedata->stl->g_data;
936  EEVEE_EffectsInfo *effects = vedata->stl->effects;
937 
939  pd->material_hash = NULL;
940 
942 }
943 
945 {
946  DRW_TEXTURE_FREE_SAFE(e_data.util_tex);
947  DRW_TEXTURE_FREE_SAFE(e_data.noise_tex);
948 }
949 
950 /* -------------------------------------------------------------------- */
955 {
956  EEVEE_PrivateData *pd = vedata->stl->g_data;
957 
958  /* For diffuse and glossy we calculate the final light + color buffer where we extract the
959  * light from by dividing by the color buffer. When one the light is requested we also tag
960  * the color buffer to do the extraction. */
963  }
966  }
967 }
968 
970 {
972 }
973 
975 {
976  EEVEE_FramebufferList *fbl = vedata->fbl;
978  EEVEE_TextureList *txl = vedata->txl;
979  EEVEE_StorageList *stl = vedata->stl;
980  EEVEE_EffectsInfo *effects = stl->effects;
981  EEVEE_PrivateData *pd = stl->g_data;
982 
983  /* Should be enough precision for many samples. */
984  const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
985 
986  /* Create FrameBuffer. */
987  GPU_framebuffer_ensure_config(&fbl->material_accum_fb,
988  {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_LEAVE});
989 
991  material_renderpass_init(&txl->env_accum, texture_format);
992  }
994  material_renderpass_init(&txl->emit_accum, texture_format);
995  }
997  material_renderpass_init(&txl->diff_color_accum, texture_format);
998  }
1000  material_renderpass_init(&txl->diff_light_accum, texture_format);
1001  }
1003  material_renderpass_init(&txl->spec_color_accum, texture_format);
1004  }
1006  for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
1007  material_renderpass_init(&txl->aov_surface_accum[aov_index], texture_format);
1008  }
1009  }
1011  material_renderpass_init(&txl->spec_light_accum, texture_format);
1012 
1013  if (effects->enabled_effects & EFFECT_SSR) {
1014  EEVEE_reflection_output_init(sldata, vedata, tot_samples);
1015  }
1016  }
1017 }
1018 
1020  EEVEE_FramebufferList *fbl,
1021  DRWPass *renderpass,
1022  DRWPass *renderpass2,
1023  EEVEE_PrivateData *pd,
1024  GPUTexture *output_tx,
1025  struct GPUUniformBuf *renderpass_option_ubo)
1026 {
1027  GPU_framebuffer_texture_attach(fbl->material_accum_fb, output_tx, 0, 0);
1029 
1030  if (effects->taa_current_sample == 1) {
1031  const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1032  GPU_framebuffer_clear_color(fbl->material_accum_fb, clear);
1033  }
1034 
1035  pd->renderpass_ubo = renderpass_option_ubo;
1036  DRW_draw_pass(renderpass);
1037  if (renderpass2) {
1038  DRW_draw_pass(renderpass2);
1039  }
1040 
1042 }
1043 
1045 {
1046  EEVEE_FramebufferList *fbl = vedata->fbl;
1047  EEVEE_PassList *psl = vedata->psl;
1048  EEVEE_PrivateData *pd = vedata->stl->g_data;
1049  EEVEE_EffectsInfo *effects = vedata->stl->effects;
1050  EEVEE_TextureList *txl = vedata->txl;
1051 
1052  if (fbl->material_accum_fb != NULL) {
1053  DRWPass *material_accum_ps = psl->material_accum_ps;
1054  DRWPass *background_accum_ps = psl->background_accum_ps;
1057  fbl,
1058  background_accum_ps,
1059  NULL,
1060  pd,
1061  txl->env_accum,
1062  sldata->renderpass_ubo.environment);
1063  }
1066  effects, fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit);
1067  }
1070  fbl,
1071  material_accum_ps,
1072  NULL,
1073  pd,
1074  txl->diff_color_accum,
1075  sldata->renderpass_ubo.diff_color);
1076  }
1079  fbl,
1080  material_accum_ps,
1081  NULL,
1082  pd,
1083  txl->diff_light_accum,
1084  sldata->renderpass_ubo.diff_light);
1085 
1086  if (effects->enabled_effects & EFFECT_SSS) {
1087  EEVEE_subsurface_output_accumulate(sldata, vedata);
1088  }
1089  }
1091  bool prev_ssr = sldata->common_data.ssr_toggle;
1092  if (prev_ssr) {
1093  /* We need to disable ssr here so output radiance is not directed to the ssr buffer. */
1094  sldata->common_data.ssr_toggle = false;
1095  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1096  }
1098  fbl,
1099  material_accum_ps,
1100  NULL,
1101  pd,
1102  txl->spec_color_accum,
1103  sldata->renderpass_ubo.spec_color);
1104  if (prev_ssr) {
1105  sldata->common_data.ssr_toggle = prev_ssr;
1106  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1107  }
1108  }
1111  fbl,
1112  material_accum_ps,
1113  NULL,
1114  pd,
1115  txl->spec_light_accum,
1116  sldata->renderpass_ubo.spec_light);
1117 
1118  if (effects->enabled_effects & EFFECT_SSR) {
1119  EEVEE_reflection_output_accumulate(sldata, vedata);
1120  }
1121  }
1123  for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
1125  fbl,
1126  material_accum_ps,
1127  background_accum_ps,
1128  pd,
1129  txl->aov_surface_accum[aov_index],
1130  sldata->renderpass_ubo.aovs[aov_index]);
1131  }
1132  }
1133  /* Free unused aov textures. */
1134  for (int aov_index = pd->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
1135  DRW_TEXTURE_FREE_SAFE(txl->aov_surface_accum[aov_index]);
1136  }
1137 
1138  /* Restore default. */
1139  pd->renderpass_ubo = sldata->renderpass_ubo.combined;
1141  }
1142 }
1143 
typedef float(TangentPoint)[2]
struct Material * BKE_material_default_surface(void)
Definition: material.c:1829
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
struct Material * BKE_material_default_holdout(void)
Definition: material.c:1824
struct Material * BKE_material_default_volume(void)
Definition: material.c:1834
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d)
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_FALLTHROUGH
#define BLI_INLINE
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
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:851
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define M_PI
Definition: BLI_math_base.h:38
#define BLI_memblock_create(elem_size)
Definition: BLI_memblock.h:44
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_memblock.c:133
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:104
Random number functions.
void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
Definition: rand.cc:299
unsigned int uint
Definition: BLI_sys_types.h:83
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define HAIR_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_BL_CULL_BACKFACE
@ MA_BL_SS_REFRACTION
@ MA_BL_HIDE_BACKFACE
@ MA_BM_CLIP
@ MA_BM_HASHED
@ MA_BM_SOLID
@ MA_BM_BLEND
@ MA_BS_HASHED
@ MA_BS_CLIP
@ MA_BS_NONE
@ eModifierType_ParticleSystem
@ OB_SOLID
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_MESH
@ OB_VOLUME
@ OB_CURVE
#define PART_DRAW_PATH
#define PART_DRAW_REND
@ DRW_TEX_WRAP
Definition: DRW_render.h:140
@ DRW_TEX_FILTER
Definition: DRW_render.h:139
#define DRW_PASS_INSTANCE_CREATE(pass, original, state)
Definition: DRW_render.h:594
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_CLIP_PLANES
Definition: DRW_render.h:354
@ DRW_STATE_STENCIL_ALWAYS
Definition: DRW_render.h:331
@ DRW_STATE_DEPTH_EQUAL
Definition: DRW_render.h:324
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_BLEND_ADD_FULL
Definition: DRW_render.h:338
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:323
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:328
@ DRW_STATE_BLEND_CUSTOM
Definition: DRW_render.h:348
@ DRW_STATE_WRITE_STENCIL
Definition: DRW_render.h:317
#define DRW_UBO_FREE_SAFE(ubo)
Definition: DRW_render.h:188
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
GPUBatch
Definition: GPU_batch.h:93
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:212
bool GPU_material_has_surface_output(GPUMaterial *mat)
Definition: gpu_material.c:626
@ GPU_MATFLAG_GLOSSY
Definition: GPU_material.h:110
@ GPU_MATFLAG_REFRACT
Definition: GPU_material.h:111
@ GPU_MATFLAG_SSS
Definition: GPU_material.h:112
@ GPU_MATFLAG_DIFFUSE
Definition: GPU_material.h:109
bool GPU_material_has_volume_output(GPUMaterial *mat)
Definition: gpu_material.c:631
bool GPU_material_flag_get(GPUMaterial *mat, eGPUMatFlag flag)
Definition: gpu_material.c:646
struct GPUShader GPUShader
Definition: GPU_shader.h:33
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_RGBA32F
Definition: GPU_texture.h:91
@ GPU_RGBA16F
Definition: GPU_texture.h:94
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)
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:969
GPUBatch * DRW_cache_fullscreen_quad_get(void)
Definition: draw_cache.c:358
int DRW_cache_object_material_count_get(struct Object *ob)
Definition: draw_cache.c:936
struct DRWShadingGroup * DRW_shgroup_hair_create_sub(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md, struct DRWShadingGroup *shgrp)
Definition: draw_hair.c:222
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
Definition: draw_manager.c:271
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:702
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_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
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_shgroup_uniform_block_ref(DRWShadingGroup *shgroup, const char *name, GPUUniformBuf **ubo)
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)
EEVEE_ObjectEngineData * EEVEE_object_data_ensure(Object *ob)
Definition: eevee_data.c:307
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:3507
const float btdf_split_sum_ggx[16][64 *64 *2]
Definition: eevee_lut.c:6585
const float bsdf_split_sum_ggx[64 *64 *2]
Definition: eevee_lut.c:5558
const float ltc_mag_ggx[64 *64 *2]
Definition: eevee_lut.c:2077
const float ltc_disk_integral[64 *64]
Definition: eevee_lut.c:2991
const float ltc_mat_ggx[64 *64 *4]
Definition: eevee_lut.c:26
float * EEVEE_lut_update_ggx_brdf(int lut_size)
Definition: eevee_lut_gen.c:38
float * EEVEE_lut_update_ggx_btdf(int lut_size, int lut_depth)
Definition: eevee_lut_gen.c:75
struct EeveeMaterialCache EeveeMaterialCache
float noise_offsets[3]
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3])
BLI_INLINE void material_shadow(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Material *ma, bool is_hair, EeveeMaterialCache *emc)
static void eevee_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, ParticleSystem *psys, ModifierData *md, int matnr, bool *cast_shadow)
#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
void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
#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 @194 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_bind_resources(DRWShadingGroup *shgrp, GPUMaterial *gpumat, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, const int *ssr_id, const float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
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)
#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_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob, ParticleSystem *psys, ModifierData *md)
#define MAX_AOVS
Definition: eevee_private.h:56
@ VAR_WORLD_BACKGROUND
@ VAR_MAT_BLEND
@ VAR_MAT_HASH
@ VAR_MAT_DEPTH
@ VAR_MAT_REFRACT
@ VAR_MAT_MESH
@ VAR_MAT_HAIR
@ KEY_HAIR
@ KEY_CULL
@ KEY_SHADOW
@ KEY_REFRACT
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)
@ 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)
int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov)
struct EEVEE_RenderPassData EEVEE_RenderPassData
#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)
#define sinf(x)
#define cosf(x)
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong state[N]
static void clear(Message *msg)
Definition: msgfmt.c:294
struct Scene * scene
Definition: DRW_render.h:745
struct ViewLayer * view_layer
Definition: DRW_render.h:746
struct View3D * v3d
Definition: DRW_render.h:742
struct Object * object_edit
Definition: DRW_render.h:769
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 GPUUniformBuf * spec_color
struct EEVEE_ViewLayerData::@202 renderpass_ubo
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:67
GPUPass * pass
Definition: gpu_material.c:79
struct GPUTexture * tex
LightCacheTexture grid_tx
LightCacheTexture cube_tx
struct bNodeTree * nodetree
short base_flag
ListBase modifiers
ParticleSettings * part
struct World * world
ListBase aovs
short use_nodes