Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/shade_volume.h
| Show First 20 Lines • Show All 253 Lines • ▼ Show 20 Lines | ccl_device void volume_shadow_heterogeneous(KernelGlobals kg, | ||||
| } | } | ||||
| *throughput = tp; | *throughput = tp; | ||||
| } | } | ||||
| /* Equi-angular sampling as in: | /* Equi-angular sampling as in: | ||||
| * "Importance Sampling Techniques for Path Tracing in Participating Media" */ | * "Importance Sampling Techniques for Path Tracing in Participating Media" */ | ||||
| /* Below this pdf we ignore samples, as they tend to lead to very long distances. | |||||
| * This can cause performance issues with BVH traversal in OptiX, leading it to | |||||
| * traverse many nodes. Since these contribute very little to the image, just ignore | |||||
| * those samples. */ | |||||
| # define VOLUME_SAMPLE_PDF_CUTOFF 1e-8f | |||||
| ccl_device float volume_equiangular_sample(ccl_private const Ray *ccl_restrict ray, | ccl_device float volume_equiangular_sample(ccl_private const Ray *ccl_restrict ray, | ||||
| const float3 light_P, | const float3 light_P, | ||||
| const float xi, | const float xi, | ||||
| ccl_private float *pdf) | ccl_private float *pdf) | ||||
| { | { | ||||
| const float t = ray->t; | const float t = ray->t; | ||||
| const float delta = dot((light_P - ray->P), ray->D); | const float delta = dot((light_P - ray->P), ray->D); | ||||
| const float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta); | const float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta); | ||||
| ▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | ccl_device_forceinline void volume_integrate_step_scattering( | ||||
| * model with balance heuristic for the channels. */ | * model with balance heuristic for the channels. */ | ||||
| const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t); | const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t); | ||||
| float3 channel_pdf; | float3 channel_pdf; | ||||
| const int channel = volume_sample_channel( | const int channel = volume_sample_channel( | ||||
| albedo, result.indirect_throughput, vstate.rphase, &channel_pdf); | albedo, result.indirect_throughput, vstate.rphase, &channel_pdf); | ||||
| /* Equiangular sampling for direct lighting. */ | /* Equiangular sampling for direct lighting. */ | ||||
| if (vstate.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR && !result.direct_scatter) { | if (vstate.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR && !result.direct_scatter) { | ||||
| if (result.direct_t >= vstate.start_t && result.direct_t <= vstate.end_t) { | if (result.direct_t >= vstate.start_t && result.direct_t <= vstate.end_t && | ||||
| vstate.equiangular_pdf > VOLUME_SAMPLE_PDF_CUTOFF) { | |||||
| const float new_dt = result.direct_t - vstate.start_t; | const float new_dt = result.direct_t - vstate.start_t; | ||||
| const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); | const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); | ||||
| result.direct_scatter = true; | result.direct_scatter = true; | ||||
| result.direct_throughput *= coeff.sigma_s * new_transmittance / vstate.equiangular_pdf; | result.direct_throughput *= coeff.sigma_s * new_transmittance / vstate.equiangular_pdf; | ||||
| shader_copy_volume_phases(&result.direct_phases, sd); | shader_copy_volume_phases(&result.direct_phases, sd); | ||||
| /* Multiple importance sampling. */ | /* Multiple importance sampling. */ | ||||
| Show All 20 Lines | if (1.0f - vstate.rscatter >= sample_transmittance) { | ||||
| const float sample_sigma_t = volume_channel_get(coeff.sigma_t, channel); | const float sample_sigma_t = volume_channel_get(coeff.sigma_t, channel); | ||||
| const float new_dt = -logf(1.0f - vstate.rscatter) / sample_sigma_t; | const float new_dt = -logf(1.0f - vstate.rscatter) / sample_sigma_t; | ||||
| const float new_t = vstate.start_t + new_dt; | const float new_t = vstate.start_t + new_dt; | ||||
| /* transmittance and pdf */ | /* transmittance and pdf */ | ||||
| const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); | const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); | ||||
| const float distance_pdf = dot(channel_pdf, coeff.sigma_t * new_transmittance); | const float distance_pdf = dot(channel_pdf, coeff.sigma_t * new_transmittance); | ||||
| if (vstate.distance_pdf * distance_pdf > VOLUME_SAMPLE_PDF_CUTOFF) { | |||||
| /* throughput */ | /* throughput */ | ||||
| result.indirect_scatter = true; | result.indirect_scatter = true; | ||||
| result.indirect_t = new_t; | result.indirect_t = new_t; | ||||
| result.indirect_throughput *= coeff.sigma_s * new_transmittance / distance_pdf; | result.indirect_throughput *= coeff.sigma_s * new_transmittance / distance_pdf; | ||||
| shader_copy_volume_phases(&result.indirect_phases, sd); | shader_copy_volume_phases(&result.indirect_phases, sd); | ||||
| if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) { | if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) { | ||||
| /* If using distance sampling for direct light, just copy parameters | /* If using distance sampling for direct light, just copy parameters | ||||
| * of indirect light since we scatter at the same point then. */ | * of indirect light since we scatter at the same point then. */ | ||||
| result.direct_scatter = true; | result.direct_scatter = true; | ||||
| result.direct_t = result.indirect_t; | result.direct_t = result.indirect_t; | ||||
| result.direct_throughput = result.indirect_throughput; | result.direct_throughput = result.indirect_throughput; | ||||
| shader_copy_volume_phases(&result.direct_phases, sd); | shader_copy_volume_phases(&result.direct_phases, sd); | ||||
| /* Multiple importance sampling. */ | /* Multiple importance sampling. */ | ||||
| if (vstate.use_mis) { | if (vstate.use_mis) { | ||||
| const float equiangular_pdf = volume_equiangular_pdf(ray, equiangular_light_P, new_t); | const float equiangular_pdf = volume_equiangular_pdf(ray, equiangular_light_P, new_t); | ||||
| const float mis_weight = power_heuristic(vstate.distance_pdf * distance_pdf, | const float mis_weight = power_heuristic(vstate.distance_pdf * distance_pdf, | ||||
| equiangular_pdf); | equiangular_pdf); | ||||
| result.direct_throughput *= 2.0f * mis_weight; | result.direct_throughput *= 2.0f * mis_weight; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| else { | else { | ||||
| /* throughput */ | /* throughput */ | ||||
| const float pdf = dot(channel_pdf, transmittance); | const float pdf = dot(channel_pdf, transmittance); | ||||
| result.indirect_throughput *= transmittance / pdf; | result.indirect_throughput *= transmittance / pdf; | ||||
| if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) { | if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) { | ||||
| vstate.distance_pdf *= pdf; | vstate.distance_pdf *= pdf; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | ccl_device_forceinline bool integrate_volume_sample_light( | ||||
| } | } | ||||
| /* Sample position on a light. */ | /* Sample position on a light. */ | ||||
| const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); | const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); | ||||
| const uint bounce = INTEGRATOR_STATE(state, path, bounce); | const uint bounce = INTEGRATOR_STATE(state, path, bounce); | ||||
| float light_u, light_v; | float light_u, light_v; | ||||
| path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v); | path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v); | ||||
| light_distribution_sample_from_volume_segment( | if (!light_distribution_sample_from_volume_segment( | ||||
| kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls); | kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls)) { | ||||
| return false; | |||||
| } | |||||
| if (ls->shader & SHADER_EXCLUDE_SCATTER) { | if (ls->shader & SHADER_EXCLUDE_SCATTER) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 330 Lines • Show Last 20 Lines | |||||