Eevee: Add support for the holdout node

Support should be full when using Alpha Blend mode and partial if using
any other blend mode (opaque / alpha clip / alpha hashed).
This commit is contained in:
Clément Foucault 2019-08-12 18:40:52 +02:00
parent 13d469e6f0
commit 67c10dbf13
Notes: blender-bot 2023-02-14 07:25:46 +01:00
Referenced by issue #68455, Holdout
4 changed files with 33 additions and 7 deletions

View File

@ -216,7 +216,7 @@ shader_node_categories = [
NodeItem("ShaderNodeEmission", poll=eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfHair", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll),
NodeItem("ShaderNodeHoldout", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeHoldout", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumeAbsorption", poll=eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumePrincipled"),

View File

@ -775,6 +775,7 @@ Closure closure_emission(vec3 rgb)
struct Closure {
vec3 radiance;
vec3 transmittance;
float holdout;
# ifdef USE_SSS
vec4 sss_data;
# ifdef USE_SSS_ALBEDO
@ -792,16 +793,18 @@ Closure nodetree_exec(void); /* Prototype */
# define CLOSURE_SSR_FLAG 1
# define CLOSURE_SSS_FLAG 2
# define CLOSURE_HOLDOUT_FLAG 4
# ifdef USE_SSS
# ifdef USE_SSS_ALBEDO
# define CLOSURE_DEFAULT \
Closure(vec3(0.0), vec3(0.0), vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), 0)
Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), 0)
# else
# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec4(0.0), vec4(0.0), vec2(0.0), 0)
# define CLOSURE_DEFAULT \
Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec4(0.0), vec2(0.0), 0)
# endif
# else
# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec4(0.0), vec2(0.0), 0)
# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
# endif
uniform int outputSsrId = 1;
@ -848,6 +851,7 @@ void closure_load_sss_data(float radius,
Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
Closure cl;
cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
cl.flag = cl1.flag | cl2.flag;
@ -874,6 +878,7 @@ Closure closure_add(Closure cl1, Closure cl2)
Closure cl;
cl.transmittance = cl1.transmittance + cl2.transmittance;
cl.radiance = cl1.radiance + cl2.radiance;
cl.holdout = cl1.holdout + cl2.holdout;
cl.flag = cl1.flag | cl2.flag;
cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
@ -933,16 +938,18 @@ void main()
{
Closure cl = nodetree_exec();
float holdout = 1.0 - saturate(cl.holdout);
# ifdef USE_ALPHA_BLEND
vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
vec3 vol_transmit, vol_scatter;
volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
float transmit = saturate(avg(cl.transmittance));
outRadiance = vec4(cl.radiance * vol_transmit + vol_scatter, (1.0 - transmit));
outTransmittance = vec4(cl.transmittance, transmit);
outRadiance = vec4(cl.radiance * vol_transmit + vol_scatter, (1.0 - transmit) * holdout);
outTransmittance = vec4(cl.transmittance, transmit * holdout);
# else
outRadiance = vec4(cl.radiance, 1.0);
outRadiance = vec4(cl.radiance, holdout);
ssrNormals = cl.ssr_normal;
ssrData = cl.ssr_data;
# ifdef USE_SSS

View File

@ -1964,6 +1964,15 @@ void node_volume_principled(vec4 color,
#endif
}
void node_holdout(out Closure result)
{
result = CLOSURE_DEFAULT;
#ifndef VOLUMETRICS
result.holdout = 1.0;
result.flag = CLOSURE_HOLDOUT_FLAG;
#endif
}
/* closures */
void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)

View File

@ -30,6 +30,15 @@ static bNodeSocketTemplate sh_node_holdout_out[] = {
{-1, 0, ""},
};
static int gpu_shader_rgb(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
GPUNodeStack *in,
GPUNodeStack *out)
{
return GPU_stack_link(mat, node, "node_holdout", in, out);
}
/* node type definition */
void register_node_type_sh_holdout(void)
{
@ -39,6 +48,7 @@ void register_node_type_sh_holdout(void)
node_type_socket_templates(&ntype, sh_node_holdout_in, sh_node_holdout_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, gpu_shader_rgb);
nodeRegisterType(&ntype);
}