23 typedef enum VolumeIntegrateEvent {
24 VOLUME_PATH_SCATTERED = 0,
25 VOLUME_PATH_ATTENUATED = 1,
26 VOLUME_PATH_MISSED = 2
27 } VolumeIntegrateEvent;
29 typedef struct VolumeIntegrateResult {
37 bool indirect_scatter;
38 float3 indirect_throughput;
41 } VolumeIntegrateResult;
47 # define VOLUME_THROUGHPUT_EPSILON 1e-6f
54 typedef struct VolumeShaderCoefficients {
58 } VolumeShaderCoefficients;
74 *extinction = sd->closure_transparent_extinction *
density;
86 shader_eval_volume<false>(kg,
state, sd, path_flag, volume_read_lambda_pass);
97 for (
int i = 0; i < sd->num_closure; i++) {
101 coeff->sigma_s += sc->weight;
116 const float object_step_size,
124 if (object_step_size == FLT_MAX) {
126 *step_size = tmax - tmin;
127 *step_shade_offset = 0.0f;
128 *steps_offset = 1.0f;
133 *max_steps =
kernel_data.integrator.volume_max_steps;
134 const float t = tmax - tmin;
135 float step =
min(object_step_size,
t);
138 if (
t > *max_steps * step) {
139 step =
t / (
float)*max_steps;
169 if (shadow_volume_shader_sample(kg,
state, sd, &sigma_t)) {
182 const float object_step_size)
195 float step_size, step_shade_offset, unused;
205 const float steps_offset = 1.0f;
212 for (
int i = 0; i < max_steps; i++) {
214 float new_t =
min(ray->tmax, ray->tmin + (i + steps_offset) * step_size);
215 float dt = new_t -
t;
217 float3 new_P = ray->P + ray->D * (
t + dt * step_shade_offset);
222 if (shadow_volume_shader_sample(kg,
state, sd, &sigma_t)) {
226 sum += (-sigma_t * dt);
227 if ((i & 0x07) == 0) {
228 tp = *throughput *
exp(
sum);
239 if (
t == ray->tmax) {
241 tp = *throughput *
exp(
sum);
256 # define VOLUME_SAMPLE_PDF_CUTOFF 1e-8f
263 const float tmin = ray->tmin;
264 const float tmax = ray->tmax;
265 const float delta =
dot((light_P - ray->P), ray->D);
271 const float theta_a =
atan2f(tmin - delta,
D);
272 const float theta_b =
atan2f(tmax - delta,
D);
273 const float t_ =
D *
tanf((xi * theta_b) + (1 - xi) * theta_a);
278 *pdf =
D / ((theta_b - theta_a) * (
D *
D + t_ * t_));
280 return clamp(delta + t_, tmin, tmax);
285 const float sample_t)
287 const float delta =
dot((light_P - ray->P), ray->D);
293 const float tmin = ray->tmin;
294 const float tmax = ray->tmax;
295 const float t_ = sample_t - delta;
297 const float theta_a =
atan2f(tmin - delta,
D);
298 const float theta_b =
atan2f(tmax - delta,
D);
303 const float pdf =
D / ((theta_b - theta_a) * (
D *
D + t_ * t_));
310 const float sample_t)
312 float delta =
dot((light_P - ray->P), ray->D);
318 const float tmin = ray->tmin;
319 const float tmax = ray->tmax;
320 const float t_ = sample_t - delta;
322 const float theta_a =
atan2f(tmin - delta,
D);
323 const float theta_b =
atan2f(tmax - delta,
D);
328 const float theta_sample =
atan2f(t_,
D);
329 const float cdf = (theta_sample - theta_a) / (theta_b - theta_a);
336 ccl_device float volume_distance_sample(
float max_t,
349 float sample_t =
min(max_t, -
logf(1.0f - xi * (1.0f - sample_transmittance)) / sample_sigma_t);
380 float3 emission = coeff->emission;
383 float3 sigma_t = coeff->sigma_t;
385 emission.
x *= (sigma_t.
x > 0.0f) ? (1.0f - transmittance.
x) / sigma_t.
x :
t;
386 emission.
y *= (sigma_t.
y > 0.0f) ? (1.0f - transmittance.
y) / sigma_t.
y :
t;
387 emission.
z *= (sigma_t.
z > 0.0f) ? (1.0f - transmittance.
z) / sigma_t.
z :
t;
397 typedef struct VolumeIntegrateState {
404 bool absorption_only;
414 float equiangular_pdf;
415 } VolumeIntegrateState;
420 const float3 equiangular_light_P,
422 const float3 transmittance,
431 albedo,
result.indirect_throughput, vstate.rphase, &channel_pdf);
435 if (
result.direct_t >= vstate.tmin &&
result.direct_t <= vstate.tmax &&
436 vstate.equiangular_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
437 const float new_dt =
result.direct_t - vstate.tmin;
440 result.direct_scatter =
true;
441 result.direct_throughput *= coeff.sigma_s * new_transmittance / vstate.equiangular_pdf;
442 shader_copy_volume_phases(&
result.direct_phases, sd);
445 if (vstate.use_mis) {
446 const float distance_pdf = vstate.distance_pdf *
447 dot(channel_pdf, coeff.sigma_t * new_transmittance);
448 const float mis_weight = 2.0f *
power_heuristic(vstate.equiangular_pdf, distance_pdf);
449 result.direct_throughput *= mis_weight;
453 result.direct_throughput *= transmittance;
454 vstate.distance_pdf *=
dot(channel_pdf, transmittance);
459 if (!
result.indirect_scatter) {
463 if (1.0f - vstate.rscatter >= sample_transmittance) {
466 const float new_dt = -
logf(1.0f - vstate.rscatter) / sample_sigma_t;
467 const float new_t = vstate.tmin + new_dt;
471 const float distance_pdf =
dot(channel_pdf, coeff.sigma_t * new_transmittance);
473 if (vstate.distance_pdf * distance_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
475 result.indirect_scatter =
true;
476 result.indirect_t = new_t;
477 result.indirect_throughput *= coeff.sigma_s * new_transmittance / distance_pdf;
478 shader_copy_volume_phases(&
result.indirect_phases, sd);
483 result.direct_scatter =
true;
486 shader_copy_volume_phases(&
result.direct_phases, sd);
489 if (vstate.use_mis) {
490 const float equiangular_pdf = volume_equiangular_pdf(ray, equiangular_light_P, new_t);
491 const float mis_weight =
power_heuristic(vstate.distance_pdf * distance_pdf,
493 result.direct_throughput *= 2.0f * mis_weight;
500 const float pdf =
dot(channel_pdf, transmittance);
501 result.indirect_throughput *= transmittance / pdf;
503 vstate.distance_pdf *= pdf;
507 vstate.rscatter = 1.0f - (1.0f - vstate.rscatter) / sample_transmittance;
523 const float object_step_size,
525 const float3 equiangular_light_P,
533 float step_size, step_shade_offset, steps_offset;
546 vstate.tmin = ray->tmin;
547 vstate.tmax = ray->tmin;
548 vstate.absorption_only =
true;
553 vstate.direct_sample_method = direct_sample_method;
555 if (vstate.use_mis) {
556 if (vstate.rscatter < 0.5f) {
557 vstate.rscatter *= 2.0f;
561 vstate.rscatter = (vstate.rscatter - 0.5f) * 2.0f;
565 vstate.equiangular_pdf = 0.0f;
566 vstate.distance_pdf = 1.0f;
570 result.direct_throughput = throughput;
571 result.indirect_throughput = throughput;
575 result.direct_t = volume_equiangular_sample(
576 ray, equiangular_light_P, vstate.rscatter, &vstate.equiangular_pdf);
579 # ifdef __DENOISING_FEATURES__
586 for (
int i = 0; i < max_steps; i++) {
588 vstate.tmax =
min(ray->tmax, ray->tmin + (i + steps_offset) * step_size);
589 const float shade_t = vstate.tmin + (vstate.tmax - vstate.tmin) * step_shade_offset;
590 sd->P = ray->P + ray->D * shade_t;
594 if (volume_shader_sample(kg,
state, sd, &coeff)) {
595 const int closure_flag = sd->flag;
598 const float dt = (vstate.tmax - vstate.tmin);
607 if (!
result.indirect_scatter) {
608 const float3 emission = volume_emission_integrate(
609 &coeff, closure_flag, transmittance, dt);
610 accum_emission +=
result.indirect_throughput * emission;
615 if ((closure_flag &
SD_SCATTER) || !vstate.absorption_only) {
616 # ifdef __DENOISING_FEATURES__
618 if (write_denoising_features && (closure_flag &
SD_SCATTER)) {
620 accum_albedo +=
result.indirect_throughput * albedo * (
one_float3() - transmittance);
625 volume_integrate_step_scattering(
626 sd, ray, equiangular_light_P, coeff, transmittance, vstate,
result);
630 result.indirect_throughput *= transmittance;
631 result.direct_throughput *= transmittance;
635 if (!
result.indirect_scatter) {
641 else if (!
result.direct_scatter) {
655 vstate.tmin = vstate.tmax;
656 if (vstate.tmin == ray->tmax) {
662 if (!
is_zero(accum_emission)) {
667 # ifdef __DENOISING_FEATURES__
669 if (write_denoising_features) {
670 kernel_write_denoising_features_volume(
694 float light_u, light_v;
698 kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls)) {
735 float light_u, light_v;
739 kg, light_u, light_v, sd->time,
P, bounce, path_flag, ls)) {
763 const float phase_pdf = shader_volume_phase_eval(kg, sd, phases, ls->D, &phase_eval);
824 state, path, rng_offset);
826 state, path, rng_hash);
833 state, path, diffuse_bounce);
835 state, path, glossy_bounce);
837 state, path, transmission_bounce);
864 float phase_u, phase_v;
873 const int label = shader_volume_phase_sample(kg,
892 # ifdef __RAY_DIFFERENTIALS__
929 shader_setup_from_volume(kg, &sd, ray);
939 const bool have_equiangular_sample = need_light_sample &&
940 integrate_volume_sample_light(
941 kg,
state, &sd, &rng_state, &ls) &&
953 VolumeIntegrateResult
result = {};
954 volume_integrate_heterogeneous(kg,
961 direct_sample_method,
972 if (probability == 0.0f) {
973 return VOLUME_PATH_MISSED;
977 if (
result.direct_scatter) {
978 const float3 direct_P = ray->P +
result.direct_t * ray->D;
979 result.direct_throughput /= probability;
980 integrate_volume_direct_light(kg,
994 if (
result.indirect_scatter) {
995 result.indirect_throughput /= probability;
999 if (
result.indirect_scatter) {
1000 sd.P = ray->P +
result.indirect_t * ray->D;
1002 if (integrate_volume_phase_scatter(kg,
state, &sd, &rng_state, &
result.indirect_phases)) {
1003 return VOLUME_PATH_SCATTERED;
1006 return VOLUME_PATH_MISSED;
1010 return VOLUME_PATH_ATTENUATED;
1031 ray.tmax = (isect.prim !=
PRIM_NONE) ? isect.t : FLT_MAX;
1040 if (event == VOLUME_PATH_SCATTERED) {
1048 else if (event == VOLUME_PATH_MISSED) {
1055 integrator_intersect_next_kernel_after_volume<DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME>(
typedef float(TangentPoint)[2]
MINLINE float safe_sqrtf(float a)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value)
ccl_device_inline bool bsdf_eval_is_zero(ccl_private BsdfEval *eval)
ccl_device_inline void kernel_accum_emission(KernelGlobals kg, ConstIntegratorState state, const float3 L, ccl_global float *ccl_restrict render_buffer, const int lightgroup=LIGHTGROUP_NONE)
ccl_device_inline float3 bsdf_eval_sum(ccl_private const BsdfEval *eval)
__forceinline int reduce_max(const avxi &v)
static T sum(const btAlignedObjectArray< T > &items)
#define ccl_device_forceinline
#define ccl_optional_struct_init
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg, const float nee_pdf, const float forward_pdf)
CCL_NAMESPACE_BEGIN ccl_device_noinline_cpu float3 light_sample_shader_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *ccl_restrict emission_sd, ccl_private LightSample *ccl_restrict ls, float time)
ccl_device_inline void light_sample_to_volume_shadow_ray(KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, ccl_private const LightSample *ccl_restrict ls, const float3 P, ccl_private Ray *ray)
ccl_device_inline bool light_sample_is_light(ccl_private const LightSample *ccl_restrict ls)
ccl_device_inline bool light_sample_terminate(KernelGlobals kg, ccl_private const LightSample *ccl_restrict ls, ccl_private BsdfEval *ccl_restrict eval, const float rand_terminate)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_device_forceinline float differential_make_compact(const differential3 D)
#define VOLUME_THROUGHPUT_EPSILON
ccl_device float3 volume_color_transmittance(float3 sigma, float t)
ccl_device float volume_channel_get(float3 value, int channel)
ccl_device int volume_sample_channel(float3 albedo, float3 throughput, float rand, ccl_private float3 *pdf)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const uint64_t render_pixel_index
ccl_device_inline float object_volume_density(KernelGlobals kg, int object)
ccl_device_inline int object_lightgroup(KernelGlobals kg, int object)
ccl_device_inline bool light_distribution_sample_from_volume_segment(KernelGlobals kg, float randu, const float randv, const float time, const float3 P, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
ccl_device_inline bool light_distribution_sample_from_position(KernelGlobals kg, float randu, const float randv, const float time, const float3 P, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
#define CLOSURE_IS_VOLUME(type)
#define AS_SHADER_DATA(shader_data_tiny_storage)
@ PATH_RAY_TERMINATE_IN_NEXT_VOLUME
@ PATH_RAY_DENOISING_FEATURES
@ PATH_RAY_SHADOW_FOR_LIGHT
@ KERNEL_FEATURE_LIGHT_PASSES
@ KERNEL_FEATURE_SHADOW_PASS
@ DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST
#define PROFILING_INIT(kg, event)
ccl_device_inline float3 one_float3()
ccl_device_inline float3 exp(float3 v)
ccl_device_inline float3 zero_float3()
ccl_device_inline float len_squared(const float3 a)
ccl_device float power_heuristic(float a, float b)
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T clamp(const T &a, const T &min, const T &max)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)
ccl_device_inline void shadow_path_state_rng_load(ConstIntegratorShadowState state, ccl_private RNGState *rng_state)
ccl_device_inline float path_state_rng_1D(KernelGlobals kg, ccl_private const RNGState *rng_state, int dimension)
ccl_device_inline float path_state_rng_light_termination(KernelGlobals kg, ccl_private const RNGState *state)
ccl_device_inline float path_state_rng_1D_hash(KernelGlobals kg, ccl_private const RNGState *rng_state, uint hash)
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, int label)
ccl_device_inline void path_state_rng_2D(KernelGlobals kg, ccl_private const RNGState *rng_state, int dimension, ccl_private float *fx, ccl_private float *fy)
CCL_NAMESPACE_BEGIN ccl_device void integrator_shade_volume(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
#define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member)
IntegratorStateCPU *ccl_restrict IntegratorState
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
#define INTEGRATOR_STATE(state, nested_struct, member)
IntegratorShadowStateCPU *ccl_restrict IntegratorShadowState
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel)
ccl_device_forceinline void integrator_path_next(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel)
ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const bool is_ao)
ccl_device_forceinline VolumeStack integrator_state_read_volume_stack(ConstIntegratorState state, int i)
ccl_device_forceinline void integrator_state_read_ray(KernelGlobals kg, ConstIntegratorState state, ccl_private Ray *ccl_restrict ray)
ccl_device_forceinline VolumeStack integrator_state_read_shadow_volume_stack(ConstIntegratorShadowState state, int i)
ccl_device_forceinline void integrator_state_read_isect(KernelGlobals kg, ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
ccl_device_forceinline void integrator_state_write_shadow_ray(KernelGlobals kg, IntegratorShadowState state, ccl_private const Ray *ccl_restrict ray)
ccl_device_forceinline void integrator_state_copy_volume_stack_to_shadow(KernelGlobals kg, IntegratorShadowState shadow_state, ConstIntegratorState state)
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
@ PROFILING_SHADE_VOLUME_INTEGRATE
@ PROFILING_SHADE_VOLUME_SETUP
@ PROFILING_SHADE_VOLUME_DIRECT_LIGHT
@ PROFILING_SHADE_VOLUME_INDIRECT_LIGHT
ccl_device VolumeSampleMethod volume_stack_sample_method(KernelGlobals kg, IntegratorState state)
ccl_device_inline void volume_stack_clean(KernelGlobals kg, IntegratorState state)
@ VOLUME_SAMPLE_EQUIANGULAR
ccl_device float volume_stack_step_size(KernelGlobals kg, StackReadOp stack_read)
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)