EEVEE Next: Ambient Occlusion #108398
|
@ -61,6 +61,10 @@ void AmbientOcclusion::init()
|
|||
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
|
||||
horizons_tx_.ensure_2d(GPU_RGBA8, inst_.film.render_extent_get(), usage);
|
||||
|
||||
/* Compute pixel size. Size is multiplied by 2 because it is applied in NDC [-1..1] range. */
|
||||
rt_data_.pixel_size = float2(2.0f) / float2(inst_.film.render_extent_get());
|
||||
pragma37 marked this conversation as resolved
Outdated
|
||||
rt_data_.push_update();
|
||||
}
|
||||
|
||||
void AmbientOcclusion::sync()
|
||||
|
|
|
@ -47,6 +47,14 @@ class AmbientOcclusion {
|
|||
void sync();
|
||||
|
||||
void render(View &view);
|
||||
|
||||
template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
|
||||
{
|
||||
inst_.hiz_buffer.bind_resources(pass);
|
||||
pass->bind_ubo(AO_BUF_SLOT, &data_);
|
||||
pass->bind_ubo(RAYTRACE_BUF_SLOT, &rt_data_);
|
||||
pass->bind_texture(AO_HORIZONS_TEX_SLOT, data_.enabled ? &horizons_tx_ : &dummy_horizons_tx_);
|
||||
}
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -150,6 +150,7 @@ void ForwardPipeline::sync()
|
|||
inst_.shadows.bind_resources(&opaque_ps_);
|
||||
inst_.sampling.bind_resources(&opaque_ps_);
|
||||
inst_.cryptomatte.bind_resources(&opaque_ps_);
|
||||
inst_.ao.bind_resources(&opaque_ps_);
|
||||
}
|
||||
|
||||
opaque_single_sided_ps_ = &opaque_ps_.sub("SingleSided");
|
||||
|
@ -175,6 +176,7 @@ void ForwardPipeline::sync()
|
|||
inst_.lights.bind_resources(&sub);
|
||||
inst_.shadows.bind_resources(&sub);
|
||||
inst_.sampling.bind_resources(&sub);
|
||||
inst_.ao.bind_resources(&sub);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,6 +330,7 @@ void DeferredLayer::begin_sync()
|
|||
|
||||
inst_.sampling.bind_resources(&gbuffer_ps_);
|
||||
inst_.cryptomatte.bind_resources(&gbuffer_ps_);
|
||||
inst_.ao.bind_resources(&gbuffer_ps_);
|
||||
}
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM | DRW_STATE_DEPTH_EQUAL |
|
||||
|
@ -370,6 +373,7 @@ void DeferredLayer::end_sync()
|
|||
inst_.shadows.bind_resources(&eval_light_ps_);
|
||||
inst_.sampling.bind_resources(&eval_light_ps_);
|
||||
inst_.hiz_buffer.bind_resources(&eval_light_ps_);
|
||||
inst_.ao.bind_resources(&eval_light_ps_);
|
||||
|
||||
eval_light_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
|
||||
eval_light_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
|
|
@ -254,6 +254,13 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
|||
info.define("MAT_RENDER_PASS_SUPPORT");
|
||||
}
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_AO) &&
|
||||
ELEM(pipeline_type, MAT_PIPE_FORWARD, MAT_PIPE_DEFERRED) &&
|
||||
ELEM(geometry_type, MAT_GEOM_MESH, MAT_GEOM_CURVES))
|
||||
{
|
||||
info.define("MAT_AO");
|
||||
}
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
|
||||
info.define("MAT_TRANSPARENT");
|
||||
/* Transparent material do not have any velocity specific pipeline. */
|
||||
|
|
|
@ -24,21 +24,23 @@ float cone_cosine(float r)
|
|||
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
|
||||
*/
|
||||
|
||||
#if defined(MESH_SHADER)
|
||||
/* TODO(Miguel Pozo) */
|
||||
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
Prefer a function that returns an empty occlusion data. Prefer a function that returns an empty occlusion data.
|
||||
#if defined(MAT_GEOM_MESH)
|
||||
# if !defined(USE_ALPHA_HASH)
|
||||
# if !defined(DEPTH_SHADER)
|
||||
# if !defined(USE_ALPHA_BLEND)
|
||||
# if !defined(MAT_TRANSPARENT)
|
||||
# if !defined(USE_REFRACTION)
|
||||
# define ENABLE_DEFERED_AO
|
||||
# define ENABLE_DEFERRED_AO
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_DEFERED_AO
|
||||
#ifndef ENABLE_DEFERRED_AO
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
Remove these and prefer individual member assignment. Remove these and prefer individual member assignment.
|
||||
# if defined(STEP_RESOLVE)
|
||||
# define ENABLE_DEFERED_AO
|
||||
# define ENABLE_DEFERRED_AO
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -440,9 +442,9 @@ OcclusionData occlusion_load(vec3 vP, float custom_occlusion)
|
|||
/* Default to fully opened cone. */
|
||||
OcclusionData data = NO_OCCLUSION_DATA;
|
||||
|
||||
#ifdef ENABLE_DEFERED_AO
|
||||
if ((ao_buf.settings & AO_ENABLED) != 0) {
|
||||
data = unpack_occlusion_data(texelFetch(horizonBuffer, ivec2(gl_FragCoord.xy), 0));
|
||||
#ifdef ENABLE_DEFERRED_AO
|
||||
if (ao_buf.enabled) {
|
||||
data = unpack_occlusion_data(texelFetch(horizons_tx, ivec2(gl_FragCoord.xy), 0));
|
||||
}
|
||||
#else
|
||||
/* For blended surfaces. */
|
||||
|
@ -457,30 +459,3 @@ OcclusionData occlusion_load(vec3 vP, float custom_occlusion)
|
|||
#ifndef GPU_FRAGMENT_SHADER
|
||||
# undef gl_FragCoord
|
||||
#endif
|
||||
|
||||
float ambient_occlusion_eval(vec3 normal,
|
||||
float max_distance,
|
||||
const float inverted,
|
||||
const float sample_count)
|
||||
{
|
||||
/* Avoid multiline define causing compiler issues. */
|
||||
/* clang-format off */
|
||||
#if defined(GPU_FRAGMENT_SHADER) && (defined(MESH_SHADER) || defined(HAIR_SHADER)) && !defined(DEPTH_SHADER) && !defined(VOLUMETRICS)
|
||||
/* clang-format on */
|
||||
vec3 bent_normal;
|
||||
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
|
||||
OcclusionData data = occlusion_search(
|
||||
viewPosition, hiz_tx, max_distance, inverted, sample_count);
|
||||
|
||||
vec3 V = cameraVec(worldPosition);
|
||||
vec3 N = normalize(normal);
|
||||
vec3 Ng = safe_normalize(cross(dFdx(worldPosition), dFdy(worldPosition)));
|
||||
|
||||
float unused_error, visibility;
|
||||
vec3 unused;
|
||||
occlusion_eval(data, V, N, Ng, inverted, visibility, unused_error, unused);
|
||||
return visibility;
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_ao_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -199,12 +199,25 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
|||
}
|
||||
|
||||
float ambient_occlusion_eval(vec3 normal,
|
||||
float distance,
|
||||
float max_distance,
|
||||
const float inverted,
|
||||
const float sample_count)
|
||||
{
|
||||
/* TODO */
|
||||
#if defined(GPU_FRAGMENT_SHADER) && defined(MAT_AO) && !defined(MAT_DEPTH) && !defined(MAT_SHADOW)
|
||||
vec3 vP = transform_point(ViewMatrix, g_data.P);
|
||||
OcclusionData data = occlusion_search(vP, hiz_tx, max_distance, inverted, sample_count);
|
||||
|
||||
vec3 V = cameraVec(g_data.P);
|
||||
vec3 N = g_data.N;
|
||||
vec3 Ng = g_data.Ng;
|
||||
|
||||
float unused_error, visibility;
|
||||
vec3 unused;
|
||||
occlusion_eval(data, V, N, Ng, inverted, visibility, unused_error, unused);
|
||||
return visibility;
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef GPU_METAL
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_ao_lib.glsl)
|
||||
fclem marked this conversation as resolved
Outdated
Clément Foucault
commented
Why is this needed? Why is this needed?
Miguel Pozo
commented
Because the AO lib is required by the AO node in the nodetree lib. Because the AO lib is required by the AO node in the nodetree lib.
But I can’t include the AO lib directly from the nodetree lib since then it ends up also in the depth, shadow and world passes.
AFAIK there’s no way to make a conditional BLENDER_REQUIRE, so the other option would be to put the whole AO lib behind a define (which would be kind of annoying in most code editors).
|
||||
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_ao_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
|
||||
|
|
|
@ -9,7 +9,7 @@ GPU_SHADER_CREATE_INFO(eevee_raytrace_lib)
|
|||
|
||||
GPU_SHADER_CREATE_INFO(eevee_ao_lib)
|
||||
.additional_info("eevee_raytrace_lib", "eevee_utility_texture")
|
||||
.sampler(AO_HORIZONS_TEX_SLOT, ImageType::FLOAT_2D, "horizons_buffer_tx")
|
||||
.sampler(AO_HORIZONS_TEX_SLOT, ImageType::FLOAT_2D, "horizons_tx")
|
||||
.uniform_buf(AO_BUF_SLOT, "AOData", "ao_buf");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_ao)
|
||||
|
|
|
@ -41,6 +41,7 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_light)
|
|||
"eevee_deferred_base",
|
||||
"eevee_hiz_data",
|
||||
"eevee_render_pass_out",
|
||||
"eevee_ao_lib",
|
||||
"draw_view",
|
||||
"draw_fullscreen")
|
||||
.do_static_compilation(true);
|
||||
|
|
|
@ -108,7 +108,8 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
|
|||
"eevee_utility_texture",
|
||||
"eevee_sampling_data",
|
||||
"eevee_render_pass_out",
|
||||
"eevee_cryptomatte_out");
|
||||
"eevee_cryptomatte_out",
|
||||
"eevee_ao_lib");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surf_forward)
|
||||
.vertex_out(eevee_surf_iface)
|
||||
|
@ -122,7 +123,8 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
|
|||
"eevee_camera",
|
||||
"eevee_utility_texture",
|
||||
"eevee_sampling_data",
|
||||
"eevee_shadow_data"
|
||||
"eevee_shadow_data",
|
||||
"eevee_ao_lib"
|
||||
/* Optionally added depending on the material. */
|
||||
// "eevee_render_pass_out",
|
||||
// "eevee_cryptomatte_out",
|
||||
|
@ -131,6 +133,7 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
|
|||
);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surf_depth)
|
||||
.define("MAT_DEPTH")
|
||||
.vertex_out(eevee_surf_iface)
|
||||
.fragment_source("eevee_surf_depth_frag.glsl")
|
||||
.additional_info("eevee_sampling_data", "eevee_camera", "eevee_utility_texture");
|
||||
|
|
Loading…
Reference in New Issue
I'm almost tempted to remove this pass altogether. It might just become a subpass of the raytracing pipeline.