Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_volume.h
| Show First 20 Lines • Show All 625 Lines • ▼ Show 20 Lines | if(heterogeneous) { | ||||
| const int global_max_steps = kernel_data.integrator.volume_max_steps; | const int global_max_steps = kernel_data.integrator.volume_max_steps; | ||||
| step_size = kernel_data.integrator.volume_step_size; | step_size = kernel_data.integrator.volume_step_size; | ||||
| /* compute exact steps in advance for malloc */ | /* compute exact steps in advance for malloc */ | ||||
| max_steps = max((int)ceilf(ray->t/step_size), 1); | max_steps = max((int)ceilf(ray->t/step_size), 1); | ||||
| if(max_steps > global_max_steps) { | if(max_steps > global_max_steps) { | ||||
| max_steps = global_max_steps; | max_steps = global_max_steps; | ||||
| step_size = ray->t / (float)max_steps; | step_size = ray->t / (float)max_steps; | ||||
| } | } | ||||
| segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps); | if(kg->decoupled_volume_steps == NULL) { | ||||
| kg->decoupled_volume_steps = | |||||
| (VolumeStep*)malloc(sizeof(VolumeStep)*global_max_steps); | |||||
| } | |||||
| segment->steps = kg->decoupled_volume_steps; | |||||
brecht: In this case `global_max_steps` is fixed, so that should be ok.
For branched path tracing… | |||||
sergeyAuthorUnsubmitted Not Done Inline ActionsWill do. sergey: Will do. | |||||
brechtUnsubmitted Not Done Inline ActionsActually I think it will be a problem with branched path tracing. In kernel_path_indirect it deallocates the array before doing the volume bounce, but you still use the array from the first and second bounces at the same time. It's just limited to 2 at the same time max. brecht: Actually I think it will be a problem with branched path tracing. In `kernel_path_indirect` it… | |||||
sergeyAuthorUnsubmitted Not Done Inline ActionsWill need to have a closer look (hopefully tomorrow, not entirely sure what's exact first and second bounce you're refferring to. But if it's just two bounces to keep at a time we can store two pointers and bitmask of some sort to see what arrays are free. Should still be cheaper than doing alloc/free for each of integrations. Gimme some time to go over the corners in details tho.. sergey: Will need to have a closer look (hopefully tomorrow, not entirely sure what's exact first and… | |||||
| random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size; | random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size; | ||||
| } | } | ||||
| else { | else { | ||||
| max_steps = 1; | max_steps = 1; | ||||
| step_size = ray->t; | step_size = ray->t; | ||||
| random_jitter_offset = 0.0f; | random_jitter_offset = 0.0f; | ||||
| segment->steps = &segment->stack_step; | segment->steps = &segment->stack_step; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if(!is_zero(last_step->cdf_distance)) { | ||||
| int numsteps = segment->numsteps; | int numsteps = segment->numsteps; | ||||
| float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance); | float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance); | ||||
| for(int i = 0; i < numsteps; i++, step++) | for(int i = 0; i < numsteps; i++, step++) | ||||
| step->cdf_distance *= inv_cdf_distance_sum; | step->cdf_distance *= inv_cdf_distance_sum; | ||||
| } | } | ||||
| } | } | ||||
| ccl_device void kernel_volume_decoupled_free(KernelGlobals *kg, VolumeSegment *segment) | |||||
| { | |||||
| if(segment->steps != &segment->stack_step) | |||||
| free(segment->steps); | |||||
| } | |||||
| /* scattering for homogeneous and heterogeneous volumes, using decoupled ray | /* scattering for homogeneous and heterogeneous volumes, using decoupled ray | ||||
| * marching. | * marching. | ||||
| * | * | ||||
| * function is expected to return VOLUME_PATH_SCATTERED when probalistic_scatter is false */ | * function is expected to return VOLUME_PATH_SCATTERED when probalistic_scatter is false */ | ||||
| ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( | ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( | ||||
| KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd, | KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd, | ||||
| float3 *throughput, float rphase, float rscatter, | float3 *throughput, float rphase, float rscatter, | ||||
| const VolumeSegment *segment, const float3 *light_P, bool probalistic_scatter) | const VolumeSegment *segment, const float3 *light_P, bool probalistic_scatter) | ||||
| ▲ Show 20 Lines • Show All 450 Lines • Show Last 20 Lines | |||||
In this case global_max_steps is fixed, so that should be ok.
For branched path tracing, this relies on the fact that kernel_path_indirect does not use decoupled shading, so we never need two such arrays in memory at once. That's fine, but might be good to add a comment about that.