Merge branch 'blender-v3.4-release'

This commit is contained in:
Joseph Eagar 2022-11-24 09:02:23 -08:00
commit 14a0fb0cc6
6 changed files with 91 additions and 41 deletions

View File

@ -34,6 +34,9 @@ typedef struct VolumeIntegrateResult {
Spectrum direct_throughput;
float direct_t;
ShaderVolumePhases direct_phases;
# ifdef __PATH_GUIDING__
VolumeSampleMethod direct_sample_method;
# endif
/* Throughput and offset for indirect light scattering. */
bool indirect_scatter;
@ -580,6 +583,9 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
result.direct_t = volume_equiangular_sample(
ray, equiangular_light_P, vstate.rscatter, &vstate.equiangular_pdf);
}
# ifdef __PATH_GUIDING__
result.direct_sample_method = vstate.direct_sample_method;
# endif
# ifdef __DENOISING_FEATURES__
const bool write_denoising_features = (INTEGRATOR_STATE(state, path, flag) &
@ -719,6 +725,9 @@ ccl_device_forceinline void integrate_volume_direct_light(
ccl_private const RNGState *ccl_restrict rng_state,
const float3 P,
ccl_private const ShaderVolumePhases *ccl_restrict phases,
# ifdef __PATH_GUIDING__
ccl_private const Spectrum unlit_throughput,
# endif
ccl_private const Spectrum throughput,
ccl_private LightSample *ccl_restrict ls)
{
@ -851,7 +860,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
kernel_data.background.lightgroup + 1;
# ifdef __PATH_GUIDING__
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = throughput;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
state, guiding, path_segment);
# endif
@ -990,7 +999,13 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
/* The current path throughput which is used later to calculate per-segment throughput.*/
const float3 initial_throughput = INTEGRATOR_STATE(state, path, throughput);
/* The path throughput used to calculate the throughput for direct light. */
float3 unlit_throughput = initial_throughput;
/* If a new path segment is generated at the direct scatter position.*/
bool guiding_generated_new_segment = false;
float rand_phase_guiding = 0.5f;
# endif
/* TODO: expensive to zero closures? */
@ -1018,41 +1033,48 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
return VOLUME_PATH_MISSED;
}
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
bool guiding_generated_new_segment = false;
if (kernel_data.integrator.use_guiding) {
/* Record transmittance using change in throughput. */
float3 transmittance_weight = spectrum_to_rgb(
safe_divide_color(result.indirect_throughput, initial_throughput));
guiding_record_volume_transmission(kg, state, transmittance_weight);
if (result.indirect_scatter) {
const float3 P = ray->P + result.indirect_t * ray->D;
/* Record volume segment up to direct scatter position.
* TODO: volume segment is wrong when direct_t and indirect_t. */
if (result.direct_scatter && (result.direct_t == result.indirect_t)) {
guiding_record_volume_segment(kg, state, P, sd.I);
guiding_generated_new_segment = true;
}
# if PATH_GUIDING_LEVEL >= 4
/* TODO: this position will be wrong for direct light pdf computation,
* since the direct light position may be different? */
volume_shader_prepare_guiding(
kg, state, &sd, &rng_state, P, ray->D, &result.direct_phases, direct_sample_method);
# endif
}
else {
/* No guiding if we don't scatter. */
state->guiding.use_volume_guiding = false;
}
}
# endif
/* Direct light. */
if (result.direct_scatter) {
const float3 direct_P = ray->P + result.direct_t * ray->D;
# ifdef __PATH_GUIDING__
if (kernel_data.integrator.use_guiding) {
# if PATH_GUIDING_LEVEL >= 1
if (result.direct_sample_method == VOLUME_SAMPLE_DISTANCE) {
/* If the direct scatter event is generated using VOLUME_SAMPLE_DISTANCE the direct event
* will happen at the same position as the indirect event and the direct light contribution
* will contribute to the position of the next path segment.*/
float3 transmittance_weight = spectrum_to_rgb(
safe_divide_color(result.indirect_throughput, initial_throughput));
guiding_record_volume_transmission(kg, state, transmittance_weight);
guiding_record_volume_segment(kg, state, direct_P, sd.I);
guiding_generated_new_segment = true;
unlit_throughput = result.indirect_throughput / continuation_probability;
rand_phase_guiding = path_state_rng_1D(kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_DISTANCE);
}
else {
/* If the direct scatter event is generated using VOLUME_SAMPLE_EQUIANGULAR the direct
* event will happen at a separate position as the indirect event and the direct light
* contribution will contribute to the position of the current/previous path segment. The
* unlit_throughput has to be adjusted to include the scattering at the previous segment.*/
float3 scatterEval = one_float3();
if (state->guiding.path_segment) {
pgl_vec3f scatteringWeight = state->guiding.path_segment->scatteringWeight;
scatterEval = make_float3(scatteringWeight.x, scatteringWeight.y, scatteringWeight.z);
}
unlit_throughput /= scatterEval;
unlit_throughput *= continuation_probability;
rand_phase_guiding = path_state_rng_1D(
kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_EQUIANGULAR);
}
# endif
# if PATH_GUIDING_LEVEL >= 4
volume_shader_prepare_guiding(
kg, state, &sd, rand_phase_guiding, direct_P, ray->D, &result.direct_phases);
# endif
}
# endif
result.direct_throughput /= continuation_probability;
integrate_volume_direct_light(kg,
state,
@ -1060,6 +1082,9 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
&rng_state,
direct_P,
&result.direct_phases,
# ifdef __PATH_GUIDING__
unlit_throughput,
# endif
result.direct_throughput,
&ls);
}
@ -1069,6 +1094,13 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
* Only divide throughput by continuation_probability if we scatter. For the attenuation
* case the next surface will already do this division. */
if (result.indirect_scatter) {
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
if (!guiding_generated_new_segment) {
float3 transmittance_weight = spectrum_to_rgb(
safe_divide_color(result.indirect_throughput, initial_throughput));
guiding_record_volume_transmission(kg, state, transmittance_weight);
}
# endif
result.indirect_throughput /= continuation_probability;
}
INTEGRATOR_STATE_WRITE(state, path, throughput) = result.indirect_throughput;
@ -1076,10 +1108,21 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
if (result.indirect_scatter) {
sd.P = ray->P + result.indirect_t * ray->D;
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
# if defined(__PATH_GUIDING__)
# if PATH_GUIDING_LEVEL >= 1
if (!guiding_generated_new_segment) {
guiding_record_volume_segment(kg, state, sd.P, sd.I);
}
# endif
# if PATH_GUIDING_LEVEL >= 4
/* If the direct scatter event was generated using VOLUME_SAMPLE_EQUIANGULAR we need to
* initialize the guiding distribution at the indirect scatter position. */
if (result.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR) {
rand_phase_guiding = path_state_rng_1D(kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_DISTANCE);
volume_shader_prepare_guiding(
kg, state, &sd, rand_phase_guiding, sd.P, ray->D, &result.indirect_phases);
}
# endif
# endif
if (integrate_volume_phase_scatter(kg, state, &sd, &rng_state, &result.indirect_phases)) {
@ -1090,6 +1133,10 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
}
}
else {
# if defined(__PATH_GUIDING__)
/* No guiding if we don't scatter. */
state->guiding.use_volume_guiding = false;
# endif
return VOLUME_PATH_ATTENUATED;
}
}

