34 for (
int i = 0;
i < sd->num_closure;
i++) {
41 for (
int j =
i + 1; j < sd->num_closure; j++) {
47 sci->weight += scj->weight;
48 sci->sample_weight += scj->sample_weight;
50 const int size = sd->num_closure - (j + 1);
52 for (
int k = 0; k <
size; k++) {
68 phases->num_closure = 0;
70 for (
int i = 0;
i < sd->num_closure;
i++) {
71 const ccl_private ShaderClosure *from_sc = &sd->closure[
i];
85# ifdef __PATH_GUIDING__
89 float rand_phase_guiding,
95 const int num_phases = phases->num_closure;
96 if (!
kernel_data.integrator.use_volume_guiding || num_phases == 0) {
97 state->guiding.use_volume_guiding =
false;
101 const float volume_guiding_probability =
kernel_data.integrator.volume_guiding_probability;
106 float phase_weight = 1.0f;
108 if (num_phases > 1) {
112 for (phase_id = 0; phase_id < num_phases; phase_id++) {
114 sum += svc->sample_weight;
117 const float r = rand_phase_guiding *
sum;
118 float partial_sum = 0.0f;
120 for (phase_id = 0; phase_id < num_phases; phase_id++) {
126 rand_phase_guiding = (r - partial_sum) / svc->sample_weight;
127 phase_weight = svc->sample_weight /
sum;
131 partial_sum = next_sum;
135 phases->closure[phase_id].sample_weight *= volume_guiding_probability;
142 state->guiding.use_volume_guiding =
false;
146 state->guiding.use_volume_guiding =
true;
147 state->guiding.sample_volume_guiding_rand = rand_phase_guiding;
148 state->guiding.volume_guiding_sampling_prob = volume_guiding_probability * phase_weight;
151 state->guiding.volume_guiding_sampling_prob <= 1.0f);
165 if (phases->num_closure > 1) {
168 float sum = phases->closure[0].sample_weight;
170 for (
int i = 1;
i < phases->num_closure;
i++) {
171 const float sample_weight = phases->closure[
i].sample_weight;
172 sum += sample_weight;
173 const float thresh = sample_weight /
sum;
176 if (rand_phase->x < thresh) {
178 rand_phase->x /= thresh;
181 rand_phase->x = (rand_phase->x - thresh) / (1.0f - thresh);
186 return &phases->closure[sampled];
194 float sum_sample_weight)
196 for (
int i = 0;
i < phases->num_closure;
i++) {
198 float phase_pdf = 0.0f;
201 if (phase_pdf != 0.0f) {
203 sum_pdf += phase_pdf * svc->sample_weight;
206 sum_sample_weight += svc->sample_weight;
210 return (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
219 float phase_pdf = 0.0f;
222 if (phase_pdf != 0.0f) {
235 const uint light_shader_flags)
239 float pdf = _volume_shader_phase_eval_mis(sd, phases, wo, phase_eval, 0.0f, 0.0f);
241# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
242 if (
state->guiding.use_volume_guiding) {
243 const float guiding_sampling_prob =
state->guiding.volume_guiding_sampling_prob;
245 pdf = (guiding_sampling_prob * guide_pdf) + (1.0f - guiding_sampling_prob) * pdf;
258# ifdef __PATH_GUIDING__
270 const bool use_volume_guiding =
state->guiding.use_volume_guiding;
271 const float guiding_sampling_prob =
state->guiding.volume_guiding_sampling_prob;
274 float rand_phase_guiding =
state->guiding.sample_volume_guiding_rand;
275 bool sample_guiding =
false;
276 if (use_volume_guiding && rand_phase_guiding < guiding_sampling_prob) {
277 sample_guiding =
true;
278 rand_phase_guiding /= guiding_sampling_prob;
281 rand_phase_guiding -= guiding_sampling_prob;
282 rand_phase_guiding /= (1.0f - guiding_sampling_prob);
289 *unguided_phase_pdf = 0.0f;
290 float guide_pdf = 0.0f;
295 if (sample_guiding) {
300 if (guide_pdf != 0.0f) {
301 *unguided_phase_pdf = volume_shader_phase_eval(kg, sd, svc, *wo, phase_eval);
302 *phase_pdf = (guiding_sampling_prob * guide_pdf) +
303 ((1.0f - guiding_sampling_prob) * (*unguided_phase_pdf));
312 if (*unguided_phase_pdf != 0.0f) {
315 *phase_pdf = *unguided_phase_pdf;
316 if (use_volume_guiding) {
318 *phase_pdf *= 1.0f - guiding_sampling_prob;
319 *phase_pdf += guiding_sampling_prob * guide_pdf;
360# ifdef __OBJECT_MOTION__
372 const float velocity_scale =
kernel_data_fetch(objects, sd->object).velocity_scale;
411 float3 velocity = primitive_volume_attribute<float3>(kg, sd, v_desc);
415 sd->P =
P - (time - time_offset) * velocity_scale * velocity;
418 velocity = primitive_volume_attribute<float3>(kg, sd, v_desc);
422 sd->P =
P - (time - time_offset) * velocity_scale * velocity;
428template<const
bool shadow, const u
int node_feature_mask,
typename ConstIntegratorGenericState>
430 ConstIntegratorGenericState
state,
433 const uint32_t path_flag)
441 sd->object = entry.object;
442 sd->shader = entry.shader;
461# ifdef __OBJECT_MOTION__
466 volume_shader_motion_blur(kg, sd);
486template<const
bool shadow,
typename StackReadOp,
typename ConstIntegratorGenericState>
488 ConstIntegratorGenericState
state,
490 const uint32_t path_flag,
491 StackReadOp stack_read)
507 sd->num_closure_left = max_closures;
511 for (
int i = 0;;
i++) {
513 if (!volume_shader_eval_entry<shadow, KERNEL_FEATURE_NODE_MASK_VOLUME>(
514 kg,
state, sd, entry, path_flag))
523 volume_shader_merge_closures(sd);
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static T sum(const btAlignedObjectArray< T > &items)
void osl_eval_nodes< SHADER_TYPE_VOLUME >(const ThreadKernelGlobalsCPU *kg, const void *state, ShaderData *sd, const uint32_t path_flag)
#define kernel_assert(cond)
#define CLOSURE_IS_VOLUME_SCATTER(type)
#define MAX_VOLUME_CLOSURE
#define kernel_data_fetch(name, index)
#define KERNEL_FEATURE_OSL_SHADING
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device bool volume_phase_equal(const ccl_private ShaderClosure *c1, const ccl_private ShaderClosure *c2)
ccl_device Spectrum volume_phase_eval(const ccl_private ShaderData *sd, const ccl_private ShaderVolumeClosure *svc, const float3 wo, ccl_private float *pdf)
ccl_device float volume_phase_get_g(const ccl_private ShaderVolumeClosure *svc)
ccl_device int volume_phase_sample(const ccl_private ShaderData *sd, const ccl_private ShaderVolumeClosure *svc, const float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf)
ccl_device_inline void object_dir_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *D)
ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg, IntegratorState state, const float2 rand_phase, ccl_private float3 *wo)
ccl_device_forceinline float guiding_phase_pdf(KernelGlobals kg, IntegratorState state, const float3 wo)
ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg, IntegratorState state, const float3 P, const float3 D, const float g, ccl_private float &rand)
ccl_device void svm_eval_nodes(KernelGlobals kg, ConstIntegratorGenericState state, ccl_private ShaderData *sd, ccl_global float *render_buffer, const uint32_t path_flag)
@ SD_IS_VOLUME_SHADER_EVAL
@ ATTR_STD_VOLUME_VELOCITY
@ PATH_RAY_ALL_VISIBILITY
@ SD_OBJECT_HAS_VOLUME_MOTION
CCL_NAMESPACE_BEGIN ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval, const ccl_private ShaderClosure *sc, const float3 wo, Spectrum value)
ccl_device_inline void bsdf_eval_accum(ccl_private BsdfEval *eval, const ccl_private ShaderClosure *sc, const float3 wo, Spectrum value)
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, const float value)
ccl_device_inline Spectrum bsdf_eval_sum(const ccl_private BsdfEval *eval)
ccl_device_inline float reduce_min(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device void shader_setup_object_transforms(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float time)
IntegratorStateCPU * IntegratorState
static bool find_attribute(const std::string &attributes, const char *search_attribute)