Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/kernel_shader.h')
-rw-r--r--intern/cycles/kernel/kernel_shader.h1749
1 files changed, 895 insertions, 854 deletions
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index b1da523501d..351b623addb 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -37,14 +37,14 @@ CCL_NAMESPACE_BEGIN
#ifdef __OBJECT_MOTION__
ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
{
- if(sd->object_flag & SD_OBJECT_MOTION) {
- sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
- sd->ob_itfm = transform_quick_inverse(sd->ob_tfm);
- }
- else {
- sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
- sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- }
+ if (sd->object_flag & SD_OBJECT_MOTION) {
+ sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
+ sd->ob_itfm = transform_quick_inverse(sd->ob_tfm);
+ }
+ else {
+ sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
+ sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
+ }
}
#endif
@@ -53,104 +53,104 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
const Intersection *isect,
const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
#ifdef __INSTANCING__
- sd->object = (isect->object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
+ sd->object = (isect->object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, isect->prim) :
+ isect->object;
#endif
- sd->lamp = LAMP_NONE;
+ sd->lamp = LAMP_NONE;
- sd->type = isect->type;
- sd->flag = 0;
- sd->object_flag = kernel_tex_fetch(__object_flag,
- sd->object);
+ sd->type = isect->type;
+ sd->flag = 0;
+ sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
- /* matrices and time */
+ /* matrices and time */
#ifdef __OBJECT_MOTION__
- shader_setup_object_transforms(kg, sd, ray->time);
+ shader_setup_object_transforms(kg, sd, ray->time);
#endif
- sd->time = ray->time;
+ sd->time = ray->time;
- sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
- sd->ray_length = isect->t;
+ sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
+ sd->ray_length = isect->t;
#ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
+ sd->u = isect->u;
+ sd->v = isect->v;
#endif
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE) {
- /* curve */
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
-
- sd->shader = __float_as_int(curvedata.z);
- sd->P = curve_refine(kg, sd, isect, ray);
- }
- else
+ if (sd->type & PRIMITIVE_ALL_CURVE) {
+ /* curve */
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+
+ sd->shader = __float_as_int(curvedata.z);
+ sd->P = curve_refine(kg, sd, isect, ray);
+ }
+ else
#endif
- if(sd->type & PRIMITIVE_TRIANGLE) {
- /* static triangle */
- float3 Ng = triangle_normal(kg, sd);
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ /* static triangle */
+ float3 Ng = triangle_normal(kg, sd);
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
- /* vectors */
- sd->P = triangle_refine(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
+ /* vectors */
+ sd->P = triangle_refine(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+ /* smooth normal */
+ if (sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
#ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
#endif
- }
- else {
- /* motion triangle */
- motion_triangle_shader_setup(kg, sd, isect, ray, false);
- }
+ }
+ else {
+ /* motion triangle */
+ motion_triangle_shader_setup(kg, sd, isect, ray, false);
+ }
- sd->I = -ray->D;
+ sd->I = -ray->D;
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
#ifdef __INSTANCING__
- if(isect->object != OBJECT_NONE) {
- /* instance transform */
- object_normal_transform_auto(kg, sd, &sd->N);
- object_normal_transform_auto(kg, sd, &sd->Ng);
+ if (isect->object != OBJECT_NONE) {
+ /* instance transform */
+ object_normal_transform_auto(kg, sd, &sd->N);
+ object_normal_transform_auto(kg, sd, &sd->Ng);
# ifdef __DPDU__
- object_dir_transform_auto(kg, sd, &sd->dPdu);
- object_dir_transform_auto(kg, sd, &sd->dPdv);
+ object_dir_transform_auto(kg, sd, &sd->dPdu);
+ object_dir_transform_auto(kg, sd, &sd->dPdv);
# endif
- }
+ }
#endif
- /* backfacing test */
- bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
+ /* backfacing test */
+ bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
- if(backfacing) {
- sd->flag |= SD_BACKFACING;
- sd->Ng = -sd->Ng;
- sd->N = -sd->N;
+ if (backfacing) {
+ sd->flag |= SD_BACKFACING;
+ sd->Ng = -sd->Ng;
+ sd->N = -sd->N;
#ifdef __DPDU__
- sd->dPdu = -sd->dPdu;
- sd->dPdv = -sd->dPdv;
+ sd->dPdu = -sd->dPdu;
+ sd->dPdv = -sd->dPdv;
#endif
- }
+ }
#ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
- differential_incoming(&sd->dI, ray->dD);
- differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
+ /* differentials */
+ differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
+ differential_incoming(&sd->dI, ray->dD);
+ differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
#endif
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
/* ShaderData setup from BSSRDF scatter */
@@ -161,86 +161,86 @@ ccl_device
# else
ccl_device_inline
# endif
-void shader_setup_from_subsurface(
- KernelGlobals *kg,
- ShaderData *sd,
- const Intersection *isect,
- const Ray *ray)
+ void
+ shader_setup_from_subsurface(KernelGlobals *kg,
+ ShaderData *sd,
+ const Intersection *isect,
+ const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
- const bool backfacing = sd->flag & SD_BACKFACING;
+ const bool backfacing = sd->flag & SD_BACKFACING;
- /* object, matrices, time, ray_length stay the same */
- sd->flag = 0;
- sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
- sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
- sd->type = isect->type;
+ /* object, matrices, time, ray_length stay the same */
+ sd->flag = 0;
+ sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
+ sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
+ sd->type = isect->type;
# ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
+ sd->u = isect->u;
+ sd->v = isect->v;
# endif
- /* fetch triangle data */
- if(sd->type == PRIMITIVE_TRIANGLE) {
- float3 Ng = triangle_normal(kg, sd);
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ /* fetch triangle data */
+ if (sd->type == PRIMITIVE_TRIANGLE) {
+ float3 Ng = triangle_normal(kg, sd);
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
- /* static triangle */
- sd->P = triangle_refine_local(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
+ /* static triangle */
+ sd->P = triangle_refine_local(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+ if (sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
# ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
# endif
- }
- else {
- /* motion triangle */
- motion_triangle_shader_setup(kg, sd, isect, ray, true);
- }
+ }
+ else {
+ /* motion triangle */
+ motion_triangle_shader_setup(kg, sd, isect, ray, true);
+ }
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
# ifdef __INSTANCING__
- if(isect->object != OBJECT_NONE) {
- /* instance transform */
- object_normal_transform_auto(kg, sd, &sd->N);
- object_normal_transform_auto(kg, sd, &sd->Ng);
+ if (isect->object != OBJECT_NONE) {
+ /* instance transform */
+ object_normal_transform_auto(kg, sd, &sd->N);
+ object_normal_transform_auto(kg, sd, &sd->Ng);
# ifdef __DPDU__
- object_dir_transform_auto(kg, sd, &sd->dPdu);
- object_dir_transform_auto(kg, sd, &sd->dPdv);
+ object_dir_transform_auto(kg, sd, &sd->dPdu);
+ object_dir_transform_auto(kg, sd, &sd->dPdv);
# endif
- }
+ }
# endif
- /* backfacing test */
- if(backfacing) {
- sd->flag |= SD_BACKFACING;
- sd->Ng = -sd->Ng;
- sd->N = -sd->N;
+ /* backfacing test */
+ if (backfacing) {
+ sd->flag |= SD_BACKFACING;
+ sd->Ng = -sd->Ng;
+ sd->N = -sd->N;
# ifdef __DPDU__
- sd->dPdu = -sd->dPdu;
- sd->dPdv = -sd->dPdv;
+ sd->dPdu = -sd->dPdu;
+ sd->dPdv = -sd->dPdv;
# endif
- }
+ }
- /* should not get used in principle as the shading will only use a diffuse
- * BSDF, but the shader might still access it */
- sd->I = sd->N;
+ /* should not get used in principle as the shading will only use a diffuse
+ * BSDF, but the shader might still access it */
+ sd->I = sd->N;
# ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
- /* don't modify dP and dI */
+ /* differentials */
+ differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
+ /* don't modify dP and dI */
# endif
- PROFILING_SHADER(sd->shader);
+ PROFILING_SHADER(sd->shader);
}
#endif
@@ -251,194 +251,208 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
const float3 P,
const float3 Ng,
const float3 I,
- int shader, int object, int prim,
- float u, float v, float t,
+ int shader,
+ int object,
+ int prim,
+ float u,
+ float v,
+ float t,
float time,
bool object_space,
int lamp)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
-
- /* vectors */
- sd->P = P;
- sd->N = Ng;
- sd->Ng = Ng;
- sd->I = I;
- sd->shader = shader;
- if(prim != PRIM_NONE)
- sd->type = PRIMITIVE_TRIANGLE;
- else if(lamp != LAMP_NONE)
- sd->type = PRIMITIVE_LAMP;
- else
- sd->type = PRIMITIVE_NONE;
-
- /* primitive */
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+
+ /* vectors */
+ sd->P = P;
+ sd->N = Ng;
+ sd->Ng = Ng;
+ sd->I = I;
+ sd->shader = shader;
+ if (prim != PRIM_NONE)
+ sd->type = PRIMITIVE_TRIANGLE;
+ else if (lamp != LAMP_NONE)
+ sd->type = PRIMITIVE_LAMP;
+ else
+ sd->type = PRIMITIVE_NONE;
+
+ /* primitive */
#ifdef __INSTANCING__
- sd->object = object;
+ sd->object = object;
#endif
- sd->lamp = LAMP_NONE;
- /* currently no access to bvh prim index for strand sd->prim*/
- sd->prim = prim;
+ sd->lamp = LAMP_NONE;
+ /* currently no access to bvh prim index for strand sd->prim*/
+ sd->prim = prim;
#ifdef __UV__
- sd->u = u;
- sd->v = v;
+ sd->u = u;
+ sd->v = v;
#endif
- sd->time = time;
- sd->ray_length = t;
+ sd->time = time;
+ sd->ray_length = t;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- sd->object_flag = 0;
- if(sd->object != OBJECT_NONE) {
- sd->object_flag |= kernel_tex_fetch(__object_flag,
- sd->object);
+ sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->object_flag = 0;
+ if (sd->object != OBJECT_NONE) {
+ sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
#ifdef __OBJECT_MOTION__
- shader_setup_object_transforms(kg, sd, time);
- }
- else if(lamp != LAMP_NONE) {
- sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
- sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
- sd->lamp = lamp;
+ shader_setup_object_transforms(kg, sd, time);
+ }
+ else if (lamp != LAMP_NONE) {
+ sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
+ sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
+ sd->lamp = lamp;
#else
- }
- else if(lamp != LAMP_NONE) {
- sd->lamp = lamp;
+ }
+ else if (lamp != LAMP_NONE) {
+ sd->lamp = lamp;
#endif
- }
+ }
- /* transform into world space */
- if(object_space) {
- object_position_transform_auto(kg, sd, &sd->P);
- object_normal_transform_auto(kg, sd, &sd->Ng);
- sd->N = sd->Ng;
- object_dir_transform_auto(kg, sd, &sd->I);
- }
+ /* transform into world space */
+ if (object_space) {
+ object_position_transform_auto(kg, sd, &sd->P);
+ object_normal_transform_auto(kg, sd, &sd->Ng);
+ sd->N = sd->Ng;
+ object_dir_transform_auto(kg, sd, &sd->I);
+ }
- if(sd->type & PRIMITIVE_TRIANGLE) {
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL) {
- sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ /* smooth normal */
+ if (sd->shader & SHADER_SMOOTH_NORMAL) {
+ sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
#ifdef __INSTANCING__
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_normal_transform_auto(kg, sd, &sd->N);
- }
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_normal_transform_auto(kg, sd, &sd->N);
+ }
#endif
- }
+ }
- /* dPdu/dPdv */
+ /* dPdu/dPdv */
#ifdef __DPDU__
- triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
# ifdef __INSTANCING__
- if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
- object_dir_transform_auto(kg, sd, &sd->dPdu);
- object_dir_transform_auto(kg, sd, &sd->dPdv);
- }
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ object_dir_transform_auto(kg, sd, &sd->dPdu);
+ object_dir_transform_auto(kg, sd, &sd->dPdv);
+ }
# endif
#endif
- }
- else {
+ }
+ else {
#ifdef __DPDU__
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
#endif
- }
+ }
- /* backfacing test */
- if(sd->prim != PRIM_NONE) {
- bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
+ /* backfacing test */
+ if (sd->prim != PRIM_NONE) {
+ bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
- if(backfacing) {
- sd->flag |= SD_BACKFACING;
- sd->Ng = -sd->Ng;
- sd->N = -sd->N;
+ if (backfacing) {
+ sd->flag |= SD_BACKFACING;
+ sd->Ng = -sd->Ng;
+ sd->N = -sd->N;
#ifdef __DPDU__
- sd->dPdu = -sd->dPdu;
- sd->dPdv = -sd->dPdv;
+ sd->dPdu = -sd->dPdu;
+ sd->dPdv = -sd->dPdv;
#endif
- }
- }
+ }
+ }
#ifdef __RAY_DIFFERENTIALS__
- /* no ray differentials here yet */
- sd->dP = differential3_zero();
- sd->dI = differential3_zero();
- sd->du = differential_zero();
- sd->dv = differential_zero();
+ /* no ray differentials here yet */
+ sd->dP = differential3_zero();
+ sd->dI = differential3_zero();
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
#endif
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
/* ShaderData setup for displacement */
-ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
- int object, int prim, float u, float v)
+ccl_device void shader_setup_from_displace(
+ KernelGlobals *kg, ShaderData *sd, int object, int prim, float u, float v)
{
- float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
- int shader;
-
- triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
-
- /* force smooth shading for displacement */
- shader |= SHADER_SMOOTH_NORMAL;
-
- shader_setup_from_sample(kg, sd,
- P, Ng, I,
- shader, object, prim,
- u, v, 0.0f, 0.5f,
- !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
- LAMP_NONE);
+ float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
+ int shader;
+
+ triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
+
+ /* force smooth shading for displacement */
+ shader |= SHADER_SMOOTH_NORMAL;
+
+ shader_setup_from_sample(
+ kg,
+ sd,
+ P,
+ Ng,
+ I,
+ shader,
+ object,
+ prim,
+ u,
+ v,
+ 0.0f,
+ 0.5f,
+ !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
+ LAMP_NONE);
}
/* ShaderData setup from ray into background */
-ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
+ccl_device_inline void shader_setup_from_background(KernelGlobals *kg,
+ ShaderData *sd,
+ const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
-
- /* vectors */
- sd->P = ray->D;
- sd->N = -ray->D;
- sd->Ng = -ray->D;
- sd->I = -ray->D;
- sd->shader = kernel_data.background.surface_shader;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- sd->object_flag = 0;
- sd->time = ray->time;
- sd->ray_length = 0.0f;
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+
+ /* vectors */
+ sd->P = ray->D;
+ sd->N = -ray->D;
+ sd->Ng = -ray->D;
+ sd->I = -ray->D;
+ sd->shader = kernel_data.background.surface_shader;
+ sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->object_flag = 0;
+ sd->time = ray->time;
+ sd->ray_length = 0.0f;
#ifdef __INSTANCING__
- sd->object = OBJECT_NONE;
+ sd->object = OBJECT_NONE;
#endif
- sd->lamp = LAMP_NONE;
- sd->prim = PRIM_NONE;
+ sd->lamp = LAMP_NONE;
+ sd->prim = PRIM_NONE;
#ifdef __UV__
- sd->u = 0.0f;
- sd->v = 0.0f;
+ sd->u = 0.0f;
+ sd->v = 0.0f;
#endif
#ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ /* dPdu/dPdv */
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
#endif
#ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- sd->dP = ray->dD;
- differential_incoming(&sd->dI, sd->dP);
- sd->du = differential_zero();
- sd->dv = differential_zero();
+ /* differentials */
+ sd->dP = ray->dD;
+ differential_incoming(&sd->dI, sd->dP);
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
#endif
- /* for NDC coordinates */
- sd->ray_P = ray->P;
+ /* for NDC coordinates */
+ sd->ray_P = ray->P;
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
/* ShaderData setup from point inside volume */
@@ -446,141 +460,145 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
#ifdef __VOLUME__
ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
{
- PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
-
- /* vectors */
- sd->P = ray->P;
- sd->N = -ray->D;
- sd->Ng = -ray->D;
- sd->I = -ray->D;
- sd->shader = SHADER_NONE;
- sd->flag = 0;
- sd->object_flag = 0;
- sd->time = ray->time;
- sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
+ PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
+
+ /* vectors */
+ sd->P = ray->P;
+ sd->N = -ray->D;
+ sd->Ng = -ray->D;
+ sd->I = -ray->D;
+ sd->shader = SHADER_NONE;
+ sd->flag = 0;
+ sd->object_flag = 0;
+ sd->time = ray->time;
+ sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
# ifdef __INSTANCING__
- sd->object = OBJECT_NONE; /* todo: fill this for texture coordinates */
+ sd->object = OBJECT_NONE; /* todo: fill this for texture coordinates */
# endif
- sd->lamp = LAMP_NONE;
- sd->prim = PRIM_NONE;
- sd->type = PRIMITIVE_NONE;
+ sd->lamp = LAMP_NONE;
+ sd->prim = PRIM_NONE;
+ sd->type = PRIMITIVE_NONE;
# ifdef __UV__
- sd->u = 0.0f;
- sd->v = 0.0f;
+ sd->u = 0.0f;
+ sd->v = 0.0f;
# endif
# ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ /* dPdu/dPdv */
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
# endif
# ifdef __RAY_DIFFERENTIALS__
- /* differentials */
- sd->dP = ray->dD;
- differential_incoming(&sd->dI, sd->dP);
- sd->du = differential_zero();
- sd->dv = differential_zero();
+ /* differentials */
+ sd->dP = ray->dD;
+ differential_incoming(&sd->dI, sd->dP);
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
# endif
- /* for NDC coordinates */
- sd->ray_P = ray->P;
- sd->ray_dP = ray->dP;
+ /* for NDC coordinates */
+ sd->ray_P = ray->P;
+ sd->ray_dP = ray->dP;
- PROFILING_SHADER(sd->shader);
- PROFILING_OBJECT(sd->object);
+ PROFILING_SHADER(sd->shader);
+ PROFILING_OBJECT(sd->object);
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Merging */
#if defined(__BRANCHED_PATH__) || defined(__VOLUME__)
ccl_device_inline void shader_merge_closures(ShaderData *sd)
{
- /* merge identical closures, better when we sample a single closure at a time */
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sci = &sd->closure[i];
-
- for(int j = i + 1; j < sd->num_closure; j++) {
- ShaderClosure *scj = &sd->closure[j];
-
- if(sci->type != scj->type)
- continue;
- if(!bsdf_merge(sci, scj))
- continue;
-
- sci->weight += scj->weight;
- sci->sample_weight += scj->sample_weight;
-
- int size = sd->num_closure - (j+1);
- if(size > 0) {
- for(int k = 0; k < size; k++) {
- scj[k] = scj[k+1];
- }
- }
-
- sd->num_closure--;
- kernel_assert(sd->num_closure >= 0);
- j--;
- }
- }
+ /* merge identical closures, better when we sample a single closure at a time */
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sci = &sd->closure[i];
+
+ for (int j = i + 1; j < sd->num_closure; j++) {
+ ShaderClosure *scj = &sd->closure[j];
+
+ if (sci->type != scj->type)
+ continue;
+ if (!bsdf_merge(sci, scj))
+ continue;
+
+ sci->weight += scj->weight;
+ sci->sample_weight += scj->sample_weight;
+
+ int size = sd->num_closure - (j + 1);
+ if (size > 0) {
+ for (int k = 0; k < size; k++) {
+ scj[k] = scj[k + 1];
+ }
+ }
+
+ sd->num_closure--;
+ kernel_assert(sd->num_closure >= 0);
+ j--;
+ }
+ }
}
-#endif /* __BRANCHED_PATH__ || __VOLUME__ */
+#endif /* __BRANCHED_PATH__ || __VOLUME__ */
/* Defensive sampling. */
-ccl_device_inline void shader_prepare_closures(ShaderData *sd,
- ccl_addr_space PathState *state)
+ccl_device_inline void shader_prepare_closures(ShaderData *sd, ccl_addr_space PathState *state)
{
- /* We can likely also do defensive sampling at deeper bounces, particularly
- * for cases like a perfect mirror but possibly also others. This will need
- * a good heuristic. */
- if(state->bounce + state->transparent_bounce == 0 && sd->num_closure > 1) {
- float sum = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- sum += sc->sample_weight;
- }
- }
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- sc->sample_weight = max(sc->sample_weight, 0.125f * sum);
- }
- }
- }
+ /* We can likely also do defensive sampling at deeper bounces, particularly
+ * for cases like a perfect mirror but possibly also others. This will need
+ * a good heuristic. */
+ if (state->bounce + state->transparent_bounce == 0 && sd->num_closure > 1) {
+ float sum = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ sum += sc->sample_weight;
+ }
+ }
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ sc->sample_weight = max(sc->sample_weight, 0.125f * sum);
+ }
+ }
+ }
}
-
/* BSDF */
-ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, ShaderData *sd, const float3 omega_in, float *pdf,
- const ShaderClosure *skip_sc, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
+ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ const float3 omega_in,
+ float *pdf,
+ const ShaderClosure *skip_sc,
+ BsdfEval *result_eval,
+ float sum_pdf,
+ float sum_sample_weight)
{
- /* this is the veach one-sample model with balance heuristic, some pdf
- * factors drop out when using balance heuristic weighting */
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ /* this is the veach one-sample model with balance heuristic, some pdf
+ * factors drop out when using balance heuristic weighting */
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(sc != skip_sc && CLOSURE_IS_BSDF(sc->type)) {
- float bsdf_pdf = 0.0f;
- float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
+ if (sc != skip_sc && CLOSURE_IS_BSDF(sc->type)) {
+ float bsdf_pdf = 0.0f;
+ float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
- if(bsdf_pdf != 0.0f) {
- bsdf_eval_accum(result_eval, sc->type, eval*sc->weight, 1.0f);
- sum_pdf += bsdf_pdf*sc->sample_weight;
- }
+ if (bsdf_pdf != 0.0f) {
+ bsdf_eval_accum(result_eval, sc->type, eval * sc->weight, 1.0f);
+ sum_pdf += bsdf_pdf * sc->sample_weight;
+ }
- sum_sample_weight += sc->sample_weight;
- }
- }
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
- *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
+ *pdf = (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
}
#ifdef __BRANCHED_PATH__
@@ -591,633 +609,654 @@ ccl_device_inline void _shader_bsdf_multi_eval_branched(KernelGlobals *kg,
float light_pdf,
bool use_mis)
{
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type)) {
- float bsdf_pdf = 0.0f;
- float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
- if(bsdf_pdf != 0.0f) {
- float mis_weight = use_mis? power_heuristic(light_pdf, bsdf_pdf): 1.0f;
- bsdf_eval_accum(result_eval,
- sc->type,
- eval * sc->weight,
- mis_weight);
- }
- }
- }
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ float bsdf_pdf = 0.0f;
+ float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
+ if (bsdf_pdf != 0.0f) {
+ float mis_weight = use_mis ? power_heuristic(light_pdf, bsdf_pdf) : 1.0f;
+ bsdf_eval_accum(result_eval, sc->type, eval * sc->weight, mis_weight);
+ }
+ }
+ }
}
-#endif /* __BRANCHED_PATH__ */
-
+#endif /* __BRANCHED_PATH__ */
#ifndef __KERNEL_CUDA__
ccl_device
#else
ccl_device_inline
#endif
-void shader_bsdf_eval(KernelGlobals *kg,
- ShaderData *sd,
- const float3 omega_in,
- BsdfEval *eval,
- float light_pdf,
- bool use_mis)
+ void
+ shader_bsdf_eval(KernelGlobals *kg,
+ ShaderData *sd,
+ const float3 omega_in,
+ BsdfEval *eval,
+ float light_pdf,
+ bool use_mis)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_EVAL);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_EVAL);
- bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
+ bsdf_eval_init(
+ eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
#ifdef __BRANCHED_PATH__
- if(kernel_data.integrator.branched)
- _shader_bsdf_multi_eval_branched(kg, sd, omega_in, eval, light_pdf, use_mis);
- else
+ if (kernel_data.integrator.branched)
+ _shader_bsdf_multi_eval_branched(kg, sd, omega_in, eval, light_pdf, use_mis);
+ else
#endif
- {
- float pdf;
- _shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, NULL, eval, 0.0f, 0.0f);
- if(use_mis) {
- float weight = power_heuristic(light_pdf, pdf);
- bsdf_eval_mis(eval, weight);
- }
- }
+ {
+ float pdf;
+ _shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, NULL, eval, 0.0f, 0.0f);
+ if (use_mis) {
+ float weight = power_heuristic(light_pdf, pdf);
+ bsdf_eval_mis(eval, weight);
+ }
+ }
}
-ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd,
- float *randu)
+ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd, float *randu)
{
- /* Note the sampling here must match shader_bssrdf_pick,
- * since we reuse the same random number. */
- int sampled = 0;
+ /* Note the sampling here must match shader_bssrdf_pick,
+ * since we reuse the same random number. */
+ int sampled = 0;
- if(sd->num_closure > 1) {
- /* Pick a BSDF or based on sample weights. */
- float sum = 0.0f;
+ if (sd->num_closure > 1) {
+ /* Pick a BSDF or based on sample weights. */
+ float sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- sum += sc->sample_weight;
- }
- }
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ sum += sc->sample_weight;
+ }
+ }
- float r = (*randu)*sum;
- float partial_sum = 0.0f;
+ float r = (*randu) * sum;
+ float partial_sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- float next_sum = partial_sum + sc->sample_weight;
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ float next_sum = partial_sum + sc->sample_weight;
- if(r < next_sum) {
- sampled = i;
+ if (r < next_sum) {
+ sampled = i;
- /* Rescale to reuse for direction sample, to better
- * preserve stratifaction. */
- *randu = (r - partial_sum) / sc->sample_weight;
- break;
- }
+ /* Rescale to reuse for direction sample, to better
+ * preserve stratifaction. */
+ *randu = (r - partial_sum) / sc->sample_weight;
+ break;
+ }
- partial_sum = next_sum;
- }
- }
- }
+ partial_sum = next_sum;
+ }
+ }
+ }
- const ShaderClosure *sc = &sd->closure[sampled];
- return CLOSURE_IS_BSDF(sc->type)? sc: NULL;
+ const ShaderClosure *sc = &sd->closure[sampled];
+ return CLOSURE_IS_BSDF(sc->type) ? sc : NULL;
}
ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
ccl_addr_space float3 *throughput,
float *randu)
{
- /* Note the sampling here must match shader_bsdf_pick,
- * since we reuse the same random number. */
- int sampled = 0;
-
- if(sd->num_closure > 1) {
- /* Pick a BSDF or BSSRDF or based on sample weights. */
- float sum_bsdf = 0.0f;
- float sum_bssrdf = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF(sc->type)) {
- sum_bsdf += sc->sample_weight;
- }
- else if(CLOSURE_IS_BSSRDF(sc->type)) {
- sum_bssrdf += sc->sample_weight;
- }
- }
-
- float r = (*randu)*(sum_bsdf + sum_bssrdf);
- float partial_sum = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- float next_sum = partial_sum + sc->sample_weight;
-
- if(r < next_sum) {
- if(CLOSURE_IS_BSDF(sc->type)) {
- *throughput *= (sum_bsdf + sum_bssrdf) / sum_bsdf;
- return NULL;
- }
- else {
- *throughput *= (sum_bsdf + sum_bssrdf) / sum_bssrdf;
- sampled = i;
-
- /* Rescale to reuse for direction sample, to better
- * preserve stratifaction. */
- *randu = (r - partial_sum) / sc->sample_weight;
- break;
- }
- }
-
- partial_sum = next_sum;
- }
- }
- }
-
- const ShaderClosure *sc = &sd->closure[sampled];
- return CLOSURE_IS_BSSRDF(sc->type)? sc: NULL;
+ /* Note the sampling here must match shader_bsdf_pick,
+ * since we reuse the same random number. */
+ int sampled = 0;
+
+ if (sd->num_closure > 1) {
+ /* Pick a BSDF or BSSRDF or based on sample weights. */
+ float sum_bsdf = 0.0f;
+ float sum_bssrdf = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ sum_bsdf += sc->sample_weight;
+ }
+ else if (CLOSURE_IS_BSSRDF(sc->type)) {
+ sum_bssrdf += sc->sample_weight;
+ }
+ }
+
+ float r = (*randu) * (sum_bsdf + sum_bssrdf);
+ float partial_sum = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ float next_sum = partial_sum + sc->sample_weight;
+
+ if (r < next_sum) {
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ *throughput *= (sum_bsdf + sum_bssrdf) / sum_bsdf;
+ return NULL;
+ }
+ else {
+ *throughput *= (sum_bsdf + sum_bssrdf) / sum_bssrdf;
+ sampled = i;
+
+ /* Rescale to reuse for direction sample, to better
+ * preserve stratifaction. */
+ *randu = (r - partial_sum) / sc->sample_weight;
+ break;
+ }
+ }
+
+ partial_sum = next_sum;
+ }
+ }
+ }
+
+ const ShaderClosure *sc = &sd->closure[sampled];
+ return CLOSURE_IS_BSSRDF(sc->type) ? sc : NULL;
}
ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
ShaderData *sd,
- float randu, float randv,
+ float randu,
+ float randv,
BsdfEval *bsdf_eval,
float3 *omega_in,
differential3 *domega_in,
float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
- const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
- if(sc == NULL) {
- *pdf = 0.0f;
- return LABEL_NONE;
- }
+ const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
+ if (sc == NULL) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
- /* BSSRDF should already have been handled elsewhere. */
- kernel_assert(CLOSURE_IS_BSDF(sc->type));
+ /* BSSRDF should already have been handled elsewhere. */
+ kernel_assert(CLOSURE_IS_BSDF(sc->type));
- int label;
- float3 eval;
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f) {
- bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
+ if (*pdf != 0.0f) {
+ bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight, kernel_data.film.use_light_pass);
- if(sd->num_closure > 1) {
- float sweight = sc->sample_weight;
- _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, bsdf_eval, *pdf*sweight, sweight);
- }
- }
+ if (sd->num_closure > 1) {
+ float sweight = sc->sample_weight;
+ _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, bsdf_eval, *pdf * sweight, sweight);
+ }
+ }
- return label;
+ return label;
}
-ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, ShaderData *sd,
- const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
- float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg,
+ ShaderData *sd,
+ const ShaderClosure *sc,
+ float randu,
+ float randv,
+ BsdfEval *bsdf_eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_SAMPLE);
- int label;
- float3 eval;
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f)
- bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
+ if (*pdf != 0.0f)
+ bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight, kernel_data.film.use_light_pass);
- return label;
+ return label;
}
ccl_device float shader_bsdf_average_roughness(ShaderData *sd)
{
- float roughness = 0.0f;
- float sum_weight = 0.0f;
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF(sc->type)) {
- /* sqrt once to undo the squaring from multiplying roughness on the
- * two axes, and once for the squared roughness convention. */
- float weight = fabsf(average(sc->weight));
- roughness += weight * sqrtf(safe_sqrtf(bsdf_get_roughness_squared(sc)));
- sum_weight += weight;
- }
- }
-
- return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f;
+ float roughness = 0.0f;
+ float sum_weight = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF(sc->type)) {
+ /* sqrt once to undo the squaring from multiplying roughness on the
+ * two axes, and once for the squared roughness convention. */
+ float weight = fabsf(average(sc->weight));
+ roughness += weight * sqrtf(safe_sqrtf(bsdf_get_roughness_squared(sc)));
+ sum_weight += weight;
+ }
+ }
+
+ return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f;
}
ccl_device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
{
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type))
- bsdf_blur(kg, sc, roughness);
- }
+ if (CLOSURE_IS_BSDF(sc->type))
+ bsdf_blur(kg, sc, roughness);
+ }
}
ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, const ShaderData *sd)
{
- if(sd->flag & SD_HAS_ONLY_VOLUME) {
- return make_float3(1.0f, 1.0f, 1.0f);
- }
- else if(sd->flag & SD_TRANSPARENT) {
- return sd->closure_transparent_extinction;
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->flag & SD_HAS_ONLY_VOLUME) {
+ return make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else if (sd->flag & SD_TRANSPARENT) {
+ return sd->closure_transparent_extinction;
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
ccl_device void shader_bsdf_disable_transparency(KernelGlobals *kg, ShaderData *sd)
{
- if(sd->flag & SD_TRANSPARENT) {
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
- sc->sample_weight = 0.0f;
- sc->weight = make_float3(0.0f, 0.0f, 0.0f);
- }
- }
-
- sd->flag &= ~SD_TRANSPARENT;
- }
+ if (sd->flag & SD_TRANSPARENT) {
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+
+ if (sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
+ sc->sample_weight = 0.0f;
+ sc->weight = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ sd->flag &= ~SD_TRANSPARENT;
+ }
}
ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
{
- float3 alpha = make_float3(1.0f, 1.0f, 1.0f) - shader_bsdf_transparency(kg, sd);
+ float3 alpha = make_float3(1.0f, 1.0f, 1.0f) - shader_bsdf_transparency(kg, sd);
- alpha = max(alpha, make_float3(0.0f, 0.0f, 0.0f));
- alpha = min(alpha, make_float3(1.0f, 1.0f, 1.0f));
+ alpha = max(alpha, make_float3(0.0f, 0.0f, 0.0f));
+ alpha = min(alpha, make_float3(1.0f, 1.0f, 1.0f));
- return alpha;
+ return alpha;
}
ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSDF_GLOSSY(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
- eval += sc->weight;
- }
+ if (CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
}
ccl_device float3 shader_bsdf_average_normal(KernelGlobals *kg, ShaderData *sd)
{
- float3 N = make_float3(0.0f, 0.0f, 0.0f);
+ float3 N = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type))
- N += sc->N*fabsf(average(sc->weight));
- }
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type))
+ N += sc->N * fabsf(average(sc->weight));
+ }
- return (is_zero(N))? sd->N : normalize(N);
+ return (is_zero(N)) ? sd->N : normalize(N);
}
ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N_)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- float3 N = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 N = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- const DiffuseBsdf *bsdf = (const DiffuseBsdf*)sc;
- eval += sc->weight*ao_factor;
- N += bsdf->N*fabsf(average(sc->weight));
- }
- }
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+ const DiffuseBsdf *bsdf = (const DiffuseBsdf *)sc;
+ eval += sc->weight * ao_factor;
+ N += bsdf->N * fabsf(average(sc->weight));
+ }
+ }
- *N_ = (is_zero(N))? sd->N : normalize(N);
- return eval;
+ *N_ = (is_zero(N)) ? sd->N : normalize(N);
+ return eval;
}
#ifdef __SUBSURFACE__
ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_blur_)
{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- float3 N = make_float3(0.0f, 0.0f, 0.0f);
- float texture_blur = 0.0f, weight_sum = 0.0f;
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 N = make_float3(0.0f, 0.0f, 0.0f);
+ float texture_blur = 0.0f, weight_sum = 0.0f;
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSSRDF(sc->type)) {
- const Bssrdf *bssrdf = (const Bssrdf*)sc;
- float avg_weight = fabsf(average(sc->weight));
+ if (CLOSURE_IS_BSSRDF(sc->type)) {
+ const Bssrdf *bssrdf = (const Bssrdf *)sc;
+ float avg_weight = fabsf(average(sc->weight));
- N += bssrdf->N*avg_weight;
- eval += sc->weight;
- texture_blur += bssrdf->texture_blur*avg_weight;
- weight_sum += avg_weight;
- }
- }
+ N += bssrdf->N * avg_weight;
+ eval += sc->weight;
+ texture_blur += bssrdf->texture_blur * avg_weight;
+ weight_sum += avg_weight;
+ }
+ }
- if(N_)
- *N_ = (is_zero(N))? sd->N: normalize(N);
+ if (N_)
+ *N_ = (is_zero(N)) ? sd->N : normalize(N);
- if(texture_blur_)
- *texture_blur_ = safe_divide(texture_blur, weight_sum);
+ if (texture_blur_)
+ *texture_blur_ = safe_divide(texture_blur, weight_sum);
- return eval;
+ return eval;
}
-#endif /* __SUBSURFACE__ */
+#endif /* __SUBSURFACE__ */
/* Constant emission optimization */
ccl_device bool shader_constant_emission_eval(KernelGlobals *kg, int shader, float3 *eval)
{
- int shader_index = shader & SHADER_MASK;
- int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
+ int shader_index = shader & SHADER_MASK;
+ int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
- if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
- *eval = make_float3(
- kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
- kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
- kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
+ if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
+ *eval = make_float3(kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
+ kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
+ kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* Background */
ccl_device float3 shader_background_eval(ShaderData *sd)
{
- if(sd->flag & SD_EMISSION) {
- return sd->closure_emission_background;
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->flag & SD_EMISSION) {
+ return sd->closure_emission_background;
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
/* Emission */
ccl_device float3 shader_emissive_eval(ShaderData *sd)
{
- if(sd->flag & SD_EMISSION) {
- return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
- }
- else {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ if (sd->flag & SD_EMISSION) {
+ return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
/* Holdout */
ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
{
- float3 weight = make_float3(0.0f, 0.0f, 0.0f);
+ float3 weight = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_HOLDOUT(sc->type))
- weight += sc->weight;
- }
+ if (CLOSURE_IS_HOLDOUT(sc->type))
+ weight += sc->weight;
+ }
- return weight;
+ return weight;
}
/* Surface Evaluation */
-ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
- ccl_addr_space PathState *state, int path_flag)
+ccl_device void shader_eval_surface(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ int path_flag)
{
- PROFILING_INIT(kg, PROFILING_SHADER_EVAL);
-
- /* If path is being terminated, we are tracing a shadow ray or evaluating
- * emission, then we don't need to store closures. The emission and shadow
- * shader data also do not have a closure array to save GPU memory. */
- int max_closures;
- if(path_flag & (PATH_RAY_TERMINATE|PATH_RAY_SHADOW|PATH_RAY_EMISSION)) {
- max_closures = 0;
- }
- else {
- max_closures = kernel_data.integrator.max_closures;
- }
-
- sd->num_closure = 0;
- sd->num_closure_left = max_closures;
+ PROFILING_INIT(kg, PROFILING_SHADER_EVAL);
+
+ /* If path is being terminated, we are tracing a shadow ray or evaluating
+ * emission, then we don't need to store closures. The emission and shadow
+ * shader data also do not have a closure array to save GPU memory. */
+ int max_closures;
+ if (path_flag & (PATH_RAY_TERMINATE | PATH_RAY_SHADOW | PATH_RAY_EMISSION)) {
+ max_closures = 0;
+ }
+ else {
+ max_closures = kernel_data.integrator.max_closures;
+ }
+
+ sd->num_closure = 0;
+ sd->num_closure_left = max_closures;
#ifdef __OSL__
- if(kg->osl) {
- if (sd->object == OBJECT_NONE) {
- OSLShader::eval_background(kg, sd, state, path_flag);
- }
- else {
- OSLShader::eval_surface(kg, sd, state, path_flag);
- }
- }
- else
+ if (kg->osl) {
+ if (sd->object == OBJECT_NONE) {
+ OSLShader::eval_background(kg, sd, state, path_flag);
+ }
+ else {
+ OSLShader::eval_surface(kg, sd, state, path_flag);
+ }
+ }
+ else
#endif
- {
+ {
#ifdef __SVM__
- svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
+ svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
#else
- if(sd->object == OBJECT_NONE) {
- sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
- sd->flag |= SD_EMISSION;
- }
- else {
- DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd,
- sizeof(DiffuseBsdf),
- make_float3(0.8f, 0.8f, 0.8f));
- if(bsdf != NULL) {
- bsdf->N = sd->N;
- sd->flag |= bsdf_diffuse_setup(bsdf);
- }
- }
+ if (sd->object == OBJECT_NONE) {
+ sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
+ sd->flag |= SD_EMISSION;
+ }
+ else {
+ DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(
+ sd, sizeof(DiffuseBsdf), make_float3(0.8f, 0.8f, 0.8f));
+ if (bsdf != NULL) {
+ bsdf->N = sd->N;
+ sd->flag |= bsdf_diffuse_setup(bsdf);
+ }
+ }
#endif
- }
+ }
- if(sd->flag & SD_BSDF_NEEDS_LCG) {
- sd->lcg_state = lcg_state_init_addrspace(state, 0xb4bc3953);
- }
+ if (sd->flag & SD_BSDF_NEEDS_LCG) {
+ sd->lcg_state = lcg_state_init_addrspace(state, 0xb4bc3953);
+ }
}
/* Volume */
#ifdef __VOLUME__
-ccl_device_inline void _shader_volume_phase_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
- int skip_phase, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
+ccl_device_inline void _shader_volume_phase_multi_eval(const ShaderData *sd,
+ const float3 omega_in,
+ float *pdf,
+ int skip_phase,
+ BsdfEval *result_eval,
+ float sum_pdf,
+ float sum_sample_weight)
{
- for(int i = 0; i < sd->num_closure; i++) {
- if(i == skip_phase)
- continue;
+ for (int i = 0; i < sd->num_closure; i++) {
+ if (i == skip_phase)
+ continue;
- const ShaderClosure *sc = &sd->closure[i];
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_PHASE(sc->type)) {
- float phase_pdf = 0.0f;
- float3 eval = volume_phase_eval(sd, sc, omega_in, &phase_pdf);
+ if (CLOSURE_IS_PHASE(sc->type)) {
+ float phase_pdf = 0.0f;
+ float3 eval = volume_phase_eval(sd, sc, omega_in, &phase_pdf);
- if(phase_pdf != 0.0f) {
- bsdf_eval_accum(result_eval, sc->type, eval, 1.0f);
- sum_pdf += phase_pdf*sc->sample_weight;
- }
+ if (phase_pdf != 0.0f) {
+ bsdf_eval_accum(result_eval, sc->type, eval, 1.0f);
+ sum_pdf += phase_pdf * sc->sample_weight;
+ }
- sum_sample_weight += sc->sample_weight;
- }
- }
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
- *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
+ *pdf = (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
}
-ccl_device void shader_volume_phase_eval(KernelGlobals *kg, const ShaderData *sd,
- const float3 omega_in, BsdfEval *eval, float *pdf)
+ccl_device void shader_volume_phase_eval(
+ KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, BsdfEval *eval, float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_EVAL);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_EVAL);
- bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
+ bsdf_eval_init(
+ eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
- _shader_volume_phase_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+ _shader_volume_phase_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
}
-ccl_device int shader_volume_phase_sample(KernelGlobals *kg, const ShaderData *sd,
- float randu, float randv, BsdfEval *phase_eval,
- float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int shader_volume_phase_sample(KernelGlobals *kg,
+ const ShaderData *sd,
+ float randu,
+ float randv,
+ BsdfEval *phase_eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
- int sampled = 0;
+ int sampled = 0;
- if(sd->num_closure > 1) {
- /* pick a phase closure based on sample weights */
- float sum = 0.0f;
+ if (sd->num_closure > 1) {
+ /* pick a phase closure based on sample weights */
+ float sum = 0.0f;
- for(sampled = 0; sampled < sd->num_closure; sampled++) {
- const ShaderClosure *sc = &sd->closure[sampled];
+ for (sampled = 0; sampled < sd->num_closure; sampled++) {
+ const ShaderClosure *sc = &sd->closure[sampled];
- if(CLOSURE_IS_PHASE(sc->type))
- sum += sc->sample_weight;
- }
+ if (CLOSURE_IS_PHASE(sc->type))
+ sum += sc->sample_weight;
+ }
- float r = randu*sum;
- float partial_sum = 0.0f;
+ float r = randu * sum;
+ float partial_sum = 0.0f;
- for(sampled = 0; sampled < sd->num_closure; sampled++) {
- const ShaderClosure *sc = &sd->closure[sampled];
+ for (sampled = 0; sampled < sd->num_closure; sampled++) {
+ const ShaderClosure *sc = &sd->closure[sampled];
- if(CLOSURE_IS_PHASE(sc->type)) {
- float next_sum = partial_sum + sc->sample_weight;
+ if (CLOSURE_IS_PHASE(sc->type)) {
+ float next_sum = partial_sum + sc->sample_weight;
- if(r <= next_sum) {
- /* Rescale to reuse for BSDF direction sample. */
- randu = (r - partial_sum) / sc->sample_weight;
- break;
- }
+ if (r <= next_sum) {
+ /* Rescale to reuse for BSDF direction sample. */
+ randu = (r - partial_sum) / sc->sample_weight;
+ break;
+ }
- partial_sum = next_sum;
- }
- }
+ partial_sum = next_sum;
+ }
+ }
- if(sampled == sd->num_closure) {
- *pdf = 0.0f;
- return LABEL_NONE;
- }
- }
+ if (sampled == sd->num_closure) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+ }
- /* todo: this isn't quite correct, we don't weight anisotropy properly
- * depending on color channels, even if this is perhaps not a common case */
- const ShaderClosure *sc = &sd->closure[sampled];
- int label;
- float3 eval;
+ /* todo: this isn't quite correct, we don't weight anisotropy properly
+ * depending on color channels, even if this is perhaps not a common case */
+ const ShaderClosure *sc = &sd->closure[sampled];
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f) {
- bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
- }
+ if (*pdf != 0.0f) {
+ bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
+ }
- return label;
+ return label;
}
-ccl_device int shader_phase_sample_closure(KernelGlobals *kg, const ShaderData *sd,
- const ShaderClosure *sc, float randu, float randv, BsdfEval *phase_eval,
- float3 *omega_in, differential3 *domega_in, float *pdf)
+ccl_device int shader_phase_sample_closure(KernelGlobals *kg,
+ const ShaderData *sd,
+ const ShaderClosure *sc,
+ float randu,
+ float randv,
+ BsdfEval *phase_eval,
+ float3 *omega_in,
+ differential3 *domega_in,
+ float *pdf)
{
- PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
+ PROFILING_INIT(kg, PROFILING_CLOSURE_VOLUME_SAMPLE);
- int label;
- float3 eval;
+ int label;
+ float3 eval;
- *pdf = 0.0f;
- label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ *pdf = 0.0f;
+ label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
- if(*pdf != 0.0f)
- bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
+ if (*pdf != 0.0f)
+ bsdf_eval_init(phase_eval, sc->type, eval, kernel_data.film.use_light_pass);
- return label;
+ return label;
}
/* Volume Evaluation */
@@ -1228,83 +1267,85 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg,
ccl_addr_space VolumeStack *stack,
int path_flag)
{
- /* If path is being terminated, we are tracing a shadow ray or evaluating
- * emission, then we don't need to store closures. The emission and shadow
- * shader data also do not have a closure array to save GPU memory. */
- int max_closures;
- if(path_flag & (PATH_RAY_TERMINATE|PATH_RAY_SHADOW|PATH_RAY_EMISSION)) {
- max_closures = 0;
- }
- else {
- max_closures = kernel_data.integrator.max_closures;
- }
-
- /* reset closures once at the start, we will be accumulating the closures
- * for all volumes in the stack into a single array of closures */
- sd->num_closure = 0;
- sd->num_closure_left = max_closures;
- sd->flag = 0;
- sd->object_flag = 0;
-
- for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
- /* setup shaderdata from stack. it's mostly setup already in
- * shader_setup_from_volume, this switching should be quick */
- sd->object = stack[i].object;
- sd->lamp = LAMP_NONE;
- sd->shader = stack[i].shader;
-
- sd->flag &= ~SD_SHADER_FLAGS;
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- sd->object_flag &= ~SD_OBJECT_FLAGS;
-
- if(sd->object != OBJECT_NONE) {
- sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
-
-#ifdef __OBJECT_MOTION__
- /* todo: this is inefficient for motion blur, we should be
- * caching matrices instead of recomputing them each step */
- shader_setup_object_transforms(kg, sd, sd->time);
-#endif
- }
-
- /* evaluate shader */
-#ifdef __SVM__
-# ifdef __OSL__
- if(kg->osl) {
- OSLShader::eval_volume(kg, sd, state, path_flag);
- }
- else
+ /* If path is being terminated, we are tracing a shadow ray or evaluating
+ * emission, then we don't need to store closures. The emission and shadow
+ * shader data also do not have a closure array to save GPU memory. */
+ int max_closures;
+ if (path_flag & (PATH_RAY_TERMINATE | PATH_RAY_SHADOW | PATH_RAY_EMISSION)) {
+ max_closures = 0;
+ }
+ else {
+ max_closures = kernel_data.integrator.max_closures;
+ }
+
+ /* reset closures once at the start, we will be accumulating the closures
+ * for all volumes in the stack into a single array of closures */
+ sd->num_closure = 0;
+ sd->num_closure_left = max_closures;
+ sd->flag = 0;
+ sd->object_flag = 0;
+
+ for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
+ /* setup shaderdata from stack. it's mostly setup already in
+ * shader_setup_from_volume, this switching should be quick */
+ sd->object = stack[i].object;
+ sd->lamp = LAMP_NONE;
+ sd->shader = stack[i].shader;
+
+ sd->flag &= ~SD_SHADER_FLAGS;
+ sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->object_flag &= ~SD_OBJECT_FLAGS;
+
+ if (sd->object != OBJECT_NONE) {
+ sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
+
+# ifdef __OBJECT_MOTION__
+ /* todo: this is inefficient for motion blur, we should be
+ * caching matrices instead of recomputing them each step */
+ shader_setup_object_transforms(kg, sd, sd->time);
+# endif
+ }
+
+ /* evaluate shader */
+# ifdef __SVM__
+# ifdef __OSL__
+ if (kg->osl) {
+ OSLShader::eval_volume(kg, sd, state, path_flag);
+ }
+ else
+# endif
+ {
+ svm_eval_nodes(kg, sd, state, SHADER_TYPE_VOLUME, path_flag);
+ }
# endif
- {
- svm_eval_nodes(kg, sd, state, SHADER_TYPE_VOLUME, path_flag);
- }
-#endif
- /* merge closures to avoid exceeding number of closures limit */
- if(i > 0)
- shader_merge_closures(sd);
- }
+ /* merge closures to avoid exceeding number of closures limit */
+ if (i > 0)
+ shader_merge_closures(sd);
+ }
}
-#endif /* __VOLUME__ */
+#endif /* __VOLUME__ */
/* Displacement Evaluation */
-ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state)
+ccl_device void shader_eval_displacement(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state)
{
- sd->num_closure = 0;
- sd->num_closure_left = 0;
+ sd->num_closure = 0;
+ sd->num_closure_left = 0;
- /* this will modify sd->P */
+ /* this will modify sd->P */
#ifdef __SVM__
# ifdef __OSL__
- if(kg->osl)
- OSLShader::eval_displacement(kg, sd, state);
- else
+ if (kg->osl)
+ OSLShader::eval_displacement(kg, sd, state);
+ else
# endif
- {
- svm_eval_nodes(kg, sd, state, SHADER_TYPE_DISPLACEMENT, 0);
- }
+ {
+ svm_eval_nodes(kg, sd, state, SHADER_TYPE_DISPLACEMENT, 0);
+ }
#endif
}
@@ -1313,29 +1354,29 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ccl_
#ifdef __TRANSPARENT_SHADOWS__
ccl_device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
{
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- int shader = 0;
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ int shader = 0;
-#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
-#endif
- shader = kernel_tex_fetch(__tri_shader, prim);
-#ifdef __HAIR__
- }
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
-#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+# ifdef __HAIR__
+ if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
+# endif
+ shader = kernel_tex_fetch(__tri_shader, prim);
+# ifdef __HAIR__
+ }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+# endif
+ int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
- return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
+ return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
}
-#endif /* __TRANSPARENT_SHADOWS__ */
+#endif /* __TRANSPARENT_SHADOWS__ */
ccl_device float shader_cryptomatte_id(KernelGlobals *kg, int shader)
{
- return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).cryptomatte_id;
+ return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).cryptomatte_id;
}
CCL_NAMESPACE_END