Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/shade_volume.h
| Show First 20 Lines • Show All 684 Lines • ▼ Show 20 Lines | |||||
| # endif /* __DENOISING_FEATURES__ */ | # endif /* __DENOISING_FEATURES__ */ | ||||
| } | } | ||||
| /* Path tracing: sample point on light and evaluate light shader, then | /* Path tracing: sample point on light and evaluate light shader, then | ||||
| * queue shadow ray to be traced. */ | * queue shadow ray to be traced. */ | ||||
| ccl_device_forceinline bool integrate_volume_sample_light( | ccl_device_forceinline bool integrate_volume_sample_light( | ||||
| KernelGlobals kg, | KernelGlobals kg, | ||||
| IntegratorState state, | IntegratorState state, | ||||
| ccl_private const Ray *ccl_restrict ray, | |||||
| ccl_private const ShaderData *ccl_restrict sd, | ccl_private const ShaderData *ccl_restrict sd, | ||||
| ccl_private const RNGState *ccl_restrict rng_state, | ccl_private const RNGState *ccl_restrict rng_state, | ||||
| ccl_private LightSample *ccl_restrict ls) | ccl_private LightSample *ccl_restrict ls) | ||||
| { | { | ||||
| /* Test if there is a light or BSDF that needs direct light. */ | /* Test if there is a light or BSDF that needs direct light. */ | ||||
| if (!kernel_data.integrator.use_direct_light) { | if (!kernel_data.integrator.use_direct_light) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* 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); | ||||
| const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); | const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); | ||||
| if (!light_distribution_sample_from_volume_segment( | if (!light_sample_from_volume_segment(kg, | ||||
| kg, rand_light.x, rand_light.y, sd->time, sd->P, bounce, path_flag, ls)) { | rand_light.x, | ||||
| rand_light.y, | |||||
| sd->time, | |||||
| sd->P, | |||||
| ray->D, | |||||
| ray->tmax - ray->tmin, | |||||
| bounce, | |||||
| path_flag, | |||||
| ls)) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| if (ls->shader & SHADER_EXCLUDE_SCATTER) { | if (ls->shader & SHADER_EXCLUDE_SCATTER) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| Show All 15 Lines | # endif | ||||
| ccl_private LightSample *ccl_restrict ls) | ccl_private LightSample *ccl_restrict ls) | ||||
| { | { | ||||
| PROFILING_INIT(kg, PROFILING_SHADE_VOLUME_DIRECT_LIGHT); | PROFILING_INIT(kg, PROFILING_SHADE_VOLUME_DIRECT_LIGHT); | ||||
| if (!kernel_data.integrator.use_direct_light) { | if (!kernel_data.integrator.use_direct_light) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Sample position on the same light again, now from the shading | /* Sample position on the same light again, now from the shading point where we scattered. | ||||
| * point where we scattered. | |||||
| * | * | ||||
| * TODO: decorrelate random numbers and use light_sample_new_position to | * Note that this means we sample the light tree twice when equiangular sampling is used. | ||||
| * avoid resampling the CDF. */ | * We could consider sampling the light tree just once and use the same light position again. | ||||
| * | |||||
| * This would make the PDFs for MIS weights more complicated due to having to account for | |||||
| * both distance/equiangular and direct/indirect light sampling, but could be more accurate. | |||||
| * Additionally we could end up behind the light or outside a spot light cone, which might | |||||
| * waste a sample. Though on the other hand it would be possible to prevent that with | |||||
| * equiangular sampling restricted to a smaller sub-segment where the light has influence. */ | |||||
| { | { | ||||
| 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); | ||||
| const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); | const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); | ||||
| if (!light_distribution_sample_from_position( | if (!light_sample_from_position(kg, | ||||
| kg, rand_light.x, rand_light.y, sd->time, P, bounce, path_flag, ls)) { | rng_state, | ||||
| rand_light.x, | |||||
| rand_light.y, | |||||
| sd->time, | |||||
| P, | |||||
| zero_float3(), | |||||
| SD_BSDF_HAS_TRANSMISSION, | |||||
| bounce, | |||||
| path_flag, | |||||
| ls)) { | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| if (ls->shader & SHADER_EXCLUDE_SCATTER) { | if (ls->shader & SHADER_EXCLUDE_SCATTER) { | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { | ||||
| INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum(); | INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum(); | ||||
| } | } | ||||
| /* Update path state */ | /* Update path state */ | ||||
| INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = phase_pdf; | INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = phase_pdf; | ||||
| INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf( | INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf( | ||||
| unguided_phase_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf)); | unguided_phase_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf)); | ||||
| path_state_next(kg, state, label); | path_state_next(kg, state, label, sd->flag); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* get the volume attenuation and emission over line segment defined by | /* get the volume attenuation and emission over line segment defined by | ||||
| * ray, with the assumption that there are no surfaces blocking light | * ray, with the assumption that there are no surfaces blocking light | ||||
| * between the endpoints. distance sampling is used to decide if we will | * between the endpoints. distance sampling is used to decide if we will | ||||
| * scatter or not. */ | * scatter or not. */ | ||||
| ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg, | ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg, | ||||
| Show All 9 Lines | ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg, | ||||
| path_state_rng_load(state, &rng_state); | path_state_rng_load(state, &rng_state); | ||||
| /* Sample light ahead of volume stepping, for equiangular sampling. */ | /* Sample light ahead of volume stepping, for equiangular sampling. */ | ||||
| /* TODO: distant lights are ignored now, but could instead use even distribution. */ | /* TODO: distant lights are ignored now, but could instead use even distribution. */ | ||||
| LightSample ls ccl_optional_struct_init; | LightSample ls ccl_optional_struct_init; | ||||
| const bool need_light_sample = !(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_TERMINATE); | const bool need_light_sample = !(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_TERMINATE); | ||||
| const bool have_equiangular_sample = need_light_sample && | const bool have_equiangular_sample = need_light_sample && | ||||
| integrate_volume_sample_light( | integrate_volume_sample_light( | ||||
| kg, state, &sd, &rng_state, &ls) && | kg, state, ray, &sd, &rng_state, &ls) && | ||||
| (ls.t != FLT_MAX); | (ls.t != FLT_MAX); | ||||
| VolumeSampleMethod direct_sample_method = (have_equiangular_sample) ? | VolumeSampleMethod direct_sample_method = (have_equiangular_sample) ? | ||||
| volume_stack_sample_method(kg, state) : | volume_stack_sample_method(kg, state) : | ||||
| VOLUME_SAMPLE_DISTANCE; | VOLUME_SAMPLE_DISTANCE; | ||||
| /* Step through volume. */ | /* Step through volume. */ | ||||
| VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i)) | VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i)) | ||||
| ▲ Show 20 Lines • Show All 194 Lines • Show Last 20 Lines | |||||