Fix T97985 EEVEE: Shader mixing not working correctly when reusing shader nodes
This was caused by the `Closure` members being added to the final contribution more than once. The workaround is to clear the members once a closure has been added to the final contribution. I used `inout` on `Closure` inputs so that the render engine implementation of mix and add closure nodes can do its own thing. The nodegraph handling of inout was changed for this to work.
This commit is contained in:
parent
10865c8f34
commit
35594f4b92
Notes:
blender-bot
2023-02-14 09:43:37 +01:00
Referenced by commit 11aa237858
, Eevee: Fix GLSL compilation error.
Referenced by issue #98003, Regression: Crash in EEVEE when switched to material preview or viewport/final render
Referenced by issue #97985, Eevee: Shader mixing not working correctly when reusing shader nodes
|
@ -309,16 +309,19 @@ vec4 closure_to_rgba(Closure closure)
|
|||
return vec4(closure.radiance, 1.0 - saturate(avg(closure.transmittance)));
|
||||
}
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
Closure closure_add(inout Closure cl1, inout Closure cl2)
|
||||
{
|
||||
Closure cl;
|
||||
cl.radiance = cl1.radiance + cl2.radiance;
|
||||
cl.transmittance = cl1.transmittance + cl2.transmittance;
|
||||
cl.holdout = cl1.holdout + cl2.holdout;
|
||||
/* Make sure each closure is only added once to the result. */
|
||||
cl1 = CLOSURE_DEFAULT;
|
||||
cl2 = CLOSURE_DEFAULT;
|
||||
return cl;
|
||||
}
|
||||
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
Closure closure_mix(inout Closure cl1, inout Closure cl2, float fac)
|
||||
{
|
||||
/* Weights have already been applied. */
|
||||
return closure_add(cl1, cl2);
|
||||
|
|
|
@ -92,7 +92,7 @@ vec4 closure_to_rgba(Closure closure)
|
|||
return vec4(0.0);
|
||||
}
|
||||
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
Closure closure_mix(inout Closure cl1, inout Closure cl2, float fac)
|
||||
{
|
||||
Closure cl;
|
||||
cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
|
||||
|
@ -102,7 +102,7 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
|||
return cl;
|
||||
}
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
Closure closure_add(inout Closure cl1, inout Closure cl2)
|
||||
{
|
||||
Closure cl;
|
||||
cl.absorption = cl1.absorption + cl2.absorption;
|
||||
|
|
|
@ -87,8 +87,8 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
ClosureReflection clearcoat,
|
||||
ClosureRefraction refraction);
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2);
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac);
|
||||
Closure closure_add(inout Closure cl1, inout Closure cl2);
|
||||
Closure closure_mix(inout Closure cl1, inout Closure cl2, float fac);
|
||||
|
||||
float ambient_occlusion_eval(vec3 normal,
|
||||
float distance,
|
||||
|
|
|
@ -611,7 +611,7 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
|
|||
|
||||
va_start(params, name);
|
||||
for (i = 0; i < function->totparam; i++) {
|
||||
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
|
||||
if (function->paramqual[i] == FUNCTION_QUAL_OUT) {
|
||||
linkptr = va_arg(params, GPUNodeLink **);
|
||||
gpu_node_output(node, function->paramtype[i], linkptr);
|
||||
}
|
||||
|
@ -669,7 +669,7 @@ static bool gpu_stack_link_v(GPUMaterial *material,
|
|||
}
|
||||
|
||||
for (i = 0; i < function->totparam; i++) {
|
||||
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
|
||||
if (function->paramqual[i] == FUNCTION_QUAL_OUT) {
|
||||
if (totout == 0) {
|
||||
linkptr = va_arg(params, GPUNodeLink **);
|
||||
gpu_node_output(node, function->paramtype[i], linkptr);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
void node_add_shader(Closure shader1, Closure shader2, out Closure shader)
|
||||
void node_add_shader(inout Closure shader1, inout Closure shader2, out Closure shader)
|
||||
{
|
||||
shader = closure_add(shader1, shader2);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
|
||||
void node_mix_shader(float fac, inout Closure shader1, inout Closure shader2, out Closure shader)
|
||||
{
|
||||
shader = closure_mix(shader1, shader2, fac);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue