EEVEE: Fix volumetric resolve in large scenes.
On NVIDIA volumetric resolve failed for large production scenes. The result would remove most color from the final render. The cause seems to be a faulty driver. This change ported the fragment shader to a compute shader which would select a different compiler branch and didn't show the error.
This commit is contained in:
parent
b404548972
commit
34051fcc12
Notes:
blender-bot
2023-02-14 08:06:33 +01:00
Referenced by commit bf05b998b6
, Revert "EEVEE: Fix volumetric resolve in large scenes."
|
@ -388,6 +388,7 @@ set(GLSL_SRC
|
|||
engines/eevee/shaders/volumetric_frag.glsl
|
||||
engines/eevee/shaders/volumetric_geom.glsl
|
||||
engines/eevee/shaders/volumetric_vert.glsl
|
||||
engines/eevee/shaders/volumetric_resolve_comp.glsl
|
||||
engines/eevee/shaders/volumetric_resolve_frag.glsl
|
||||
engines/eevee/shaders/volumetric_scatter_frag.glsl
|
||||
engines/eevee/shaders/volumetric_integration_frag.glsl
|
||||
|
|
|
@ -1261,6 +1261,7 @@ 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(bool accum);
|
||||
struct GPUShader *EEVEE_shaders_volumes_resolve_comp_sh_get(bool float_target);
|
||||
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);
|
||||
|
|
|
@ -133,6 +133,7 @@ static struct {
|
|||
struct GPUShader *scatter_with_lights_sh;
|
||||
struct GPUShader *volumetric_integration_sh;
|
||||
struct GPUShader *volumetric_resolve_sh[2];
|
||||
struct GPUShader *volumetric_resolve_comp_sh[2];
|
||||
struct GPUShader *volumetric_accum_sh;
|
||||
|
||||
/* Shader strings */
|
||||
|
@ -261,6 +262,7 @@ extern char datatoc_volumetric_frag_glsl[];
|
|||
extern char datatoc_volumetric_geom_glsl[];
|
||||
extern char datatoc_volumetric_integration_frag_glsl[];
|
||||
extern char datatoc_volumetric_lib_glsl[];
|
||||
extern char datatoc_volumetric_resolve_comp_glsl[];
|
||||
extern char datatoc_volumetric_resolve_frag_glsl[];
|
||||
extern char datatoc_volumetric_scatter_frag_glsl[];
|
||||
extern char datatoc_volumetric_vert_glsl[];
|
||||
|
@ -903,6 +905,20 @@ struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get(bool accum)
|
|||
return e_data.volumetric_resolve_sh[index];
|
||||
}
|
||||
|
||||
struct GPUShader *EEVEE_shaders_volumes_resolve_comp_sh_get(bool float_target)
|
||||
{
|
||||
const int index = (float_target ? 1 : 0);
|
||||
if (e_data.volumetric_resolve_comp_sh[index] == NULL) {
|
||||
e_data.volumetric_resolve_comp_sh[index] = DRW_shader_create_compute_with_shaderlib(
|
||||
datatoc_volumetric_resolve_comp_glsl,
|
||||
e_data.lib,
|
||||
float_target ? "#define TARGET_IMG_FLOAT\n" SHADER_DEFINES : SHADER_DEFINES,
|
||||
__func__);
|
||||
}
|
||||
|
||||
return e_data.volumetric_resolve_comp_sh[index];
|
||||
}
|
||||
|
||||
struct GPUShader *EEVEE_shaders_volumes_accum_sh_get()
|
||||
{
|
||||
if (e_data.volumetric_accum_sh == NULL) {
|
||||
|
|
|
@ -396,18 +396,37 @@ 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(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);
|
||||
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
|
||||
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
|
||||
if (GPU_compute_shader_support() && GPU_shader_image_load_store_support()) {
|
||||
const bool use_float_target = DRW_state_is_image_render();
|
||||
grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_comp_sh_get(use_float_target),
|
||||
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);
|
||||
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
|
||||
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
|
||||
DRW_shgroup_uniform_image_ref(grp, "target_img", &txl->color);
|
||||
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
const float *size = DRW_viewport_size_get();
|
||||
DRW_shgroup_call_compute(grp, size[0], size[1], 1);
|
||||
}
|
||||
else {
|
||||
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);
|
||||
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
|
||||
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
|
||||
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,11 +565,16 @@ void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
|
|||
}
|
||||
|
||||
/* Apply for opaque geometry. */
|
||||
GPU_framebuffer_bind(fbl->main_color_fb);
|
||||
DRW_draw_pass(psl->volumetric_resolve_ps);
|
||||
if (GPU_compute_shader_support() && GPU_shader_image_load_store_support()) {
|
||||
DRW_draw_pass(psl->volumetric_resolve_ps);
|
||||
}
|
||||
else {
|
||||
GPU_framebuffer_bind(fbl->main_color_fb);
|
||||
DRW_draw_pass(psl->volumetric_resolve_ps);
|
||||
|
||||
/* Restore. */
|
||||
GPU_framebuffer_bind(fbl->main_fb);
|
||||
/* Restore. */
|
||||
GPU_framebuffer_bind(fbl->main_fb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
|
||||
|
||||
/* Based on Frosbite Unified Volumetric.
|
||||
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
|
||||
|
||||
/* Step 4 : Apply final integration on top of the scene color. */
|
||||
|
||||
uniform sampler2D inSceneDepth;
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1) in;
|
||||
|
||||
#ifdef TARGET_IMG_FLOAT
|
||||
layout(binding = 0, rgba32f) uniform image2D target_img;
|
||||
#else
|
||||
layout(binding = 0, rgba16f) uniform image2D target_img;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 co = ivec2(gl_GlobalInvocationID.xy);
|
||||
vec2 uvs = co / vec2(textureSize(inSceneDepth, 0));
|
||||
float scene_depth = texture(inSceneDepth, uvs).r;
|
||||
|
||||
vec3 transmittance, scattering;
|
||||
volumetric_resolve(uvs, scene_depth, transmittance, scattering);
|
||||
|
||||
/* Approximate volume alpha by using a monochromatic transmittance
|
||||
* and adding it to the scene alpha. */
|
||||
float alpha = dot(transmittance, vec3(1.0 / 3.0));
|
||||
|
||||
vec4 color0 = vec4(scattering, 1.0 - alpha);
|
||||
vec4 color1 = vec4(transmittance, alpha);
|
||||
|
||||
vec4 color_in = imageLoad(target_img, co);
|
||||
vec4 color_out = color0 + color1 * color_in;
|
||||
imageStore(target_img, co, color_out);
|
||||
}
|
|
@ -207,6 +207,10 @@ struct GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
|
|||
const char *lib,
|
||||
const char *defines,
|
||||
const char *name);
|
||||
struct GPUShader *DRW_shader_create_compute_with_shaderlib(const char *comp,
|
||||
const DRWShaderLibrary *lib,
|
||||
const char *defines,
|
||||
const char *name);
|
||||
struct GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
|
||||
const char *geom,
|
||||
const char *frag,
|
||||
|
|
|
@ -297,6 +297,18 @@ GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
|
|||
return sh;
|
||||
}
|
||||
|
||||
GPUShader *DRW_shader_create_compute_with_shaderlib(const char *comp,
|
||||
const DRWShaderLibrary *lib,
|
||||
const char *defines,
|
||||
const char *name)
|
||||
{
|
||||
char *comp_with_lib = DRW_shader_library_create_shader_string(lib, comp);
|
||||
GPUShader *sh = GPU_shader_create_compute(comp_with_lib, NULL, defines, name);
|
||||
MEM_SAFE_FREE(comp_with_lib);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
|
||||
const char *geom,
|
||||
const char *frag,
|
||||
|
|
|
@ -360,6 +360,8 @@ static void test_eevee_glsl_shaders_static()
|
|||
EXPECT_NE(EEVEE_shaders_volumes_integration_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_resolve_comp_sh_get(false), nullptr);
|
||||
EXPECT_NE(EEVEE_shaders_volumes_resolve_comp_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);
|
||||
|
|
Loading…
Reference in New Issue