Fix T81254: Incorrect calculation of EEVEE Transmittance Volumetrics

Regular rendering uses a custom blend mode, but render passes renders to
2 separate textures. This wasn't configured correctly inside the
fragment shaders. This patch adds a switch to configure the fragment
shader with the correct attachments.

Backport to Blender 2.83.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D9038
This commit is contained in:
Jeroen Bakker 2020-10-07 17:17:19 +02:00 committed by Jeroen Bakker
parent afab33e0b9
commit 7c373555fd
Notes: blender-bot 2023-02-14 03:46:57 +01:00
Referenced by issue #81254, EEVEE: Scattering pass is also outputted as Transmittance Volume Renderpass
Referenced by issue #77348, Blender LTS: Maintenance Task 2.83
6 changed files with 23 additions and 13 deletions

View File

@ -1119,7 +1119,7 @@ struct GPUShader *EEVEE_shaders_volumes_clear_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_scatter_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_scatter_with_lights_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_integration_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get(bool accum);
struct GPUShader *EEVEE_shaders_volumes_accum_sh_get(void);
struct GPUShader *EEVEE_shaders_ggx_lut_sh_get(void);
struct GPUShader *EEVEE_shaders_ggx_refraction_lut_sh_get(void);

View File

@ -137,7 +137,7 @@ static struct {
struct GPUShader *scatter_sh;
struct GPUShader *scatter_with_lights_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh;
struct GPUShader *volumetric_resolve_sh[2];
struct GPUShader *volumetric_accum_sh;
/* Shader strings */
@ -854,13 +854,16 @@ struct GPUShader *EEVEE_shaders_volumes_integration_sh_get()
return e_data.volumetric_integration_sh;
}
struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get()
struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get(bool accum)
{
if (e_data.volumetric_resolve_sh == NULL) {
e_data.volumetric_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_volumetric_resolve_frag_glsl, e_data.lib, SHADER_DEFINES);
const int index = accum ? 1 : 0;
if (e_data.volumetric_resolve_sh[index] == NULL) {
e_data.volumetric_resolve_sh[index] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_volumetric_resolve_frag_glsl,
e_data.lib,
accum ? "#define VOLUMETRICS_ACCUM\n" SHADER_DEFINES : SHADER_DEFINES);
}
return e_data.volumetric_resolve_sh;
return e_data.volumetric_resolve_sh[index];
}
struct GPUShader *EEVEE_shaders_volumes_accum_sh_get()
@ -1409,7 +1412,8 @@ void EEVEE_shaders_free(void)
DRW_SHADER_FREE_SAFE(e_data.scatter_sh);
DRW_SHADER_FREE_SAFE(e_data.scatter_with_lights_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh[0]);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh[1]);
DRW_SHADER_FREE_SAFE(e_data.volumetric_accum_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);

View File

@ -610,7 +610,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
DRW_PASS_CREATE(psl->volumetric_resolve_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_sh_get(), psl->volumetric_resolve_ps);
grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_sh_get(false), psl->volumetric_resolve_ps);
DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
@ -823,7 +823,7 @@ void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
DRW_PASS_CREATE(psl->volumetric_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
DRWShadingGroup *grp = NULL;
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_sh_get(), psl->volumetric_accum_ps);
grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_sh_get(true), psl->volumetric_accum_ps);
DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);

View File

@ -1,8 +1,8 @@
/* This shader is used to add default values to the volume accum textures.
* so it looks similar (transmittance = 1, scattering = 0) */
layout(location = 0, index = 0) out vec4 FragColor0;
layout(location = 0, index = 1) out vec4 FragColor1;
layout(location = 0) out vec4 FragColor0;
layout(location = 1) out vec4 FragColor1;
void main()
{

View File

@ -9,8 +9,13 @@
uniform sampler2D inSceneDepth;
/* Blend equation is : FragColor0 + FragColor1 * DstColor */
#ifdef VOLUMETRICS_ACCUM
layout(location = 0) out vec4 FragColor0;
layout(location = 1) out vec4 FragColor1;
#else
layout(location = 0, index = 0) out vec4 FragColor0;
layout(location = 0, index = 1) out vec4 FragColor1;
#endif
void main()
{

View File

@ -340,7 +340,8 @@ TEST_F(DrawTest, eevee_glsl_shaders_static)
EXPECT_NE(EEVEE_shaders_volumes_scatter_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_scatter_with_lights_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_integration_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_resolve_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_resolve_sh_get(false), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_resolve_sh_get(true), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_accum_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_studiolight_probe_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_studiolight_background_sh_get(), nullptr);