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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-06-02 17:58:07 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-06-02 17:58:07 +0300
commitb18c2a3c413b7741b2a854b7bd25721352be2589 (patch)
tree7dbdc9556a5eb4ff8f4d52afae01a9d3c47f7951 /source/blender/draw/engines/eevee/eevee_shaders.c
parentb82cb0ad3241ead3faee699847bc3e0065e304cd (diff)
EEVEE: Refactor of eevee_material.c
These are the modifications: -With DRW modification we reduce the number of passes we need to populate. -Rename passes for consistent naming. -Reduce complexity in code compilation -Cleanup how renderpass accumulation passes are setup, using pass instances. -Make sculpt mode compatible with shadows -Make hair passes compatible with SSS -Error shader and lookdev materials now use standalone materials. -Support default shader (world and material) using a default nodetree internally. -Change BLEND_CLIP to be emulated by gpu nodetree. Making less shader variations. -Use BLI_memblock for cache memory allocation. -Renderpasses are handled by switching a UBO ref bind. One major hack in this patch is the use of modified pointer as ghash keys. This rely on the assumption that the keys will never overlap because the number of options per key will never be bigger than the pointed struct. The use of one single nodetree to support default material is also a bit hacky since it won't support concurent usage of this nodetree. (see EEVEE_shader_default_surface_nodetree) Another change is that objects with shader errors now appear solid magenta instead of shaded magenta. This is only because of code reuse purpose but could be changed if really needed. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D7642
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_shaders.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c488
1 files changed, 483 insertions, 5 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 50b7c5c5f97..4d25f62a317 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -22,12 +22,20 @@
#include "DRW_render.h"
+#include "BKE_lib_id.h"
+#include "BKE_node.h"
+
+#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
#include "MEM_guardedalloc.h"
+#include "GPU_material.h"
#include "GPU_shader.h"
+#include "NOD_shader.h"
+
+#include "eevee_engine.h"
#include "eevee_private.h"
static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
@@ -61,6 +69,38 @@ static struct {
struct GPUShader *taa_resolve_sh;
struct GPUShader *taa_resolve_reproject_sh;
+ /* General purpose Shaders. */
+ struct GPUShader *default_background;
+ struct GPUShader *update_noise_sh;
+
+ /* Shader strings */
+ char *frag_shader_lib;
+ char *vert_shader_str;
+ char *vert_shadow_shader_str;
+ char *vert_background_shader_str;
+ char *vert_volume_shader_str;
+ char *geom_volume_shader_str;
+ char *volume_shader_lib;
+
+ /* LookDev Materials */
+ Material *glossy_mat;
+ Material *diffuse_mat;
+
+ Material *error_mat;
+
+ /* Default Material */
+ struct {
+ bNodeTree *ntree;
+ bNodeSocketValueRGBA *color_socket;
+ bNodeSocketValueFloat *metallic_socket;
+ bNodeSocketValueFloat *roughness_socket;
+ bNodeSocketValueFloat *specular_socket;
+ } surface;
+
+ struct {
+ bNodeTree *ntree;
+ bNodeSocketValueRGBA *color_socket;
+ } world;
} e_data = {NULL}; /* Engine data */
extern char datatoc_bsdf_common_lib_glsl[];
@@ -68,27 +108,42 @@ extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_background_vert_glsl[];
+extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_default_world_frag_glsl[];
-extern char datatoc_lightprobe_geom_glsl[];
-extern char datatoc_lightprobe_vert_glsl[];
+extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_cube_display_frag_glsl[];
extern char datatoc_lightprobe_cube_display_vert_glsl[];
extern char datatoc_lightprobe_filter_diffuse_frag_glsl[];
extern char datatoc_lightprobe_filter_glossy_frag_glsl[];
extern char datatoc_lightprobe_filter_visibility_frag_glsl[];
+extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_grid_display_frag_glsl[];
extern char datatoc_lightprobe_grid_display_vert_glsl[];
extern char datatoc_lightprobe_grid_fill_frag_glsl[];
+extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_lightprobe_planar_display_frag_glsl[];
extern char datatoc_lightprobe_planar_display_vert_glsl[];
extern char datatoc_lightprobe_planar_downsample_frag_glsl[];
extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
-extern char datatoc_irradiance_lib_glsl[];
-extern char datatoc_lightprobe_lib_glsl[];
+extern char datatoc_lightprobe_vert_glsl[];
+extern char datatoc_lights_lib_glsl[];
+extern char datatoc_lit_surface_frag_glsl[];
+extern char datatoc_lit_surface_vert_glsl[];
+extern char datatoc_ltc_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
+extern char datatoc_prepass_frag_glsl[];
+extern char datatoc_raytrace_lib_glsl[];
+extern char datatoc_shadow_vert_glsl[];
+extern char datatoc_ssr_lib_glsl[];
+extern char datatoc_update_noise_frag_glsl[];
+extern char datatoc_volumetric_frag_glsl[];
+extern char datatoc_volumetric_geom_glsl[];
+extern char datatoc_volumetric_lib_glsl[];
+extern char datatoc_volumetric_vert_glsl[];
/* Velocity Resolve */
extern char datatoc_effect_velocity_resolve_frag_glsl[];
@@ -150,6 +205,64 @@ void EEVEE_shaders_lightprobe_shaders_init(void)
NULL);
}
+void EEVEE_shaders_material_shaders_init(void)
+{
+ e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_bsdf_sampling_lib_glsl,
+ datatoc_ambient_occlusion_lib_glsl,
+ datatoc_raytrace_lib_glsl,
+ datatoc_ssr_lib_glsl,
+ datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
+ datatoc_irradiance_lib_glsl,
+ datatoc_lightprobe_lib_glsl,
+ datatoc_ltc_lib_glsl,
+ datatoc_lights_lib_glsl,
+ /* Add one for each Closure */
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
+ datatoc_volumetric_lib_glsl);
+
+ e_data.volume_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_ambient_occlusion_lib_glsl,
+ datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
+ datatoc_irradiance_lib_glsl,
+ datatoc_lightprobe_lib_glsl,
+ datatoc_ltc_lib_glsl,
+ datatoc_lights_lib_glsl,
+ datatoc_volumetric_lib_glsl,
+ datatoc_volumetric_frag_glsl);
+
+ e_data.vert_shader_str = BLI_string_joinN(
+ datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_lit_surface_vert_glsl);
+
+ e_data.vert_shadow_shader_str = BLI_string_joinN(
+ datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl);
+
+ e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_background_vert_glsl);
+
+ e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_volumetric_vert_glsl);
+
+ e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_volumetric_geom_glsl);
+}
+
GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
{
return e_data.probe_filter_glossy_sh;
@@ -292,6 +405,26 @@ GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void)
return e_data.velocity_resolve_sh;
}
+GPUShader *EEVEE_shaders_default_background_sh_get(void)
+{
+ if (e_data.default_background == NULL) {
+ e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
+ NULL,
+ datatoc_default_world_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
+ }
+ return e_data.default_background;
+}
+
+GPUShader *EEVEE_shaders_update_noise_sh_get(void)
+{
+ if (e_data.update_noise_sh == NULL) {
+ e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL);
+ }
+ return e_data.update_noise_sh;
+}
+
GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
{
GPUShader **sh;
@@ -316,8 +449,330 @@ GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
return *sh;
}
+Material *EEVEE_material_default_diffuse_get(void)
+{
+ if (!e_data.diffuse_mat) {
+ Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default diffuse");
+
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ ma->nodetree = ntree;
+ ma->use_nodes = true;
+
+ bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_DIFFUSE);
+ bNodeSocket *base_color = nodeFindSocket(bsdf, SOCK_IN, "Color");
+ copy_v3_fl(((bNodeSocketValueRGBA *)base_color->default_value)->value, 0.8f);
+
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+
+ nodeAddLink(ntree,
+ bsdf,
+ nodeFindSocket(bsdf, SOCK_OUT, "BSDF"),
+ output,
+ nodeFindSocket(output, SOCK_IN, "Surface"));
+
+ nodeSetActive(ntree, output);
+ e_data.diffuse_mat = ma;
+ }
+ return e_data.diffuse_mat;
+}
+
+Material *EEVEE_material_default_glossy_get(void)
+{
+ if (!e_data.glossy_mat) {
+ Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default metal");
+
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ ma->nodetree = ntree;
+ ma->use_nodes = true;
+
+ bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_GLOSSY);
+ bNodeSocket *base_color = nodeFindSocket(bsdf, SOCK_IN, "Color");
+ copy_v3_fl(((bNodeSocketValueRGBA *)base_color->default_value)->value, 1.0f);
+ bNodeSocket *roughness = nodeFindSocket(bsdf, SOCK_IN, "Roughness");
+ ((bNodeSocketValueFloat *)roughness->default_value)->value = 0.0f;
+
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+
+ nodeAddLink(ntree,
+ bsdf,
+ nodeFindSocket(bsdf, SOCK_OUT, "BSDF"),
+ output,
+ nodeFindSocket(output, SOCK_IN, "Surface"));
+
+ nodeSetActive(ntree, output);
+ e_data.glossy_mat = ma;
+ }
+ return e_data.glossy_mat;
+}
+
+Material *EEVEE_material_default_error_get(void)
+{
+ if (!e_data.error_mat) {
+ Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default metal");
+
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ ma->nodetree = ntree;
+ ma->use_nodes = true;
+
+ /* Use emission and output material to be compatible with both World and Material. */
+ bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_EMISSION);
+ bNodeSocket *color = nodeFindSocket(bsdf, SOCK_IN, "Color");
+ copy_v3_fl3(((bNodeSocketValueRGBA *)color->default_value)->value, 1.0f, 0.0f, 1.0f);
+
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+
+ nodeAddLink(ntree,
+ bsdf,
+ nodeFindSocket(bsdf, SOCK_OUT, "Emission"),
+ output,
+ nodeFindSocket(output, SOCK_IN, "Surface"));
+
+ nodeSetActive(ntree, output);
+ e_data.error_mat = ma;
+ }
+ return e_data.error_mat;
+}
+
+/* Configure a default nodetree with the given material. */
+struct bNodeTree *EEVEE_shader_default_surface_nodetree(Material *ma)
+{
+ /* WARNING: This function is not threadsafe. Which is not a problem for the moment. */
+ if (!e_data.surface.ntree) {
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_PRINCIPLED);
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+ bNodeSocket *bsdf_out = nodeFindSocket(bsdf, SOCK_OUT, "BSDF");
+ bNodeSocket *output_in = nodeFindSocket(output, SOCK_IN, "Surface");
+ nodeAddLink(ntree, bsdf, bsdf_out, output, output_in);
+ nodeSetActive(ntree, output);
+
+ e_data.surface.color_socket = nodeFindSocket(bsdf, SOCK_IN, "Base Color")->default_value;
+ e_data.surface.metallic_socket = nodeFindSocket(bsdf, SOCK_IN, "Metallic")->default_value;
+ e_data.surface.roughness_socket = nodeFindSocket(bsdf, SOCK_IN, "Roughness")->default_value;
+ e_data.surface.specular_socket = nodeFindSocket(bsdf, SOCK_IN, "Specular")->default_value;
+ e_data.surface.ntree = ntree;
+ }
+ /* Update */
+ copy_v3_fl3(e_data.surface.color_socket->value, ma->r, ma->g, ma->b);
+ e_data.surface.metallic_socket->value = ma->metallic;
+ e_data.surface.roughness_socket->value = ma->roughness;
+ e_data.surface.specular_socket->value = ma->spec;
+
+ return e_data.surface.ntree;
+}
+
+/* Configure a default nodetree with the given world. */
+struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo)
+{
+ /* WARNING: This function is not threadsafe. Which is not a problem for the moment. */
+ if (!e_data.world.ntree) {
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ bNode *bg = nodeAddStaticNode(NULL, ntree, SH_NODE_BACKGROUND);
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_WORLD);
+ bNodeSocket *bg_out = nodeFindSocket(bg, SOCK_OUT, "Background");
+ bNodeSocket *output_in = nodeFindSocket(output, SOCK_IN, "Surface");
+ nodeAddLink(ntree, bg, bg_out, output, output_in);
+ nodeSetActive(ntree, output);
+
+ e_data.world.color_socket = nodeFindSocket(bg, SOCK_IN, "Color")->default_value;
+ e_data.world.ntree = ntree;
+ }
+
+ copy_v3_fl3(e_data.world.color_socket->value, wo->horr, wo->horg, wo->horb);
+
+ return e_data.world.ntree;
+}
+
+static char *eevee_get_defines(int options)
+{
+ char *str = NULL;
+
+ DynStr *ds = BLI_dynstr_new();
+ BLI_dynstr_append(ds, SHADER_DEFINES);
+
+ if ((options & VAR_WORLD_BACKGROUND) != 0) {
+ BLI_dynstr_append(ds, "#define WORLD_BACKGROUND\n");
+ }
+ if ((options & VAR_MAT_VOLUME) != 0) {
+ BLI_dynstr_append(ds, "#define VOLUMETRICS\n");
+ }
+ if ((options & VAR_MAT_MESH) != 0) {
+ BLI_dynstr_append(ds, "#define MESH_SHADER\n");
+ }
+ if ((options & VAR_MAT_DEPTH) != 0) {
+ BLI_dynstr_append(ds, "#define DEPTH_SHADER\n");
+ }
+ if ((options & VAR_MAT_HAIR) != 0) {
+ BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
+ }
+ if ((options & (VAR_MAT_PROBE | VAR_WORLD_PROBE)) != 0) {
+ BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n");
+ }
+ if ((options & VAR_MAT_HASH) != 0) {
+ BLI_dynstr_append(ds, "#define USE_ALPHA_HASH\n");
+ }
+ if ((options & VAR_MAT_BLEND) != 0) {
+ BLI_dynstr_append(ds, "#define USE_ALPHA_BLEND\n");
+ }
+ if ((options & VAR_MAT_REFRACT) != 0) {
+ BLI_dynstr_append(ds, "#define USE_REFRACTION\n");
+ }
+ if ((options & VAR_MAT_LOOKDEV) != 0) {
+ BLI_dynstr_append(ds, "#define LOOKDEV\n");
+ }
+ if ((options & VAR_MAT_HOLDOUT) != 0) {
+ BLI_dynstr_append(ds, "#define HOLDOUT\n");
+ }
+
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ return str;
+}
+
+static char *eevee_get_vert(int options)
+{
+ char *str = NULL;
+
+ if ((options & VAR_MAT_VOLUME) != 0) {
+ str = BLI_strdup(e_data.vert_volume_shader_str);
+ }
+ else if ((options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0) {
+ str = BLI_strdup(e_data.vert_background_shader_str);
+ }
+ else {
+ str = BLI_strdup(e_data.vert_shader_str);
+ }
+
+ return str;
+}
+
+static char *eevee_get_geom(int options)
+{
+ char *str = NULL;
+
+ if ((options & VAR_MAT_VOLUME) != 0) {
+ str = BLI_strdup(e_data.geom_volume_shader_str);
+ }
+
+ return str;
+}
+
+static char *eevee_get_frag(int options)
+{
+ char *str = NULL;
+
+ if ((options & VAR_MAT_VOLUME) != 0) {
+ str = BLI_strdup(e_data.volume_shader_lib);
+ }
+ else if ((options & VAR_MAT_DEPTH) != 0) {
+ str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl);
+ }
+ else {
+ str = BLI_strdup(e_data.frag_shader_lib);
+ }
+
+ return str;
+}
+
+static struct GPUMaterial *eevee_material_get_ex(
+ struct Scene *scene, Material *ma, World *wo, int options, bool deferred)
+{
+ BLI_assert(ma || wo);
+ const bool is_volume = (options & VAR_MAT_VOLUME) != 0;
+ const bool is_default = (options & VAR_DEFAULT) != 0;
+ const void *engine = &DRW_engine_viewport_eevee_type;
+
+ GPUMaterial *mat = NULL;
+
+ if (ma) {
+ mat = DRW_shader_find_from_material(ma, engine, options, deferred);
+ }
+ else {
+ mat = DRW_shader_find_from_world(wo, engine, options, deferred);
+ }
+
+ if (mat) {
+ return mat;
+ }
+
+ char *defines = eevee_get_defines(options);
+ char *vert = eevee_get_vert(options);
+ char *geom = eevee_get_geom(options);
+ char *frag = eevee_get_frag(options);
+
+ if (ma) {
+ bNodeTree *ntree = !is_default ? ma->nodetree : EEVEE_shader_default_surface_nodetree(ma);
+ mat = DRW_shader_create_from_material(
+ scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
+ }
+ else {
+ bNodeTree *ntree = !is_default ? wo->nodetree : EEVEE_shader_default_world_nodetree(wo);
+ mat = DRW_shader_create_from_world(
+ scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
+ }
+
+ MEM_SAFE_FREE(defines);
+ MEM_SAFE_FREE(vert);
+ MEM_SAFE_FREE(geom);
+ MEM_SAFE_FREE(frag);
+
+ return mat;
+}
+
+/* Note: Compilation is not deferred. */
+struct GPUMaterial *EEVEE_material_default_get(struct Scene *scene, Material *ma, int options)
+{
+ Material *def_ma = (ma && (options & VAR_MAT_VOLUME)) ? BKE_material_default_volume() :
+ BKE_material_default_surface();
+ BLI_assert(def_ma->use_nodes && def_ma->nodetree);
+
+ return eevee_material_get_ex(scene, def_ma, NULL, options, false);
+}
+
+struct GPUMaterial *EEVEE_material_get(
+ EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options)
+{
+ if ((ma && (!ma->use_nodes || !ma->nodetree)) || (wo && (!wo->use_nodes || !wo->nodetree))) {
+ options |= VAR_DEFAULT;
+ }
+
+ /* Meh, implicit option. World probe cannot be deferred because they need
+ * to be rendered immediatly. */
+ const bool deferred = (options & VAR_WORLD_PROBE) == 0;
+
+ GPUMaterial *mat = eevee_material_get_ex(scene, ma, wo, options, deferred);
+
+ int status = GPU_material_status(mat);
+ switch (status) {
+ case GPU_MAT_SUCCESS:
+ break;
+ case GPU_MAT_QUEUED:
+ vedata->stl->g_data->queued_shaders_count++;
+ mat = EEVEE_material_default_get(scene, ma, options);
+ break;
+ case GPU_MAT_FAILED:
+ default:
+ ma = EEVEE_material_default_error_get();
+ mat = eevee_material_get_ex(scene, ma, NULL, options, false);
+ break;
+ }
+ /* Returned material should be ready to be drawn. */
+ BLI_assert(GPU_material_status(mat) == GPU_MAT_SUCCESS);
+ return mat;
+}
+
void EEVEE_shaders_free(void)
{
+ MEM_SAFE_FREE(e_data.frag_shader_lib);
+ MEM_SAFE_FREE(e_data.vert_shader_str);
+ MEM_SAFE_FREE(e_data.vert_shadow_shader_str);
+ MEM_SAFE_FREE(e_data.vert_background_shader_str);
+ MEM_SAFE_FREE(e_data.vert_volume_shader_str);
+ MEM_SAFE_FREE(e_data.geom_volume_shader_str);
+ MEM_SAFE_FREE(e_data.volume_shader_lib);
+ DRW_SHADER_FREE_SAFE(e_data.default_background);
+ DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
@@ -332,4 +787,27 @@ void EEVEE_shaders_free(void)
DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh);
+
+ if (e_data.glossy_mat) {
+ BKE_id_free(NULL, e_data.glossy_mat);
+ e_data.glossy_mat = NULL;
+ }
+ if (e_data.diffuse_mat) {
+ BKE_id_free(NULL, e_data.diffuse_mat);
+ e_data.diffuse_mat = NULL;
+ }
+ if (e_data.error_mat) {
+ BKE_id_free(NULL, e_data.error_mat);
+ e_data.error_mat = NULL;
+ }
+ if (e_data.surface.ntree) {
+ ntreeFreeEmbeddedTree(e_data.surface.ntree);
+ MEM_freeN(e_data.surface.ntree);
+ e_data.surface.ntree = NULL;
+ }
+ if (e_data.world.ntree) {
+ ntreeFreeEmbeddedTree(e_data.world.ntree);
+ MEM_freeN(e_data.world.ntree);
+ e_data.world.ntree = NULL;
+ }
}