23 #define VOLUME_THROUGHPUT_EPSILON 1e-6f
58 *extinction = sd->closure_transparent_extinction * density;
84 for (
int i = 0; i < sd->num_closure; i++) {
104 return exp3(-sigma *
t);
109 return (channel == 0) ? value.
x : ((channel == 1) ? value.
y : value.
z);
116 float step_size = FLT_MAX;
118 for (
int i = 0; stack[i].shader !=
SHADER_NONE; i++) {
121 bool heterogeneous =
false;
124 heterogeneous =
true;
130 int object = stack[i].object;
134 heterogeneous =
true;
141 object_step_size *=
kernel_data.integrator.volume_step_rate;
142 step_size =
fminf(object_step_size, step_size);
181 const float object_step_size,
184 float *step_shade_offset,
187 const int max_steps =
kernel_data.integrator.volume_max_steps;
188 float step =
min(object_step_size,
t);
191 if (
t > max_steps * step) {
192 step =
t / (
float)max_steps;
213 ccl_device void kernel_volume_shadow_homogeneous(KernelGlobals *
kg,
221 if (volume_shader_extinction_sample(
kg, sd,
state, ray->
P, &sigma_t))
227 ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *
kg,
232 const float object_step_size)
240 int max_steps =
kernel_data.integrator.volume_max_steps;
241 float step_size, step_shade_offset, unused;
242 kernel_volume_step_init(
243 kg,
state, object_step_size, ray->
t, &step_size, &step_shade_offset, &unused);
244 const float steps_offset = 1.0f;
251 for (
int i = 0; i < max_steps; i++) {
253 float new_t =
min(ray->
t, (i + steps_offset) * step_size);
254 float dt = new_t -
t;
256 float3 new_P = ray->
P + ray->
D * (
t + dt * step_shade_offset);
260 if (volume_shader_extinction_sample(
kg, sd,
state, new_P, &sigma_t)) {
264 sum += (-sigma_t * dt);
265 if ((i & 0x07) == 0) {
289 # if defined(__KERNEL_OPTIX__) && defined(__SHADER_RAYTRACE__)
296 optixDirectCall<void>(1,
kg, shadow_sd,
state, ray, throughput);
298 extern "C" __device__
void __direct_callable__kernel_volume_shadow(
308 shader_setup_from_volume(
kg, shadow_sd, ray);
310 float step_size = volume_stack_step_size(
kg,
state->volume_stack);
311 if (step_size != FLT_MAX)
312 kernel_volume_shadow_heterogeneous(
kg,
state, ray, shadow_sd, throughput, step_size);
314 kernel_volume_shadow_homogeneous(
kg,
state, ray, shadow_sd, throughput);
326 float delta =
dot((light_P - ray->
P), ray->
D);
332 float theta_a = -
atan2f(delta,
D);
333 float theta_b =
atan2f(
t - delta,
D);
334 float t_ =
D *
tanf((xi * theta_b) + (1 - xi) * theta_a);
339 *pdf =
D / ((theta_b - theta_a) * (
D *
D + t_ * t_));
341 return min(
t, delta + t_);
346 float delta =
dot((light_P - ray->
P), ray->
D);
353 float t_ = sample_t - delta;
355 float theta_a = -
atan2f(delta,
D);
356 float theta_b =
atan2f(
t - delta,
D);
361 float pdf =
D / ((theta_b - theta_a) * (
D *
D + t_ * t_));
369 float max_t,
float3 sigma_t,
int channel,
float xi,
float3 *transmittance,
float3 *pdf)
377 float sample_t =
min(max_t, -
logf(1.0f - xi * (1.0f - sample_transmittance)) / sample_sigma_t);
413 emission.
x *= (sigma_t.
x > 0.0f) ? (1.0f - transmittance.
x) / sigma_t.
x :
t;
414 emission.
y *= (sigma_t.
y > 0.0f) ? (1.0f - transmittance.
y) / sigma_t.
y :
t;
415 emission.
z *= (sigma_t.
z > 0.0f) ? (1.0f - transmittance.
z) / sigma_t.
z :
t;
436 float sum_weights = weights.
x + weights.
y + weights.
z;
439 if (sum_weights > 0.0f) {
440 weights_pdf = weights / sum_weights;
443 weights_pdf =
make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
449 if (rand < weights_pdf.
x) {
452 else if (rand < weights_pdf.
x + weights_pdf.
y) {
465 kernel_volume_integrate_homogeneous(KernelGlobals *
kg,
471 bool probalistic_scatter)
475 if (!volume_shader_sample(
kg, sd,
state, ray->
P, &coeff))
478 int closure_flag = sd->flag;
482 # ifdef __VOLUME_SCATTER__
495 if (probalistic_scatter) {
497 float sample_transmittance =
expf(-sample_sigma_t *
t);
499 if (1.0f - xi >= sample_transmittance) {
503 xi = 1.0f - (1.0f - xi - sample_transmittance) / (1.0f - sample_transmittance);
517 ray->
t, coeff.
sigma_t, channel, xi, &transmittance, &pdf);
520 if (probalistic_scatter)
523 new_tp = *throughput * coeff.
sigma_s * transmittance /
dot(channel_pdf, pdf);
529 float pdf =
dot(channel_pdf, transmittance);
530 new_tp = *throughput * transmittance / pdf;
538 new_tp = *throughput * transmittance;
541 new_tp = *throughput;
548 &coeff, closure_flag, transmittance, ray->
t);
554 *throughput = new_tp;
559 sd->P = ray->
P +
t * ray->
D;
573 kernel_volume_integrate_heterogeneous_distance(KernelGlobals *
kg,
579 const float object_step_size)
585 int max_steps =
kernel_data.integrator.volume_max_steps;
586 float step_size, step_shade_offset, steps_offset;
587 kernel_volume_step_init(
588 kg,
state, object_step_size, ray->
t, &step_size, &step_shade_offset, &steps_offset);
598 bool has_scatter =
false;
600 for (
int i = 0; i < max_steps; i++) {
602 float new_t =
min(ray->
t, (i + steps_offset) * step_size);
603 float dt = new_t -
t;
605 float3 new_P = ray->
P + ray->
D * (
t + dt * step_shade_offset);
609 if (volume_shader_sample(
kg, sd,
state, new_P, &coeff)) {
610 int closure_flag = sd->flag;
613 bool scatter =
false;
616 # ifdef __VOLUME_SCATTER__
631 if (1.0f - xi >= sample_transmittance) {
634 float new_dt = -
logf(1.0f - xi) / sample_sigma_t;
642 new_tp = tp * coeff.
sigma_s * new_transmittance /
dot(channel_pdf, pdf);
647 float pdf =
dot(channel_pdf, transmittance);
648 new_tp = tp * transmittance / pdf;
651 xi = 1.0f - (1.0f - xi) / sample_transmittance;
659 new_tp = tp * transmittance;
669 &coeff, closure_flag, transmittance, dt);
688 sd->P = ray->
P + new_t * ray->
D;
695 accum_transmittance *= transmittance;
715 kernel_volume_integrate(KernelGlobals *
kg,
723 shader_setup_from_volume(
kg, sd, ray);
725 if (step_size != FLT_MAX)
726 return kernel_volume_integrate_heterogeneous_distance(
727 kg,
state, ray, sd,
L, throughput, step_size);
729 return kernel_volume_integrate_homogeneous(
kg,
state, ray, sd,
L, throughput,
true);
732 # ifndef __SPLIT_KERNEL__
743 typedef struct VolumeStep {
746 float3 accum_transmittance;
753 typedef struct VolumeSegment {
754 VolumeStep stack_step;
760 float3 accum_transmittance;
772 # ifdef __VOLUME_DECOUPLED__
773 ccl_device void kernel_volume_decoupled_record(KernelGlobals *
kg,
778 const float object_step_size)
782 float step_size, step_shade_offset, steps_offset;
784 if (object_step_size != FLT_MAX) {
785 max_steps =
kernel_data.integrator.volume_max_steps;
786 kernel_volume_step_init(
787 kg,
state, object_step_size, ray->
t, &step_size, &step_shade_offset, &steps_offset);
789 # ifdef __KERNEL_CPU__
800 const int index =
kg->decoupled_volume_steps_index;
801 assert(index <
sizeof(
kg->decoupled_volume_steps) /
sizeof(*
kg->decoupled_volume_steps));
802 if (
kg->decoupled_volume_steps[index] ==
NULL) {
803 kg->decoupled_volume_steps[index] = (VolumeStep *)malloc(
sizeof(VolumeStep) * max_steps);
805 segment->steps =
kg->decoupled_volume_steps[index];
806 ++
kg->decoupled_volume_steps_index;
808 segment->steps = (VolumeStep *)malloc(
sizeof(VolumeStep) * max_steps);
814 step_shade_offset = 0.0f;
828 bool is_last_step_empty =
false;
830 VolumeStep *step =
segment->steps;
832 for (
int i = 0; i < max_steps; i++, step++) {
834 float new_t =
min(ray->
t, (i + steps_offset) * step_size);
835 float dt = new_t -
t;
837 float3 new_P = ray->
P + ray->
D * (
t + dt * step_shade_offset);
841 if (volume_shader_sample(
kg, sd,
state, new_P, &coeff)) {
842 int closure_flag = sd->flag;
856 &coeff, closure_flag, transmittance, dt);
857 accum_emission += accum_transmittance * emission;
860 accum_transmittance *= transmittance;
863 float3 pdf_distance = dt * accum_transmittance * coeff.
sigma_s;
864 cdf_distance = cdf_distance + pdf_distance;
867 step->sigma_t = sigma_t;
869 step->closure_flag = closure_flag;
871 segment->closure_flag |= closure_flag;
873 is_last_step_empty =
false;
877 if (is_last_step_empty) {
885 step->closure_flag = 0;
888 is_last_step_empty =
true;
892 step->accum_transmittance = accum_transmittance;
893 step->cdf_distance = cdf_distance;
895 step->shade_t =
t + dt * step_shade_offset;
910 segment->accum_emission = accum_emission;
911 segment->accum_transmittance = accum_transmittance;
912 segment->accum_albedo = accum_albedo;
917 if (!
is_zero(last_step->cdf_distance)) {
918 VolumeStep *step = &
segment->steps[0];
919 int numsteps =
segment->numsteps;
922 for (
int i = 0; i < numsteps; i++, step++)
923 step->cdf_distance *= inv_cdf_distance_sum;
930 # ifdef __KERNEL_CPU__
934 assert(
kg->decoupled_volume_steps_index > 0);
935 assert(
segment->steps ==
kg->decoupled_volume_steps[
kg->decoupled_volume_steps_index - 1]);
936 --
kg->decoupled_volume_steps_index;
957 bool probalistic_scatter)
964 segment->accum_albedo, *throughput, rphase, &channel_pdf);
969 if (probalistic_scatter) {
972 if (1.0f - xi >= sample_transmittance) {
974 xi = 1.0f - (1.0f - xi - sample_transmittance) / (1.0f - sample_transmittance);
977 *throughput /= sample_transmittance;
985 float mis_weight = 1.0f;
986 bool distance_sample =
true;
987 bool use_mis =
false;
989 if (
segment->sampling_method && light_P) {
997 xi = (xi - 0.5f) * 2.0f;
998 distance_sample =
false;
1005 distance_sample =
false;
1010 if (distance_sample) {
1014 float prev_t = 0.0f;
1018 float prev_cdf = 0.0f;
1019 float step_cdf = 1.0f;
1022 for (
int i = 0;; i++, step++) {
1026 if (xi < step_cdf || i == segment->numsteps - 1)
1029 prev_cdf = step_cdf;
1031 prev_cdf_distance = step->cdf_distance;
1035 xi = (xi - prev_cdf) / (step_cdf - prev_cdf);
1038 step_pdf_distance = step->cdf_distance - prev_cdf_distance;
1042 float step_t = step->t - prev_t;
1047 step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf);
1050 if (probalistic_scatter)
1053 pdf =
dot(channel_pdf, distance_pdf * step_pdf_distance);
1069 float prev_t = 0.0f;
1075 int numsteps =
segment->numsteps;
1076 int high = numsteps - 1;
1083 if (sample_t < step[mid].
t)
1085 else if (sample_t >= step[mid + 1].
t)
1089 prev_t = step[mid].t;
1090 prev_cdf_distance = step[mid].cdf_distance;
1096 if (
low >= numsteps - 1) {
1097 prev_t = step[numsteps - 1].t;
1098 prev_cdf_distance = step[numsteps - 1].cdf_distance;
1099 step += numsteps - 1;
1103 step_pdf_distance = step->cdf_distance - prev_cdf_distance;
1107 float step_t = step->t - prev_t;
1108 float step_sample_t = sample_t - prev_t;
1116 float distance_pdf =
dot(channel_pdf, distance_pdf3 * step_pdf_distance);
1120 if (sample_t < 0.0f || pdf == 0.0f) {
1126 transmittance *= (step - 1)->accum_transmittance;
1129 *throughput *= step->sigma_s * transmittance * (mis_weight / pdf);
1133 sd->P = ray->
P + step->shade_t * ray->
D;
1136 volume_shader_sample(
kg, sd,
state, sd->P, &coeff);
1140 sd->P = ray->
P + sample_t * ray->
D;
1147 ccl_device bool kernel_volume_use_decoupled(KernelGlobals *
kg,
1150 int sampling_method)
1158 # ifdef __KERNEL_GPU__
1164 if (sampling_method != 0)
1170 return kernel_data.integrator.sample_all_lights_direct;
1172 return kernel_data.integrator.sample_all_lights_indirect;
1180 ccl_device void kernel_volume_stack_init(KernelGlobals *
kg,
1194 stack[0].shader =
kernel_data.background.volume_shader;
1206 Ray volume_ray = *ray;
1207 volume_ray.
t = FLT_MAX;
1210 int stack_index = 0, enclosed_index = 0;
1212 # ifdef __VOLUME_RECORD_ALL__
1214 uint num_hits = scene_intersect_volume_all(
1220 qsort(hits, num_hits,
sizeof(
Intersection), intersections_compare);
1222 for (
uint hit = 0; hit < num_hits; ++hit, ++isect) {
1225 bool need_add =
true;
1226 for (
int i = 0; i < enclosed_index && need_add; ++i) {
1230 if (enclosed_volumes[i] == stack_sd->object) {
1234 for (
int i = 0; i < stack_index && need_add; ++i) {
1236 if (stack[i].
object == stack_sd->object) {
1242 stack[stack_index].object = stack_sd->object;
1243 stack[stack_index].shader = stack_sd->shader;
1251 enclosed_volumes[enclosed_index++] = stack_sd->object;
1262 if (!scene_intersect_volume(
kg, &volume_ray, &isect, visibility)) {
1271 bool need_add =
true;
1272 for (
int i = 0; i < enclosed_index && need_add; ++i) {
1276 if (enclosed_volumes[i] == stack_sd->object) {
1280 for (
int i = 0; i < stack_index && need_add; ++i) {
1282 if (stack[i].
object == stack_sd->object) {
1288 stack[stack_index].object = stack_sd->object;
1289 stack[stack_index].shader = stack_sd->shader;
1297 enclosed_volumes[enclosed_index++] = stack_sd->object;
1301 volume_ray.
P =
ray_offset(stack_sd->P, -stack_sd->Ng);
1313 stack[0].shader =
kernel_data.background.volume_shader;
1322 ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *
kg,
1335 for (
int i = 0; stack[i].shader !=
SHADER_NONE; i++) {
1336 if (stack[i].
object == sd->object) {
1339 stack[i] = stack[i + 1];
1351 for (i = 0; stack[i].shader !=
SHADER_NONE; i++) {
1353 if (stack[i].
object == sd->object)
1362 stack[i].shader = sd->shader;
1363 stack[i].object = sd->object;
1368 # ifdef __SUBSURFACE__
1369 ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *
kg,
1376 Ray volume_ray = *ray;
1378 # ifdef __VOLUME_RECORD_ALL__
1380 uint num_hits = scene_intersect_volume_all(
1385 qsort(hits, num_hits,
sizeof(
Intersection), intersections_compare);
1387 for (
uint hit = 0; hit < num_hits; ++hit, ++isect) {
1389 kernel_volume_stack_enter_exit(
kg, stack_sd, stack);
1399 kernel_volume_stack_enter_exit(
kg, stack_sd, stack);
1402 volume_ray.
P =
ray_offset(stack_sd->P, -stack_sd->Ng);
1403 if (volume_ray.
t != FLT_MAX) {
typedef float(TangentPoint)[2]
void BLI_kdtree_nd_() free(KDTree *tree)
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
static T sum(const btAlignedObjectArray< T > &items)
ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)
ccl_device_inline float object_volume_density(KernelGlobals *kg, int object)
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
ccl_device_inline void path_radiance_accum_emission(KernelGlobals *kg, PathRadiance *L, ccl_addr_space PathState *state, float3 throughput, float3 value)
#define kernel_assert(cond)
#define kernel_tex_fetch(tex, index)
#define ccl_optional_struct_init
#define ccl_device_noinline_cpu
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
#define make_float3(x, y, z)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
ccl_device float power_heuristic(float a, float b)
ccl_device_inline float path_state_rng_1D(KernelGlobals *kg, const ccl_addr_space PathState *state, int dimension)
ccl_device_inline float path_state_rng_1D_hash(KernelGlobals *kg, const ccl_addr_space PathState *state, uint hash)
CCL_NAMESPACE_BEGIN ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
@ SD_NEED_VOLUME_ATTRIBUTES
@ SD_HETEROGENEOUS_VOLUME
@ PATH_RAY_ALL_VISIBILITY
@ SD_OBJECT_HAS_VOLUME_ATTRIBUTES
#define VOLUME_STACK_SIZE
#define VOLUME_THROUGHPUT_EPSILON
ccl_device float3 volume_color_transmittance(float3 sigma, float t)
ccl_device int kernel_volume_sample_channel(float3 albedo, float3 throughput, float rand, float3 *pdf)
struct VolumeShaderCoefficients VolumeShaderCoefficients
ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, float xi, float *pdf)
ccl_device float3 kernel_volume_distance_pdf(float max_t, float3 sigma_t, float sample_t)
ccl_device float kernel_volume_channel_get(float3 value, int channel)
ccl_device float kernel_volume_distance_sample(float max_t, float3 sigma_t, int channel, float xi, float3 *transmittance, float3 *pdf)
ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float sample_t)
ccl_device float3 kernel_volume_emission_integrate(VolumeShaderCoefficients *coeff, int closure_flag, float3 transmittance, float t)
Segment< FEdge *, Vec3r > segment
#define CLOSURE_IS_VOLUME(type)
__forceinline ssef low(const avxf &a)
__forceinline ssef high(const avxf &a)
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
ccl_device_inline float3 safe_invert_color(float3 a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 normalize_len(const float2 &a, float *t)
ccl_device_inline bool is_zero(const float2 &a)
ccl_device_inline float2 fabs(const float2 &a)
ccl_device_inline float3 one_float3()
ccl_device_inline float3 exp3(float3 v)
ccl_device_inline float3 zero_float3()
ccl_device_inline float len_squared(const float3 a)
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)