Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c77
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c151
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
5 files changed, 148 insertions, 89 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 2a866ee2b86..ecded9bb929 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -100,7 +100,7 @@ static void eevee_cache_init(void *vedata)
EEVEE_effects_cache_init(sldata, vedata);
EEVEE_lightprobes_cache_init(sldata, vedata);
EEVEE_lights_cache_init(sldata, vedata);
- EEVEE_materials_cache_init(vedata);
+ EEVEE_materials_cache_init(sldata, vedata);
EEVEE_motion_blur_cache_init(sldata, vedata);
EEVEE_occlusion_cache_init(sldata, vedata);
EEVEE_screen_raytrace_cache_init(sldata, vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index dd4dc590b10..9705ba7d645 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -85,8 +85,6 @@ static struct {
struct Gwn_VertFormat *format_probe_display_cube;
struct Gwn_VertFormat *format_probe_display_planar;
-
- int update_world;
} e_data = {NULL}; /* Engine data */
extern char datatoc_background_vert_glsl[];
@@ -304,6 +302,9 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL);
}
+ /* Only start doing probes if all materials have finished compiling. */
+ sldata->probes->all_materials_updated = true;
+
common_data->spec_toggle = true;
common_data->ssr_toggle = true;
common_data->sss_toggle = true;
@@ -334,7 +335,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
}
if (update_all) {
- e_data.update_world |= PROBE_UPDATE_ALL;
+ sldata->probes->update_world |= PROBE_UPDATE_ALL;
sldata->probes->updated_bounce = 0;
sldata->probes->grid_initialized = false;
}
@@ -395,34 +396,50 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
float *col = ts.colorBackground;
if (wo) {
col = &wo->horr;
- if (wo->update_flag != 0 || pinfo->prev_world != wo) {
- e_data.update_world |= PROBE_UPDATE_ALL;
- pinfo->updated_bounce = 0;
- pinfo->grid_initialized = false;
- }
- wo->update_flag = 0;
+ bool wo_sh_compiled = true;
if (wo->use_nodes && wo->nodetree) {
+ static float error_col[3] = {1.0f, 0.0f, 1.0f};
+ static float compile_col[3] = {0.5f, 0.5f, 0.5f};
struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo);
- grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
-
- if (grp) {
- DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- DRW_shgroup_call_add(grp, geom, NULL);
- }
- else {
- /* Shader failed : pink background */
- static float pink[3] = {1.0f, 0.0f, 1.0f};
- col = pink;
+ GPUMaterialStatus status = GPU_material_status(gpumat);
+
+ switch (status) {
+ case GPU_MAT_SUCCESS:
+ grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
+ DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
+ DRW_shgroup_call_add(grp, geom, NULL);
+ wo_sh_compiled = true;
+ break;
+ case GPU_MAT_QUEUED:
+ pinfo->all_materials_updated = false;
+ wo_sh_compiled = false;
+ /* TODO Bypass probe compilation. */
+ col = compile_col;
+ break;
+ case GPU_MAT_FAILED:
+ default:
+ wo_sh_compiled = true;
+ col = error_col;
+ break;
}
}
- pinfo->prev_world = wo;
+ if (wo->update_flag != 0 || pinfo->prev_world != wo || pinfo->prev_wo_sh_compiled != wo_sh_compiled) {
+ pinfo->update_world |= PROBE_UPDATE_ALL;
+ pinfo->updated_bounce = 0;
+ pinfo->grid_initialized = false;
+
+ pinfo->prev_wo_sh_compiled = wo_sh_compiled;
+ pinfo->prev_world = wo;
+ }
+ wo->update_flag = 0;
}
else if (pinfo->prev_world) {
+ pinfo->prev_wo_sh_compiled = false;
pinfo->prev_world = NULL;
- e_data.update_world |= PROBE_UPDATE_ALL;
+ pinfo->update_world |= PROBE_UPDATE_ALL;
pinfo->updated_bounce = 0;
pinfo->grid_initialized = false;
}
@@ -584,7 +601,7 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
}
}
- if (e_data.update_world) {
+ if (pinfo->update_world) {
ped->need_update = true;
ped->updated_cells = 0;
ped->updated_lvl = 0;
@@ -899,7 +916,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
}
/* Tag probes to refresh */
- e_data.update_world |= PROBE_UPDATE_CUBE;
+ pinfo->update_world |= PROBE_UPDATE_CUBE;
common_data->prb_num_render_cube = 0;
pinfo->cache_num_cube = pinfo->num_cube;
@@ -935,7 +952,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
common_data->prb_num_render_grid = 0;
pinfo->updated_bounce = 0;
pinfo->grid_initialized = false;
- e_data.update_world |= PROBE_UPDATE_GRID;
+ pinfo->update_world |= PROBE_UPDATE_GRID;
for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_PROBE); i++) {
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
@@ -1372,14 +1389,15 @@ static void lightprobe_cell_world_location_get(EEVEE_LightGrid *egrid, float loc
static void lightprobes_refresh_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+ EEVEE_LightProbesInfo *pinfo = sldata->probes;
EEVEE_PassList *psl = vedata->psl;
render_world_to_probe(sldata, psl);
- if (e_data.update_world & PROBE_UPDATE_CUBE) {
+ if (pinfo->update_world & PROBE_UPDATE_CUBE) {
glossy_filter_probe(sldata, vedata, psl, 0, 1.0);
common_data->prb_num_render_cube = 1;
}
- if (e_data.update_world & PROBE_UPDATE_GRID) {
+ if (pinfo->update_world & PROBE_UPDATE_GRID) {
diffuse_filter_probe(sldata, vedata, psl, 0, 0.0, 0.0, 0.0, 0.0, 1.0);
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
DRW_framebuffer_texture_detach(sldata->probe_pool);
@@ -1389,7 +1407,7 @@ static void lightprobes_refresh_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
common_data->prb_num_render_grid = 1;
}
- e_data.update_world = 0;
+ pinfo->update_world = 0;
DRW_viewport_request_redraw();
}
@@ -1664,6 +1682,7 @@ bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+ EEVEE_LightProbesInfo *pinfo = sldata->probes;
/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
common_data->spec_toggle = false;
@@ -1677,10 +1696,10 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ao_dist = 0.0f;
/* Render world in priority */
- if (e_data.update_world) {
+ if (pinfo->update_world) {
lightprobes_refresh_world(sldata, vedata);
}
- else if (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) {
+ else if (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false && pinfo->all_materials_updated) {
lightprobes_refresh_all_no_world(sldata, vedata);
}
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 314cbc5033a..a72bf85cbe9 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -856,7 +856,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
}
-void EEVEE_materials_cache_init(EEVEE_Data *vedata)
+void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
@@ -894,6 +894,7 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
DRW_shgroup_call_add(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
+ sldata->probes->all_materials_updated = false;
/* TODO Bypass probe compilation. */
col = compile_col;
break;
@@ -1042,60 +1043,29 @@ static void material_opaque(
}
if (use_gpumat) {
+ static float error_col[3] = {1.0f, 0.0f, 1.0f};
+ static float compile_col[3] = {0.5f, 0.5f, 0.5f};
+ static float half = 0.5f;
+
/* Shading */
*gpumat = EEVEE_material_mesh_get(scene, ma, vedata, false, false, use_refract,
use_sss, use_translucency, linfo->shadow_method);
- *shgrp = DRW_shgroup_material_create(*gpumat,
- (use_refract) ? psl->refract_pass :
- (use_sss) ? psl->sss_pass : psl->material_pass);
- if (*shgrp) {
- static int no_ssr = -1;
- static int first_ssr = 1;
- int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr;
- add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false);
-
- if (use_sss) {
- struct GPUTexture *sss_tex_profile = NULL;
- struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(*gpumat,
- stl->effects->sss_sample_count,
- &sss_tex_profile);
-
- if (sss_profile) {
- if (use_translucency) {
- DRW_shgroup_uniform_block(*shgrp, "sssProfile", sss_profile);
- DRW_shgroup_uniform_texture(*shgrp, "sssTexProfile", sss_tex_profile);
- }
-
- /* Limit of 8 bit stencil buffer. ID 255 is refraction. */
- if (e_data.sss_count < 254) {
- DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
- EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
- e_data.sss_count++;
- }
- else {
- /* TODO : display message. */
- printf("Error: Too many different Subsurface shader in the scene.\n");
- }
- }
- }
- }
- else {
- /* Shader failed : pink color */
- static float col[3] = {1.0f, 0.0f, 1.0f};
- static float half = 0.5f;
-
- color_p = col;
- metal_p = spec_p = rough_p = &half;
- }
+ GPUMaterialStatus status_mat_surface = GPU_material_status(*gpumat);
/* Alpha CLipped : Discard pixel from depth pass, then
* fail the depth test for shading. */
if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) {
*gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma,
- (ma->blend_method == MA_BM_HASHED), false);
+ (ma->blend_method == MA_BM_HASHED), false);
- if (use_refract) {
+ GPUMaterialStatus status_mat_depth = GPU_material_status(*gpumat_depth);
+ if (status_mat_depth != GPU_MAT_SUCCESS) {
+ /* Mixing both flags. If depth shader fails, show it to the user by not using
+ * the surface shader. */
+ status_mat_surface = status_mat_depth;
+ }
+ else if (use_refract) {
*shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
*shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
}
@@ -1117,6 +1087,59 @@ static void material_opaque(
}
}
}
+
+ switch (status_mat_surface) {
+ case GPU_MAT_SUCCESS:
+ {
+ static int no_ssr = -1;
+ static int first_ssr = 1;
+ int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr;
+
+ *shgrp = DRW_shgroup_material_create(*gpumat,
+ (use_refract) ? psl->refract_pass :
+ (use_sss) ? psl->sss_pass : psl->material_pass);
+ add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false);
+
+ if (use_sss) {
+ struct GPUTexture *sss_tex_profile = NULL;
+ struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(*gpumat,
+ stl->effects->sss_sample_count,
+ &sss_tex_profile);
+
+ if (sss_profile) {
+ if (use_translucency) {
+ DRW_shgroup_uniform_block(*shgrp, "sssProfile", sss_profile);
+ DRW_shgroup_uniform_texture(*shgrp, "sssTexProfile", sss_tex_profile);
+ }
+
+ /* Limit of 8 bit stencil buffer. ID 255 is refraction. */
+ if (e_data.sss_count < 254) {
+ DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
+ EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
+ e_data.sss_count++;
+ }
+ else {
+ /* TODO : display message. */
+ printf("Error: Too many different Subsurface shader in the scene.\n");
+ }
+ }
+ }
+ break;
+ }
+ case GPU_MAT_QUEUED:
+ {
+ sldata->probes->all_materials_updated = false;
+ /* TODO Bypass probe compilation. */
+ color_p = compile_col;
+ metal_p = spec_p = rough_p = &half;
+ break;
+ }
+ case GPU_MAT_FAILED:
+ default:
+ color_p = error_col;
+ metal_p = spec_p = rough_p = &half;
+ break;
+ }
}
/* Fallback to default shader */
@@ -1166,23 +1189,37 @@ static void material_transparent(
float *rough_p = &ma->gloss_mir;
if (ma->use_nodes && ma->nodetree) {
+ static float error_col[3] = {1.0f, 0.0f, 1.0f};
+ static float compile_col[3] = {0.5f, 0.5f, 0.5f};
+ static float half = 0.5f;
+
/* Shading */
*gpumat = EEVEE_material_mesh_get(scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract,
false, false, linfo->shadow_method);
- *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
- if (*shgrp) {
- static int ssr_id = -1; /* TODO transparent SSR */
- bool use_blend = (ma->blend_method & MA_BM_BLEND) != 0;
- add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend);
- }
- else {
- /* Shader failed : pink color */
- static float col[3] = {1.0f, 0.0f, 1.0f};
- static float half = 0.5f;
+ switch (GPU_material_status(*gpumat)) {
+ case GPU_MAT_SUCCESS:
+ {
+ static int ssr_id = -1; /* TODO transparent SSR */
+ bool use_blend = (ma->blend_method & MA_BM_BLEND) != 0;
- color_p = col;
- metal_p = spec_p = rough_p = &half;
+ *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
+ add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend);
+ break;
+ }
+ case GPU_MAT_QUEUED:
+ {
+ sldata->probes->all_materials_updated = false;
+ /* TODO Bypass probe compilation. */
+ color_p = compile_col;
+ metal_p = spec_p = rough_p = &half;
+ break;
+ }
+ case GPU_MAT_FAILED:
+ default:
+ color_p = error_col;
+ metal_p = spec_p = rough_p = &half;
+ break;
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8b035e97bf4..70e8d56d546 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -441,7 +441,10 @@ typedef struct EEVEE_LightProbesInfo {
int target_size;
int grid_initialized;
struct World *prev_world;
+ int update_world;
+ bool prev_wo_sh_compiled;
bool do_cube_update;
+ bool all_materials_updated;
/* For rendering probes */
float probemat[6][4][4];
int layer;
@@ -766,7 +769,7 @@ EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob);
/* eevee_materials.c */
struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl);
-void EEVEE_materials_cache_init(EEVEE_Data *vedata);
+void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob);
void EEVEE_materials_cache_finish(EEVEE_Data *vedata);
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index bc55624c7b7..b54640e64df 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -115,7 +115,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
EEVEE_effects_cache_init(sldata, vedata);
EEVEE_lightprobes_cache_init(sldata, vedata);
EEVEE_lights_cache_init(sldata, vedata);
- EEVEE_materials_cache_init(vedata);
+ EEVEE_materials_cache_init(sldata, vedata);
EEVEE_motion_blur_cache_init(sldata, vedata);
EEVEE_occlusion_cache_init(sldata, vedata);
EEVEE_screen_raytrace_cache_init(sldata, vedata);