EEVEE Next: Subsurface Scattering #107407

Merged
Miguel Pozo merged 24 commits from pragma37/blender:pull-eevee-next-sss into main 2023-06-15 15:49:12 +02:00
3 changed files with 20 additions and 24 deletions
Showing only changes of commit 7db9f0087f - Show all commits

View File

@ -156,8 +156,7 @@ void ForwardPipeline::sync()
opaque_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info);
/* Textures. */
opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
opaque_ps_.bind_texture(SSS_TRANSMITTANCE_TEX_SLOT,
inst_.subsurface.transmittance_ref_get());
opaque_ps_.bind_texture(SSS_TRANSMITTANCE_TEX_SLOT, inst_.subsurface.transmittance_tx_get());
/* Uniform Buffer. */
opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
@ -185,7 +184,7 @@ void ForwardPipeline::sync()
/* Textures. */
sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
sub.bind_texture(SSS_TRANSMITTANCE_TEX_SLOT, inst_.subsurface.transmittance_ref_get());
sub.bind_texture(SSS_TRANSMITTANCE_TEX_SLOT, inst_.subsurface.transmittance_tx_get());
/* Uniform Buffer. */
sub.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
@ -366,17 +365,14 @@ void DeferredLayer::begin_sync()
void DeferredLayer::end_sync()
{
/* Use stencil test to reject pixel not written by this layer. */
/* WORKAROUND: Stencil write is only here to avoid rasterizer discard. */
DRWState state = DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_EQUAL;
/* Allow output to combined pass for the last pass. */
DRWState state_write_color = state | DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
if (closure_bits_ & (CLOSURE_DIFFUSE | CLOSURE_REFLECTION)) {
const bool is_last_eval_pass = !(closure_bits_ & CLOSURE_SSS);
eval_light_ps_.init();
eval_light_ps_.state_set(state_write_color);
/* Use stencil test to reject pixel not written by this layer. */
eval_light_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL |
DRW_STATE_BLEND_CUSTOM);
eval_light_ps_.state_stencil(0x00u, 0x01u, 0xFFu);
eval_light_ps_.shader_set(inst_.shaders.static_shader_get(DEFERRED_LIGHT));
eval_light_ps_.bind_image("out_diffuse_light_img", &diffuse_light_tx_);
@ -387,7 +383,7 @@ void DeferredLayer::end_sync()
eval_light_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx);
eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
eval_light_ps_.bind_texture(SSS_TRANSMITTANCE_TEX_SLOT,
inst_.subsurface.transmittance_ref_get());
inst_.subsurface.transmittance_tx_get());
inst_.lights.bind_resources(&eval_light_ps_);
inst_.shadows.bind_resources(&eval_light_ps_);

View File

@ -31,7 +31,7 @@ void SubsurfaceModule::end_sync()
data_.sample_len = 55;
}
if (transmittance_tx == nullptr) {
if (!transmittance_tx.is_valid()) {
precompute_transmittance_profile();
}
@ -105,12 +105,8 @@ void SubsurfaceModule::precompute_transmittance_profile()
profile.first() = 1;
profile.last() = 0;
transmittance_tx = GPU_texture_create_1d("SSSTransmittanceProfile",
profile.size(),
1,
GPU_R16F,
GPU_TEXTURE_USAGE_SHADER_READ,
profile.data());
transmittance_tx.ensure_1d(
GPU_R16F, profile.size(), GPU_TEXTURE_USAGE_SHADER_READ, profile.data());
}
/** \} */

View File

@ -5,6 +5,15 @@
/** \file
* \ingroup eevee
*
* Postprocess diffuse radiance output from the diffuse evaluation pass to mimic subsurface
* transmission.
*
* This implementation follows the technique described in the siggraph presentation:
* "Efficient screen space subsurface scattering Siggraph 2018"
* by Evgenii Golubev
*
* But, instead of having all the precomputed weights for all three color primaries,
* we precompute a weight profile texture to be able to support per pixel AND per channel radius.
*/
#pragma once
@ -27,7 +36,7 @@ struct SubsurfaceModule {
/** Contains samples locations. */
SubsurfaceDataBuf data_;
/** Contains translucence profile for a single color channel. */
GPUTexture *transmittance_tx = nullptr;
Texture transmittance_tx;
public:
SubsurfaceModule(Instance &inst) : inst_(inst)
@ -48,12 +57,7 @@ struct SubsurfaceModule {
pass->bind_ubo("sss_buf", data_);
}
const GPUUniformBuf *ubo_get(void) const
{
return data_;
}
GPUTexture **transmittance_ref_get(void)
GPUTexture **transmittance_tx_get(void)
{
return &transmittance_tx;
}