Fix #94323: Cycles blocky artifacts in overlapping volumes due to scale difference
when computing coefficients in volume, the volume density of the object at the top of the stack is used, which leads to wrong result if overlapping volumes have different scales. This commit fixes the problem by pre-multiplying the volume density per object when evaluating the shader. Pull Request: https://projects.blender.org/blender/blender/pulls/123733
This commit is contained in:
parent
9b61673b46
commit
02e6985c62
@ -82,8 +82,7 @@ ccl_device_inline bool shadow_volume_shader_sample(KernelGlobals kg,
|
||||
return false;
|
||||
}
|
||||
|
||||
const float density = object_volume_density(kg, sd->object);
|
||||
*extinction = sd->closure_transparent_extinction * density;
|
||||
*extinction = sd->closure_transparent_extinction;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -116,11 +115,6 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
|
||||
const float density = object_volume_density(kg, sd->object);
|
||||
coeff->sigma_s *= density;
|
||||
coeff->sigma_t *= density;
|
||||
coeff->emission *= density;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ ccl_device_inline void volume_shader_eval(KernelGlobals kg,
|
||||
* for all volumes in the stack into a single array of closures */
|
||||
sd->num_closure = 0;
|
||||
sd->num_closure_left = max_closures;
|
||||
sd->flag = 0;
|
||||
sd->flag = SD_IS_VOLUME_SHADER_EVAL;
|
||||
sd->object_flag = 0;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
|
@ -749,6 +749,9 @@ ccl_device void osl_closure_emission_setup(KernelGlobals kg,
|
||||
ccl_private const GenericEmissiveClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (sd->flag & SD_IS_VOLUME_SHADER_EVAL) {
|
||||
weight *= object_volume_density(kg, sd->object);
|
||||
}
|
||||
emission_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
|
||||
@ -1031,7 +1034,7 @@ ccl_device void osl_closure_absorption_setup(KernelGlobals kg,
|
||||
ccl_private const VolumeAbsorptionClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
volume_extinction_setup(sd, rgb_to_spectrum(weight));
|
||||
volume_extinction_setup(sd, rgb_to_spectrum(weight * object_volume_density(kg, sd->object)));
|
||||
}
|
||||
|
||||
ccl_device void osl_closure_henyey_greenstein_setup(
|
||||
@ -1042,6 +1045,7 @@ ccl_device void osl_closure_henyey_greenstein_setup(
|
||||
ccl_private const VolumeHenyeyGreensteinClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
weight *= object_volume_density(kg, sd->object);
|
||||
volume_extinction_setup(sd, rgb_to_spectrum(weight));
|
||||
|
||||
ccl_private HenyeyGreensteinVolume *volume = (ccl_private HenyeyGreensteinVolume *)bsdf_alloc(
|
||||
|
@ -935,7 +935,7 @@ ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg,
|
||||
|
||||
float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
|
||||
__uint_as_float(node.z);
|
||||
density = mix_weight * fmaxf(density, 0.0f);
|
||||
density = mix_weight * fmaxf(density, 0.0f) * object_volume_density(kg, sd->object);
|
||||
|
||||
/* Compute scattering coefficient. */
|
||||
Spectrum weight = closure_weight;
|
||||
@ -997,7 +997,7 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
||||
float primitive_density = 1.0f;
|
||||
float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
|
||||
__uint_as_float(value_node.x);
|
||||
density = mix_weight * fmaxf(density, 0.0f);
|
||||
density = mix_weight * fmaxf(density, 0.0f) * object_volume_density(kg, sd->object);
|
||||
|
||||
if (density > CLOSURE_WEIGHT_CUTOFF) {
|
||||
/* Density and color attribute lookup if available. */
|
||||
@ -1055,7 +1055,8 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
||||
|
||||
if (emission > CLOSURE_WEIGHT_CUTOFF) {
|
||||
float3 emission_color = stack_load_float3(stack, emission_color_offset);
|
||||
emission_setup(sd, rgb_to_spectrum(emission * emission_color));
|
||||
emission_setup(
|
||||
sd, rgb_to_spectrum(emission * emission_color * object_volume_density(kg, sd->object)));
|
||||
}
|
||||
|
||||
if (blackbody > CLOSURE_WEIGHT_CUTOFF) {
|
||||
@ -1079,14 +1080,15 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
||||
float3 blackbody_tint = stack_load_float3(stack, node.w);
|
||||
float3 bb = blackbody_tint * intensity *
|
||||
rec709_to_rgb(kg, svm_math_blackbody_color_rec709(T));
|
||||
emission_setup(sd, rgb_to_spectrum(bb));
|
||||
emission_setup(sd, rgb_to_spectrum(bb * object_volume_density(kg, sd->object)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return offset;
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd,
|
||||
ccl_device_noinline void svm_node_closure_emission(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
uint4 node)
|
||||
@ -1104,6 +1106,10 @@ ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd,
|
||||
weight *= mix_weight;
|
||||
}
|
||||
|
||||
if (sd->flag & SD_IS_VOLUME_SHADER_EVAL) {
|
||||
weight *= object_volume_density(kg, sd->object);
|
||||
}
|
||||
|
||||
emission_setup(sd, weight);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
|
||||
SVM_CASE(NODE_CLOSURE_EMISSION)
|
||||
IF_KERNEL_NODES_FEATURE(EMISSION)
|
||||
{
|
||||
svm_node_closure_emission(sd, stack, closure_weight, node);
|
||||
svm_node_closure_emission(kg, sd, stack, closure_weight, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_BACKGROUND)
|
||||
|
@ -1024,6 +1024,8 @@ enum ShaderDataFlag {
|
||||
SD_EXTINCTION = (1 << 6),
|
||||
/* Shader has have volume phase (scatter) closure. */
|
||||
SD_SCATTER = (1 << 7),
|
||||
/* Shader is being evaluated in a volume. */
|
||||
SD_IS_VOLUME_SHADER_EVAL = (1 << 8),
|
||||
/* Shader has transparent closure. */
|
||||
SD_TRANSPARENT = (1 << 9),
|
||||
/* BSDF requires LCG for evaluation. */
|
||||
@ -1034,8 +1036,8 @@ enum ShaderDataFlag {
|
||||
SD_RAY_PORTAL = (1 << 12),
|
||||
|
||||
SD_CLOSURE_FLAGS = (SD_EMISSION | SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSSRDF | SD_HOLDOUT |
|
||||
SD_EXTINCTION | SD_SCATTER | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION |
|
||||
SD_RAY_PORTAL),
|
||||
SD_EXTINCTION | SD_SCATTER | SD_IS_VOLUME_SHADER_EVAL | SD_BSDF_NEEDS_LCG |
|
||||
SD_BSDF_HAS_TRANSMISSION | SD_RAY_PORTAL),
|
||||
|
||||
/* Shader flags. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user