EEVEE-Next: Limit cost of transmission evaluation
This uses specialization constants to compile optimized deferred lighting shader for when transmission is not needed.
This commit is contained in:
@@ -617,6 +617,7 @@ void DeferredLayer::end_sync(bool is_first_pass, bool is_last_pass)
|
||||
sub.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
|
||||
}
|
||||
{
|
||||
const bool use_transmission = (closure_bits_ & CLOSURE_TRANSMISSION) != 0;
|
||||
const bool use_split_indirect = !use_raytracing_ && use_split_radiance_;
|
||||
PassSimple::Sub &sub = pass.sub("Eval.Light");
|
||||
/* Use depth test to reject background pixels which have not been stencil cleared. */
|
||||
@@ -636,6 +637,7 @@ void DeferredLayer::end_sync(bool is_first_pass, bool is_last_pass)
|
||||
sub.specialize_constant(sh, "render_pass_shadow_id", rbuf_data.shadow_id);
|
||||
sub.specialize_constant(sh, "use_split_indirect", use_split_indirect);
|
||||
sub.specialize_constant(sh, "use_lightprobe_eval", !use_raytracing_);
|
||||
sub.specialize_constant(sh, "use_transmission", false);
|
||||
const ShadowSceneData &shadow_scene = inst_.shadows.get_data();
|
||||
sub.specialize_constant(sh, "shadow_ray_count", &shadow_scene.ray_count);
|
||||
sub.specialize_constant(sh, "shadow_ray_step_count", &shadow_scene.step_count);
|
||||
@@ -654,11 +656,18 @@ void DeferredLayer::end_sync(bool is_first_pass, bool is_last_pass)
|
||||
sub.bind_resources(inst_.hiz_buffer.front);
|
||||
sub.bind_resources(inst_.sphere_probes);
|
||||
sub.bind_resources(inst_.volume_probes);
|
||||
/* TODO(fclem): Transmission evaluation specialization. */
|
||||
uint8_t compare_mask = uint8_t(StencilBits::CLOSURE_COUNT_0) |
|
||||
uint8_t(StencilBits::CLOSURE_COUNT_1);
|
||||
uint8_t(StencilBits::CLOSURE_COUNT_1) |
|
||||
uint8_t(StencilBits::TRANSMISSION);
|
||||
sub.state_stencil(0x0u, i + 1, compare_mask);
|
||||
sub.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
if (use_transmission) {
|
||||
/* Separate pass for transmission BSDF as their evaluation is quite costly. */
|
||||
sub.specialize_constant(sh, "use_transmission", true);
|
||||
sub.shader_set(sh);
|
||||
sub.state_stencil(0x0u, (i + 1) | uint8_t(StencilBits::TRANSMISSION), compare_mask);
|
||||
sub.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,28 +70,22 @@ void main()
|
||||
* by 1 for this evaluation and skip evaluating the transmission closure twice. */
|
||||
light_eval_reflection(stack, P, Ng, V, vPz);
|
||||
|
||||
#if 1 /* TODO Limit to transmission. Can bypass the check if stencil is tagged properly and use \
|
||||
specialization constant. */
|
||||
ClosureUndetermined cl_transmit = gbuffer_closure_get(gbuf, 0);
|
||||
if ((cl_transmit.type == CLOSURE_BSDF_TRANSLUCENT_ID) ||
|
||||
(cl_transmit.type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID) ||
|
||||
(cl_transmit.type == CLOSURE_BSSRDF_BURLEY_ID))
|
||||
{
|
||||
|
||||
# if 1 /* TODO Limit to SSS. */
|
||||
if (use_transmission) {
|
||||
ClosureUndetermined cl_transmit = gbuffer_closure_get(gbuf, 0);
|
||||
#if 1 /* TODO Limit to SSS. */
|
||||
vec3 sss_reflect_shadowed, sss_reflect_unshadowed;
|
||||
if (cl_transmit.type == CLOSURE_BSSRDF_BURLEY_ID) {
|
||||
sss_reflect_shadowed = stack.cl[0].light_shadowed;
|
||||
sss_reflect_unshadowed = stack.cl[0].light_unshadowed;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
stack.cl[0] = closure_light_new(cl_transmit, V, gbuf.thickness);
|
||||
|
||||
/* NOTE: Only evaluates `stack.cl[0]`. */
|
||||
light_eval_transmission(stack, P, Ng, V, vPz, gbuf.thickness);
|
||||
|
||||
# if 1 /* TODO Limit to SSS. */
|
||||
#if 1 /* TODO Limit to SSS. */
|
||||
if (cl_transmit.type == CLOSURE_BSSRDF_BURLEY_ID) {
|
||||
/* Apply transmission profile onto transmitted light and sum with reflected light. */
|
||||
vec3 sss_profile = subsurface_transmission(to_closure_subsurface(cl_transmit).sss_radius,
|
||||
@@ -101,9 +95,8 @@ void main()
|
||||
stack.cl[0].light_shadowed += sss_reflect_shadowed;
|
||||
stack.cl[0].light_unshadowed += sss_reflect_unshadowed;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (render_pass_shadow_id != -1) {
|
||||
vec3 radiance_shadowed = vec3(0);
|
||||
|
||||
@@ -63,6 +63,7 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_light)
|
||||
.image_out(7, DEFERRED_RADIANCE_FORMAT, "indirect_radiance_3_img")
|
||||
.specialization_constant(Type::BOOL, "use_split_indirect", false)
|
||||
.specialization_constant(Type::BOOL, "use_lightprobe_eval", false)
|
||||
.specialization_constant(Type::BOOL, "use_transmission", false)
|
||||
.specialization_constant(Type::INT, "render_pass_shadow_id", -1)
|
||||
.define("SPECIALIZED_SHADOW_PARAMS")
|
||||
.specialization_constant(Type::INT, "shadow_ray_count", 1)
|
||||
|
||||
Reference in New Issue
Block a user