View File

@ -95,11 +95,10 @@ ccl_device_inline void volume_shader_copy_phases(ccl_private ShaderVolumePhases
ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
IntegratorState state,
ccl_private ShaderData *sd,
ccl_private const RNGState *rng_state,
float rand_phase_guiding,
const float3 P,
const float3 D,
ccl_private ShaderVolumePhases *phases,
const VolumeSampleMethod direct_sample_method)
ccl_private ShaderVolumePhases *phases)
{
/* Have any phase functions to guide? */
const int num_phases = phases->num_closure;
@ -109,7 +108,6 @@ ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
}
const float volume_guiding_probability = kernel_data.integrator.volume_guiding_probability;
float rand_phase_guiding = path_state_rng_1D(kg, rng_state, PRNG_VOLUME_PHASE_GUIDING);
/* If we have more than one phase function we select one random based on its
* sample weight to calculate the product distribution for guiding. */

View File

@ -160,7 +160,8 @@ enum PathTraceDimension {
PRNG_VOLUME_SCATTER_DISTANCE = 5,
PRNG_VOLUME_OFFSET = 6,
PRNG_VOLUME_SHADE_OFFSET = 7,
PRNG_VOLUME_PHASE_GUIDING = 8,
PRNG_VOLUME_PHASE_GUIDING_DISTANCE = 8,
PRNG_VOLUME_PHASE_GUIDING_EQUIANGULAR = 9,
/* Subsurface random walk bounces */
PRNG_SUBSURFACE_BSDF = 0,

View File

@ -749,7 +749,7 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
if (node_skip_input(node, input)) {
continue;
}
if (input->flags() & SocketType::LINK_OSL_INITIALIZER) {
if ((input->flags() & SocketType::LINK_OSL_INITIALIZER) && !(input->constant_folded_in)) {
continue;
}

View File

@ -847,7 +847,10 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object
use_stroke_id = true;
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_CAVITY_USE_CURVE)) {
BKE_curvemapping_init(brush->automasking_cavity_curve);
if (brush) {
BKE_curvemapping_init(brush->automasking_cavity_curve);
}
BKE_curvemapping_init(sd->automasking_cavity_curve);
}

View File

@ -1357,6 +1357,7 @@ float SCULPT_automasking_factor_get(struct AutomaskingCache *automasking,
* brushes and filter. */
struct AutomaskingCache *SCULPT_automasking_active_cache_get(SculptSession *ss);
/* Brush can be null. */
struct AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob);
void SCULPT_automasking_cache_free(struct AutomaskingCache *automasking);