From 90312da85ae64f86742c3c041428d6536b7202b9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 3 Sep 2020 15:26:52 +0200 Subject: Fix T80332: principle volume shader not working for world in Eevee The handling of missing volume grids for the principled volume shader was incomplete, different inputs need different default values. --- source/blender/draw/engines/eevee/eevee_volumes.c | 49 +++++++++++++--------- source/blender/gpu/GPU_material.h | 10 ++++- source/blender/gpu/intern/gpu_node_graph.c | 13 ++++-- .../nodes/shader/nodes/node_shader_attribute.c | 6 +-- .../nodes/shader/nodes/node_shader_volume_info.c | 8 ++-- .../shader/nodes/node_shader_volume_principled.c | 6 +-- 6 files changed, 58 insertions(+), 34 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index a443ec61ceb..9fe83a341c5 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -63,10 +63,9 @@ static struct { GPUTexture *depth_src; - GPUTexture *dummy_density; - GPUTexture *dummy_color; + GPUTexture *dummy_zero; + GPUTexture *dummy_one; GPUTexture *dummy_flame; - GPUTexture *dummy_missing; GPUTexture *dummy_scatter; GPUTexture *dummy_transmit; @@ -150,14 +149,24 @@ static void eevee_create_shader_volumes(void) e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl, NULL); - const float density[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, density); + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + e_data.dummy_zero = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, zero); + + const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + e_data.dummy_one = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, one); const float flame = 0.0f; e_data.dummy_flame = DRW_texture_create_3d(1, 1, 1, GPU_R8, DRW_TEX_WRAP, &flame); +} - const float missing[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - e_data.dummy_missing = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, missing); +static GPUTexture *eevee_volume_default_texture(eGPUVolumeDefaultValue default_value) +{ + switch (default_value) { + case GPU_VOLUME_DEFAULT_0: + return e_data.dummy_zero; + case GPU_VOLUME_DEFAULT_1: + return e_data.dummy_one; + } } void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample) @@ -378,7 +387,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) /* Fix principle volumetric not working with world materials. */ ListBase gpu_grids = GPU_material_volume_grids(mat); LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, &gpu_grids) { - DRW_shgroup_uniform_texture(grp, gpu_grid->sampler_name, e_data.dummy_missing); + DRW_shgroup_uniform_texture( + grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value)); } DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]); @@ -466,7 +476,9 @@ static bool eevee_volume_object_grids_init(Object *ob, ListBase *gpu_grids, DRWS NULL; DRW_shgroup_uniform_texture( - grp, gpu_grid->sampler_name, (drw_grid) ? drw_grid->texture : e_data.dummy_missing); + grp, + gpu_grid->sampler_name, + (drw_grid) ? drw_grid->texture : eevee_volume_default_texture(gpu_grid->default_value)); if (drw_grid && multiple_transforms) { /* Specify per-volume transform matrix that is applied after the @@ -519,21 +531,20 @@ static bool eevee_volume_object_mesh_init(Scene *scene, LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) { if (STREQ(gpu_grid->name, "density")) { - DRW_shgroup_uniform_texture_ref(grp, - gpu_grid->sampler_name, - fds->tex_density ? &fds->tex_density : - &e_data.dummy_density); + DRW_shgroup_uniform_texture_ref( + grp, gpu_grid->sampler_name, fds->tex_density ? &fds->tex_density : &e_data.dummy_one); } else if (STREQ(gpu_grid->name, "color")) { DRW_shgroup_uniform_texture_ref( - grp, gpu_grid->sampler_name, fds->tex_color ? &fds->tex_color : &e_data.dummy_density); + grp, gpu_grid->sampler_name, fds->tex_color ? &fds->tex_color : &e_data.dummy_one); } else if (STREQ(gpu_grid->name, "flame") || STREQ(gpu_grid->name, "temperature")) { DRW_shgroup_uniform_texture_ref( grp, gpu_grid->sampler_name, fds->tex_flame ? &fds->tex_flame : &e_data.dummy_flame); } else { - DRW_shgroup_uniform_texture_ref(grp, gpu_grid->sampler_name, &e_data.dummy_density); + DRW_shgroup_uniform_texture( + grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value)); } } @@ -549,7 +560,8 @@ static bool eevee_volume_object_mesh_init(Scene *scene, } else { LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) { - DRW_shgroup_uniform_texture(grp, gpu_grid->sampler_name, e_data.dummy_density); + DRW_shgroup_uniform_texture( + grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value)); } } @@ -858,10 +870,9 @@ void EEVEE_volumes_free(void) DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter); DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit); - DRW_TEXTURE_FREE_SAFE(e_data.dummy_density); + DRW_TEXTURE_FREE_SAFE(e_data.dummy_zero); + DRW_TEXTURE_FREE_SAFE(e_data.dummy_one); DRW_TEXTURE_FREE_SAFE(e_data.dummy_flame); - DRW_TEXTURE_FREE_SAFE(e_data.dummy_color); - DRW_TEXTURE_FREE_SAFE(e_data.dummy_missing); DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh); DRW_SHADER_FREE_SAFE(e_data.scatter_sh); diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index b2352b3f3b0..b5631e1ed5d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -136,6 +136,11 @@ typedef enum eGPUMaterialStatus { GPU_MAT_SUCCESS, } eGPUMaterialStatus; +typedef enum eGPUVolumeDefaultValue { + GPU_VOLUME_DEFAULT_0, + GPU_VOLUME_DEFAULT_1, +} eGPUVolumeDefaultValue; + GPUNodeLink *GPU_constant(const float *num); GPUNodeLink *GPU_uniform(const float *num); GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name); @@ -149,7 +154,9 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, eGPUSamplerState sampler_state); GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser); GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *layer); -GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, const char *name); +GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, + const char *name, + eGPUVolumeDefaultValue default_value); GPUNodeLink *GPU_builtin(eGPUBuiltin builtin); bool GPU_link(GPUMaterial *mat, const char *name, ...); @@ -242,6 +249,7 @@ typedef struct GPUMaterialTexture { typedef struct GPUMaterialVolumeGrid { struct GPUMaterialVolumeGrid *next, *prev; char *name; + eGPUVolumeDefaultValue default_value; char sampler_name[32]; /* Name of sampler in GLSL. */ char transform_name[32]; /* Name of 4x4 matrix in GLSL. */ int users; diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index 17d97dc05e2..096320dc43e 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -333,13 +333,15 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, return tex; } -static GPUMaterialVolumeGrid *gpu_node_graph_add_volume_grid(GPUNodeGraph *graph, const char *name) +static GPUMaterialVolumeGrid *gpu_node_graph_add_volume_grid(GPUNodeGraph *graph, + const char *name, + eGPUVolumeDefaultValue default_value) { /* Find existing volume grid. */ int num_grids = 0; GPUMaterialVolumeGrid *grid = graph->volume_grids.first; for (; grid; grid = grid->next) { - if (STREQ(grid->name, name)) { + if (STREQ(grid->name, name) && grid->default_value == default_value) { break; } num_grids++; @@ -349,6 +351,7 @@ static GPUMaterialVolumeGrid *gpu_node_graph_add_volume_grid(GPUNodeGraph *graph if (grid == NULL) { grid = MEM_callocN(sizeof(*grid), __func__); grid->name = BLI_strdup(name); + grid->default_value = default_value; BLI_snprintf(grid->sampler_name, sizeof(grid->sampler_name), "vsamp%d", num_grids); BLI_snprintf(grid->transform_name, sizeof(grid->transform_name), "vtfm%d", num_grids); BLI_addtail(&graph->volume_grids, grid); @@ -442,14 +445,16 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro return link; } -GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, const char *name) +GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, + const char *name, + eGPUVolumeDefaultValue default_value) { /* NOTE: this could be optimized by automatically merging duplicate * lookups of the same attribute. */ GPUNodeGraph *graph = gpu_material_node_graph(mat); GPUNodeLink *link = gpu_node_link_create(); link->link_type = GPU_NODE_LINK_VOLUME_GRID; - link->volume_grid = gpu_node_graph_add_volume_grid(graph, name); + link->volume_grid = gpu_node_graph_add_volume_grid(graph, name, default_value); GPUNodeLink *transform_link = gpu_node_link_create(); transform_link->link_type = GPU_NODE_LINK_VOLUME_GRID_TRANSFORM; diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c index 6b5d46e250b..66d8a787001 100644 --- a/source/blender/nodes/shader/nodes/node_shader_attribute.c +++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c @@ -44,13 +44,13 @@ static int node_shader_gpu_attribute(GPUMaterial *mat, if (GPU_material_is_volume_shader(mat)) { if (out[0].hasoutput) { - out[0].link = GPU_volume_grid(mat, attr->name); + out[0].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); } if (out[1].hasoutput) { - out[1].link = GPU_volume_grid(mat, attr->name); + out[1].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); } if (out[2].hasoutput) { - out[2].link = GPU_volume_grid(mat, attr->name); + out[2].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); } return 1; diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_info.c b/source/blender/nodes/shader/nodes/node_shader_volume_info.c index 7ccc00f1af3..6cafc991e13 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_volume_info.c @@ -34,16 +34,16 @@ static int node_shader_gpu_volume_info(GPUMaterial *mat, GPUNodeStack *out) { if (out[0].hasoutput) { - out[0].link = GPU_volume_grid(mat, "color"); + out[0].link = GPU_volume_grid(mat, "color", GPU_VOLUME_DEFAULT_0); } if (out[1].hasoutput) { - out[1].link = GPU_volume_grid(mat, "density"); + out[1].link = GPU_volume_grid(mat, "density", GPU_VOLUME_DEFAULT_0); } if (out[2].hasoutput) { - out[2].link = GPU_volume_grid(mat, "flame"); + out[2].link = GPU_volume_grid(mat, "flame", GPU_VOLUME_DEFAULT_0); } if (out[3].hasoutput) { - out[3].link = GPU_volume_grid(mat, "temperature"); + out[3].link = GPU_volume_grid(mat, "temperature", GPU_VOLUME_DEFAULT_0); } return true; diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c index b581a4bd3a6..1a25aec5cb8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c @@ -78,13 +78,13 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat, } if (STREQ(sock->name, "Density Attribute")) { - density = GPU_volume_grid(mat, attribute_name); + density = GPU_volume_grid(mat, attribute_name, GPU_VOLUME_DEFAULT_1); } else if (STREQ(sock->name, "Color Attribute")) { - color = GPU_volume_grid(mat, attribute_name); + color = GPU_volume_grid(mat, attribute_name, GPU_VOLUME_DEFAULT_1); } else if (use_blackbody && STREQ(sock->name, "Temperature Attribute")) { - temperature = GPU_volume_grid(mat, attribute_name); + temperature = GPU_volume_grid(mat, attribute_name, GPU_VOLUME_DEFAULT_0); } } -- cgit v1.2.3