diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 963da894f76..14d7d317914 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -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; } diff --git a/intern/cycles/kernel/integrator/volume_shader.h b/intern/cycles/kernel/integrator/volume_shader.h index 23493562fe8..ca36df1b95f 100644 --- a/intern/cycles/kernel/integrator/volume_shader.h +++ b/intern/cycles/kernel/integrator/volume_shader.h @@ -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++) { diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h index 970e4d8916c..764abc96ac8 100644 --- a/intern/cycles/kernel/osl/closures_setup.h +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -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( diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 24da8869a4d..ac494366928 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -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); } diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index df95cef8b5e..c13d20596f9 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -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) diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 1693d685799..a7790e74837 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -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. */