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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-12 17:13:56 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-12 17:13:56 +0400
commitebc653463ddfd9f8b893b6acbcc6465972e6abc6 (patch)
tree6b3cc2ba3f04994cf9f8d8f5bca6d63cfe2c9d1f /intern/cycles/kernel/svm
parentc40492205b4369de3babe63b43d127ca622773ec (diff)
Cycles:
* Fix missing update when editing objects with emission materials. * Fix preview pass rendering set to 1 not showing full resolution. * Fix CUDA runtime compiling failing due to missing cache directory. * Use settings from first render layer for visibility and material override. And a bunch of incomplete and still disabled code mostly related to closure sampling.
Diffstat (limited to 'intern/cycles/kernel/svm')
-rw-r--r--intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h20
-rw-r--r--intern/cycles/kernel/svm/bsdf_diffuse.h28
-rw-r--r--intern/cycles/kernel/svm/bsdf_microfacet.h84
-rw-r--r--intern/cycles/kernel/svm/bsdf_reflection.h16
-rw-r--r--intern/cycles/kernel/svm/bsdf_refraction.h18
-rw-r--r--intern/cycles/kernel/svm/bsdf_transparent.h14
-rw-r--r--intern/cycles/kernel/svm/bsdf_ward.h30
-rw-r--r--intern/cycles/kernel/svm/bsdf_westin.h44
-rw-r--r--intern/cycles/kernel/svm/emissive.h27
-rw-r--r--intern/cycles/kernel/svm/svm.h40
-rw-r--r--intern/cycles/kernel/svm/svm_bsdf.h106
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h279
-rw-r--r--intern/cycles/kernel/svm/svm_types.h10
-rw-r--r--intern/cycles/kernel/svm/volume.h2
14 files changed, 433 insertions, 285 deletions
diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h
index e94b33efaae..e16efebf5bb 100644
--- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h
@@ -40,24 +40,24 @@ typedef struct BsdfAshikhminVelvetClosure {
float m_invsigma2;
} BsdfAshikhminVelvetClosure;
-__device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, float3 N, float sigma)
+__device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, ShaderClosure *sc, float sigma)
{
sigma = fmaxf(sigma, 0.01f);
float m_invsigma2 = 1.0f/(sigma * sigma);
- sd->svm_closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
+ sc->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL;
- sd->svm_closure_data0 = m_invsigma2;
+ sc->data0 = m_invsigma2;
}
-__device void bsdf_ashikhmin_velvet_blur(ShaderData *sd, float roughness)
+__device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_invsigma2 = sd->svm_closure_data0;
+ float m_invsigma2 = sc->data0;
float3 m_N = sd->N;
float cosNO = dot(m_N, I);
@@ -89,19 +89,19 @@ __device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const f
return make_float3(0, 0, 0);
}
-__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_invsigma2 = sd->svm_closure_data0;
+ float m_invsigma2 = sc->data0;
float3 m_N = sd->N;
// we are viewing the surface from above - send a ray out with uniform
diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/svm/bsdf_diffuse.h
index a917db86ff5..e8a002cb84c 100644
--- a/intern/cycles/kernel/svm/bsdf_diffuse.h
+++ b/intern/cycles/kernel/svm/bsdf_diffuse.h
@@ -41,17 +41,17 @@ typedef struct BsdfDiffuseClosure {
//float3 m_N;
} BsdfDiffuseClosure;
-__device void bsdf_diffuse_setup(ShaderData *sd, float3 N)
+__device void bsdf_diffuse_setup(ShaderData *sd, ShaderClosure *sc)
{
- sd->svm_closure = CLOSURE_BSDF_DIFFUSE_ID;
+ sc->type = CLOSURE_BSDF_DIFFUSE_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL;
}
-__device void bsdf_diffuse_blur(ShaderData *sd, float roughness)
+__device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float3 m_N = sd->N;
@@ -60,17 +60,17 @@ __device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const float3 I,
return make_float3(cos_pi, cos_pi, cos_pi);
}
-__device float3 bsdf_diffuse_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_diffuse_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_diffuse_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_diffuse_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_diffuse_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float3 m_N = sd->N;
@@ -99,22 +99,22 @@ typedef struct BsdfTranslucentClosure {
//float3 m_N;
} BsdfTranslucentClosure;
-__device void bsdf_translucent_setup(ShaderData *sd, float3 N)
+__device void bsdf_translucent_setup(ShaderData *sd, ShaderClosure *sc)
{
- sd->svm_closure = CLOSURE_BSDF_TRANSLUCENT_ID;
+ sc->type = CLOSURE_BSDF_TRANSLUCENT_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL;
}
-__device void bsdf_translucent_blur(ShaderData *sd, float roughness)
+__device void bsdf_translucent_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float3 m_N = sd->N;
@@ -123,12 +123,12 @@ __device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const float
return make_float3 (cos_pi, cos_pi, cos_pi);
}
-__device float bsdf_translucent_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_translucent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_translucent_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_translucent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float3 m_N = sd->N;
diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/svm/bsdf_microfacet.h
index 0ca37eedc22..3acd3ba4c85 100644
--- a/intern/cycles/kernel/svm/bsdf_microfacet.h
+++ b/intern/cycles/kernel/svm/bsdf_microfacet.h
@@ -43,34 +43,34 @@ typedef struct BsdfMicrofacetGGXClosure {
float m_eta;
} BsdfMicrofacetGGXClosure;
-__device void bsdf_microfacet_ggx_setup(ShaderData *sd, float3 N, float ag, float eta, bool refractive)
+__device void bsdf_microfacet_ggx_setup(ShaderData *sd, ShaderClosure *sc, float ag, float eta, bool refractive)
{
float m_ag = clamp(ag, 1e-5f, 1.0f);
float m_eta = eta;
- sd->svm_closure_data0 = m_ag;
- sd->svm_closure_data1 = m_eta;
+ sc->data0 = m_ag;
+ sc->data1 = m_eta;
if(refractive)
- sd->svm_closure = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
else
- sd->svm_closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
-__device void bsdf_microfacet_ggx_blur(ShaderData *sd, float roughness)
+__device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
{
- float m_ag = sd->svm_closure_data0;
+ float m_ag = sc->data0;
m_ag = fmaxf(roughness, m_ag);
- sd->svm_closure_data0 = m_ag;
+ sc->data0 = m_ag;
}
-__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_ag = sd->svm_closure_data0;
- //float m_eta = sd->svm_closure_data1;
- int m_refractive = sd->svm_closure == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ float m_ag = sc->data0;
+ //float m_eta = sc->data1;
+ int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 m_N = sd->N;
if(m_refractive) return make_float3 (0, 0, 0);
@@ -103,11 +103,11 @@ __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const flo
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_ag = sd->svm_closure_data0;
- float m_eta = sd->svm_closure_data1;
- int m_refractive = sd->svm_closure == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ float m_ag = sc->data0;
+ float m_eta = sc->data1;
+ int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 m_N = sd->N;
if(!m_refractive) return make_float3 (0, 0, 0);
@@ -139,16 +139,16 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const fl
return make_float3 (out, out, out);
}
-__device float bsdf_microfacet_ggx_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_microfacet_ggx_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_microfacet_ggx_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_ag = sd->svm_closure_data0;
- float m_eta = sd->svm_closure_data1;
- int m_refractive = sd->svm_closure == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ float m_ag = sc->data0;
+ float m_eta = sc->data1;
+ int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 m_N = sd->N;
float cosNO = dot(m_N, sd->I);
@@ -268,34 +268,34 @@ typedef struct BsdfMicrofacetBeckmannClosure {
float m_eta;
} BsdfMicrofacetBeckmannClosure;
-__device void bsdf_microfacet_beckmann_setup(ShaderData *sd, float3 N, float ab, float eta, bool refractive)
+__device void bsdf_microfacet_beckmann_setup(ShaderData *sd, ShaderClosure *sc, float ab, float eta, bool refractive)
{
float m_ab = clamp(ab, 1e-5f, 1.0f);
float m_eta = eta;
- sd->svm_closure_data0 = m_ab;
- sd->svm_closure_data1 = m_eta;
+ sc->data0 = m_ab;
+ sc->data1 = m_eta;
if(refractive)
- sd->svm_closure = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
else
- sd->svm_closure = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
+ sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
-__device void bsdf_microfacet_beckmann_blur(ShaderData *sd, float roughness)
+__device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
{
- float m_ab = sd->svm_closure_data0;
+ float m_ab = sc->data0;
m_ab = fmaxf(roughness, m_ab);
- sd->svm_closure_data0 = m_ab;
+ sc->data0 = m_ab;
}
-__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_ab = sd->svm_closure_data0;
- //float m_eta = sd->svm_closure_data1;
- int m_refractive = sd->svm_closure == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ float m_ab = sc->data0;
+ //float m_eta = sc->data1;
+ int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 m_N = sd->N;
if(m_refractive) return make_float3 (0, 0, 0);
@@ -330,11 +330,11 @@ __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, cons
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_ab = sd->svm_closure_data0;
- float m_eta = sd->svm_closure_data1;
- int m_refractive = sd->svm_closure == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ float m_ab = sc->data0;
+ float m_eta = sc->data1;
+ int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 m_N = sd->N;
if(!m_refractive) return make_float3 (0, 0, 0);
@@ -368,16 +368,16 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con
return make_float3 (out, out, out);
}
-__device float bsdf_microfacet_beckmann_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_microfacet_beckmann_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_ab = sd->svm_closure_data0;
- float m_eta = sd->svm_closure_data1;
- int m_refractive = sd->svm_closure == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ float m_ab = sc->data0;
+ float m_eta = sc->data1;
+ int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 m_N = sd->N;
float cosNO = dot(m_N, sd->I);
diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/svm/bsdf_reflection.h
index 4dad61704df..f00b72c4869 100644
--- a/intern/cycles/kernel/svm/bsdf_reflection.h
+++ b/intern/cycles/kernel/svm/bsdf_reflection.h
@@ -41,34 +41,34 @@ typedef struct BsdfReflectionClosure {
//float3 m_N;
} BsdfReflectionClosure;
-__device void bsdf_reflection_setup(ShaderData *sd, float3 N)
+__device void bsdf_reflection_setup(ShaderData *sd, ShaderClosure *sc)
{
- sd->svm_closure = CLOSURE_BSDF_REFLECTION_ID;
+ sc->type = CLOSURE_BSDF_REFLECTION_ID;
sd->flag |= SD_BSDF;
}
-__device void bsdf_reflection_blur(ShaderData *sd, float roughness)
+__device void bsdf_reflection_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_reflection_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_reflection_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_reflection_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_reflection_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_reflection_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_reflection_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_reflection_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_reflection_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- //const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sd->svm_closure_data;
+ //const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data;
float3 m_N = sd->N;
// only one direction is possible
diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/svm/bsdf_refraction.h
index 93bd747eb31..07ef8633e0d 100644
--- a/intern/cycles/kernel/svm/bsdf_refraction.h
+++ b/intern/cycles/kernel/svm/bsdf_refraction.h
@@ -41,36 +41,36 @@ typedef struct BsdfRefractionClosure {
float m_eta;
} BsdfRefractionClosure;
-__device void bsdf_refraction_setup(ShaderData *sd, float3 N, float eta)
+__device void bsdf_refraction_setup(ShaderData *sd, ShaderClosure *sc, float eta)
{
- sd->svm_closure_data0 = eta;
+ sc->data0 = eta;
- sd->svm_closure = CLOSURE_BSDF_REFRACTION_ID;
+ sc->type = CLOSURE_BSDF_REFRACTION_ID;
sd->flag |= SD_BSDF;
}
-__device void bsdf_refraction_blur(ShaderData *sd, float roughness)
+__device void bsdf_refraction_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_refraction_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_refraction_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_refraction_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_refraction_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_refraction_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_refraction_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_refraction_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_refraction_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_eta = sd->svm_closure_data0;
+ float m_eta = sc->data0;
float3 m_N = sd->N;
float3 R, T;
diff --git a/intern/cycles/kernel/svm/bsdf_transparent.h b/intern/cycles/kernel/svm/bsdf_transparent.h
index 1674f04955e..4425c4bf104 100644
--- a/intern/cycles/kernel/svm/bsdf_transparent.h
+++ b/intern/cycles/kernel/svm/bsdf_transparent.h
@@ -35,32 +35,32 @@
CCL_NAMESPACE_BEGIN
-__device void bsdf_transparent_setup(ShaderData *sd)
+__device void bsdf_transparent_setup(ShaderData *sd, ShaderClosure *sc)
{
- sd->svm_closure = CLOSURE_BSDF_TRANSPARENT_ID;
+ sc->type = CLOSURE_BSDF_TRANSPARENT_ID;
sd->flag |= SD_BSDF;
}
-__device void bsdf_transparent_blur(ShaderData *sd, float roughness)
+__device void bsdf_transparent_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_transparent_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_transparent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float3 bsdf_transparent_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_transparent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_transparent_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_transparent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_transparent_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_transparent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
// only one direction is possible
*omega_in = -sd->I;
diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/svm/bsdf_ward.h
index 18967b3981e..d46baf099a6 100644
--- a/intern/cycles/kernel/svm/bsdf_ward.h
+++ b/intern/cycles/kernel/svm/bsdf_ward.h
@@ -44,28 +44,28 @@ typedef struct BsdfWardClosure {
float m_ay;
} BsdfWardClosure;
-__device void bsdf_ward_setup(ShaderData *sd, float3 N, float3 T, float ax, float ay)
+__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float3 T, float ax, float ay)
{
float m_ax = clamp(ax, 1e-5f, 1.0f);
float m_ay = clamp(ay, 1e-5f, 1.0f);
- sd->svm_closure_data0 = m_ax;
- sd->svm_closure_data1 = m_ay;
+ sc->data0 = m_ax;
+ sc->data1 = m_ay;
- sd->svm_closure = CLOSURE_BSDF_WARD_ID;
+ sc->type = CLOSURE_BSDF_WARD_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
-__device void bsdf_ward_blur(ShaderData *sd, float roughness)
+__device void bsdf_ward_blur(ShaderClosure *sc, float roughness)
{
- sd->svm_closure_data0 = fmaxf(roughness, sd->svm_closure_data0);
- sd->svm_closure_data1 = fmaxf(roughness, sd->svm_closure_data1);
+ sc->data0 = fmaxf(roughness, sc->data0);
+ sc->data1 = fmaxf(roughness, sc->data1);
}
-__device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_ax = sd->svm_closure_data0;
- float m_ay = sd->svm_closure_data1;
+ float m_ax = sc->data0;
+ float m_ay = sc->data1;
float3 m_N = sd->N;
float3 m_T = normalize(sd->dPdu);
@@ -93,20 +93,20 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const float3 I, con
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_ward_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ward_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_ward_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_ward_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_ward_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_ax = sd->svm_closure_data0;
- float m_ay = sd->svm_closure_data1;
+ float m_ax = sc->data0;
+ float m_ay = sc->data1;
float3 m_N = sd->N;
float3 m_T = normalize(sd->dPdu);
diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/svm/bsdf_westin.h
index 0f38deb0885..21e5018c489 100644
--- a/intern/cycles/kernel/svm/bsdf_westin.h
+++ b/intern/cycles/kernel/svm/bsdf_westin.h
@@ -42,26 +42,26 @@ typedef struct BsdfWestinBackscatterClosure {
float m_invroughness;
} BsdfWestinBackscatterClosure;
-__device void bsdf_westin_backscatter_setup(ShaderData *sd, float3 N, float roughness)
+__device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness)
{
roughness = clamp(roughness, 1e-5f, 1.0f);
float m_invroughness = 1.0f/roughness;
- sd->svm_closure = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID;
+ sc->type = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
- sd->svm_closure_data0 = m_invroughness;
+ sc->data0 = m_invroughness;
}
-__device void bsdf_westin_backscatter_blur(ShaderData *sd, float roughness)
+__device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness)
{
- float m_invroughness = sd->svm_closure_data0;
+ float m_invroughness = sc->data0;
m_invroughness = min(1.0f/roughness, m_invroughness);
- sd->svm_closure_data0 = m_invroughness;
+ sc->data0 = m_invroughness;
}
-__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_invroughness = sd->svm_closure_data0;
+ float m_invroughness = sc->data0;
float3 m_N = sd->N;
// pdf is implicitly 0 (no indirect sampling)
@@ -76,19 +76,19 @@ __device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_westin_backscatter_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_invroughness = sd->svm_closure_data0;
+ float m_invroughness = sc->data0;
float3 m_N = sd->N;
float cosNO = dot(m_N, sd->I);
@@ -137,20 +137,20 @@ typedef struct BsdfWestinSheenClosure {
float m_edginess;
} BsdfWestinSheenClosure;
-__device void bsdf_westin_sheen_setup(ShaderData *sd, float3 N, float edginess)
+__device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess)
{
- sd->svm_closure = CLOSURE_BSDF_WESTIN_SHEEN_ID;
+ sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID;
sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
- sd->svm_closure_data0 = edginess;
+ sc->data0 = edginess;
}
-__device void bsdf_westin_sheen_blur(ShaderData *sd, float roughness)
+__device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float m_edginess = sd->svm_closure_data0;
+ float m_edginess = sc->data0;
float3 m_N = sd->N;
// pdf is implicitly 0 (no indirect sampling)
@@ -165,19 +165,19 @@ __device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const float
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_westin_sheen_albedo(const ShaderData *sd, const float3 I)
+__device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_westin_sheen_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
- float m_edginess = sd->svm_closure_data0;
+ float m_edginess = sc->data0;
float3 m_N = sd->N;
// we are viewing the surface from the right side - send a ray out with cosine
diff --git a/intern/cycles/kernel/svm/emissive.h b/intern/cycles/kernel/svm/emissive.h
index ed2b2e4aee8..8bd31751fb3 100644
--- a/intern/cycles/kernel/svm/emissive.h
+++ b/intern/cycles/kernel/svm/emissive.h
@@ -42,23 +42,6 @@ __device float3 emissive_eval(const float3 Ng, const float3 I)
return make_float3(res, res, res);
}
-__device void emissive_sample(const float3 Ng, float randu, float randv, float3 *I, float *pdf)
-{
- // We don't do anything sophisticated here for the step
- // We just sample the whole cone uniformly to the cosine
- float3 T, B;
- make_orthonormals(Ng, &T, &B);
- float phi = 2 * M_PI_F * randu;
-
- float cosTheta = sqrtf(1.0f - 1.0f * randv);
- float sinTheta = sqrtf(1.0f - cosTheta * cosTheta);
- *I = (cosf(phi) * sinTheta) * T +
- (sinf(phi) * sinTheta) * B +
- cosTheta * Ng;
-
- *pdf = M_1_PI_F;
-}
-
/// Return the probability distribution function in the direction I,
/// given the parameters and the light's surface normal. This MUST match
/// the PDF computed by sample().
@@ -68,15 +51,9 @@ __device float emissive_pdf(const float3 Ng, const float3 I)
return (cosNO > 0.0f)? M_1_PI_F: 0.0f;
}
-__device float3 svm_emissive_eval(ShaderData *sd)
-{
- return sd->svm_closure_weight*emissive_eval(sd->Ng, sd->I);
-}
-
-__device void svm_emissive_sample(ShaderData *sd, float randu, float randv, float3 *eval, float3 *I, float *pdf)
+__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
{
- *eval = sd->svm_closure_weight;
- emissive_sample(sd->Ng, randu, randv, I, pdf);
+ return emissive_eval(sd->Ng, sd->I);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 989c37c3cd0..a5d95c1b394 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -47,14 +47,14 @@ CCL_NAMESPACE_BEGIN
/* Stack */
-__device float3 stack_load_float3(float *stack, uint a)
+__device_inline float3 stack_load_float3(float *stack, uint a)
{
kernel_assert(a+2 < SVM_STACK_SIZE);
return make_float3(stack[a+0], stack[a+1], stack[a+2]);
}
-__device void stack_store_float3(float *stack, uint a, float3 f)
+__device_inline void stack_store_float3(float *stack, uint a, float3 f)
{
kernel_assert(a+2 < SVM_STACK_SIZE);
@@ -63,40 +63,40 @@ __device void stack_store_float3(float *stack, uint a, float3 f)
stack[a+2] = f.z;
}
-__device float stack_load_float(float *stack, uint a)
+__device_inline float stack_load_float(float *stack, uint a)
{
kernel_assert(a < SVM_STACK_SIZE);
return stack[a];
}
-__device float stack_load_float_default(float *stack, uint a, uint value)
+__device_inline float stack_load_float_default(float *stack, uint a, uint value)
{
return (a == (uint)SVM_STACK_INVALID)? __int_as_float(value): stack_load_float(stack, a);
}
-__device void stack_store_float(float *stack, uint a, float f)
+__device_inline void stack_store_float(float *stack, uint a, float f)
{
kernel_assert(a < SVM_STACK_SIZE);
stack[a] = f;
}
-__device bool stack_valid(uint a)
+__device_inline bool stack_valid(uint a)
{
return a != (uint)SVM_STACK_INVALID;
}
/* Reading Nodes */
-__device uint4 read_node(KernelGlobals *kg, int *offset)
+__device_inline uint4 read_node(KernelGlobals *kg, int *offset)
{
uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
(*offset)++;
return node;
}
-__device float4 read_node_float(KernelGlobals *kg, int *offset)
+__device_inline float4 read_node_float(KernelGlobals *kg, int *offset)
{
uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
float4 f = make_float4(__int_as_float(node.x), __int_as_float(node.y), __int_as_float(node.z), __int_as_float(node.w));
@@ -104,7 +104,7 @@ __device float4 read_node_float(KernelGlobals *kg, int *offset)
return f;
}
-__device void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
+__device_inline void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
{
if(x) *x = (i & 0xFF);
if(y) *y = ((i >> 8) & 0xFF);
@@ -154,8 +154,12 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
float closure_weight = 1.0f;
int offset = sd->shader;
- sd->svm_closure = NBUILTIN_CLOSURES;
- sd->svm_closure_weight = make_float3(0.0f, 0.0f, 0.0f);
+#ifdef __MULTI_CLOSURE__
+ sd->num_closure = 0;
+ sd->randb_closure = randb;
+#else
+ sd->closure.type = NBUILTIN_CLOSURES;
+#endif
while(1) {
uint4 node = read_node(kg, &offset);
@@ -169,16 +173,16 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
break;
}
case NODE_CLOSURE_BSDF:
- svm_node_closure_bsdf(sd, stack, node, randb);
+ svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag);
break;
case NODE_CLOSURE_EMISSION:
- svm_node_closure_emission(sd);
+ svm_node_closure_emission(sd, stack, node);
break;
case NODE_CLOSURE_BACKGROUND:
- svm_node_closure_background(sd);
+ svm_node_closure_background(sd, node);
break;
case NODE_CLOSURE_HOLDOUT:
- svm_node_closure_holdout(sd);
+ svm_node_closure_holdout(sd, stack, node);
break;
case NODE_CLOSURE_SET_WEIGHT:
svm_node_closure_set_weight(sd, node.y, node.z, node.w);
@@ -190,7 +194,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
svm_node_emission_weight(kg, sd, stack, node);
break;
case NODE_MIX_CLOSURE:
- svm_node_mix_closure(sd, stack, node.y, node.z, &offset, &randb);
+ svm_node_mix_closure(sd, stack, node, &offset, &randb);
break;
case NODE_ADD_CLOSURE:
svm_node_add_closure(sd, stack, node.y, node.z, &offset, &randb, &closure_weight);
@@ -307,7 +311,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
break;
case NODE_END:
default:
- sd->svm_closure_weight *= closure_weight;
+#ifndef __MULTI_CLOSURE__
+ sd->closure.weight *= closure_weight;
+#endif
return;
}
}
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
index 22985e9ace5..a1b39c6ca1e 100644
--- a/intern/cycles/kernel/svm/svm_bsdf.h
+++ b/intern/cycles/kernel/svm/svm_bsdf.h
@@ -29,48 +29,48 @@
CCL_NAMESPACE_BEGIN
-__device int svm_bsdf_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
+__device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
{
int label;
- switch(sd->svm_closure) {
+ switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- label = bsdf_diffuse_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_diffuse_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#ifdef __SVM__
case CLOSURE_BSDF_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_translucent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_reflection_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_refraction_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- label = bsdf_transparent_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_transparent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_microfacet_ggx_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_microfacet_beckmann_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- label = bsdf_ward_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_ward_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_ashikhmin_velvet_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- label = bsdf_westin_backscatter_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_westin_backscatter_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- label = bsdf_westin_sheen_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_westin_sheen_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#endif
default:
@@ -78,53 +78,51 @@ __device int svm_bsdf_sample(const ShaderData *sd, float randu, float randv, flo
break;
}
- *eval *= sd->svm_closure_weight;
-
return label;
}
-__device float3 svm_bsdf_eval(const ShaderData *sd, const float3 omega_in, float *pdf)
+__device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
{
float3 eval;
if(dot(sd->Ng, omega_in) >= 0.0f) {
- switch(sd->svm_closure) {
+ switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_diffuse_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_translucent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_reflection_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_refraction_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_transparent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_ggx_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_ward_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_westin_backscatter_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_reflect(sd, sd->I, omega_in, pdf);
+ eval = bsdf_westin_sheen_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
default:
eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -132,43 +130,43 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const float3 omega_in, float
}
}
else {
- switch(sd->svm_closure) {
+ switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_diffuse_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_translucent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_reflection_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_refraction_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_transparent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_ggx_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_ward_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_westin_backscatter_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_transmit(sd, sd->I, omega_in, pdf);
+ eval = bsdf_westin_sheen_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
default:
eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -176,50 +174,48 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const float3 omega_in, float
}
}
- eval *= sd->svm_closure_weight;
-
return eval;
}
-__device void svm_bsdf_blur(ShaderData *sd, float roughness)
+__device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
{
- switch(sd->svm_closure) {
+ switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- bsdf_diffuse_blur(sd, roughness);
+ bsdf_diffuse_blur(sc, roughness);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- bsdf_translucent_blur(sd, roughness);
+ bsdf_translucent_blur(sc, roughness);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- bsdf_reflection_blur(sd, roughness);
+ bsdf_reflection_blur(sc, roughness);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- bsdf_refraction_blur(sd, roughness);
+ bsdf_refraction_blur(sc, roughness);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- bsdf_transparent_blur(sd, roughness);
+ bsdf_transparent_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- bsdf_microfacet_ggx_blur(sd, roughness);
+ bsdf_microfacet_ggx_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- bsdf_microfacet_beckmann_blur(sd, roughness);
+ bsdf_microfacet_beckmann_blur(sc, roughness);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- bsdf_ward_blur(sd, roughness);
+ bsdf_ward_blur(sc, roughness);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- bsdf_ashikhmin_velvet_blur(sd, roughness);
+ bsdf_ashikhmin_velvet_blur(sc, roughness);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- bsdf_westin_backscatter_blur(sd, roughness);
+ bsdf_westin_backscatter_blur(sc, roughness);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- bsdf_westin_sheen_blur(sd, roughness);
+ bsdf_westin_sheen_blur(sc, roughness);
break;
default:
break;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 1efadcefbd5..aaf2926f60d 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -20,28 +20,92 @@ CCL_NAMESPACE_BEGIN
/* Closure Nodes */
-__device void svm_node_closure_bsdf(ShaderData *sd, float *stack, uint4 node, float randb)
+__device void svm_node_glossy_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract)
+{
+ if(type == CLOSURE_BSDF_REFRACTION_ID) {
+ if(refract)
+ bsdf_refraction_setup(sd, sc, eta);
+ else
+ bsdf_reflection_setup(sd, sc);
+ }
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) {
+ bsdf_microfacet_beckmann_setup(sd, sc, roughness, eta, refract);
+ }
+ else
+ bsdf_microfacet_ggx_setup(sd, sc, roughness, eta, refract);
+}
+
+__device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd)
+{
+#ifdef __MULTI_CLOSURE__
+ ShaderClosure *sc = &sd->closure[sd->num_closure];
+
+ if(sd->num_closure < MAX_CLOSURE)
+ sd->num_closure++;
+
+ return sc;
+#else
+ return &sd->closure;
+#endif
+}
+
+__device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mix_weight)
+{
+#ifdef __MULTI_CLOSURE__
+ sc->weight *= mix_weight;
+ sc->sample_weight = fabsf(average(sc->weight));
+#endif
+}
+
+__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag)
{
uint type, param1_offset, param2_offset;
+
+#ifdef __MULTI_CLOSURE__
+ uint mix_weight_offset;
+ decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
+ float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
+
+ if(mix_weight == 0.0f)
+ return;
+#else
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
+ float mix_weight = 1.0f;
+#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __int_as_float(node.z);
float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __int_as_float(node.w);
switch(type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- bsdf_diffuse_setup(sd, sd->N);
+ case CLOSURE_BSDF_DIFFUSE_ID: {
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+ bsdf_diffuse_setup(sd, sc);
break;
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- bsdf_translucent_setup(sd, sd->N);
+ }
+ case CLOSURE_BSDF_TRANSLUCENT_ID: {
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+ bsdf_translucent_setup(sd, sc);
break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- bsdf_transparent_setup(sd);
+ }
+ case CLOSURE_BSDF_TRANSPARENT_ID: {
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+ bsdf_transparent_setup(sd, sc);
break;
+ }
case CLOSURE_BSDF_REFLECTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: {
- /* roughness */
+#ifdef __CAUSTICS_TRICKS__
+ if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
+ break;
+#endif
+
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+
/* index of refraction */
float eta = clamp(1.0f-param2, 1e-5f, 1.0f - 1e-5f);
eta = 1.0f/eta;
@@ -49,26 +113,22 @@ __device void svm_node_closure_bsdf(ShaderData *sd, float *stack, uint4 node, fl
/* fresnel */
float cosNO = dot(sd->N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
+ float roughness = param1;
- sd->svm_closure_weight *= fresnel;
+ sc->weight *= fresnel;
/* setup bsdf */
- if(type == CLOSURE_BSDF_REFLECTION_ID) {
- bsdf_reflection_setup(sd, sd->N);
- }
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) {
- float roughness = param1;
- bsdf_microfacet_beckmann_setup(sd, sd->N, roughness, eta, false);
- }
- else {
- float roughness = param1;
- bsdf_microfacet_ggx_setup(sd, sd->N, roughness, eta, false);
- }
+ svm_node_glossy_setup(sd, sc, type, eta, roughness, false);
break;
}
case CLOSURE_BSDF_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
+#ifdef __CAUSTICS_TRICKS__
+ if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
+ break;
+#endif
+
/* index of refraction */
float eta = clamp(1.0f-param2, 1e-5f, 1.0f - 1e-5f);
eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta;
@@ -76,34 +136,58 @@ __device void svm_node_closure_bsdf(ShaderData *sd, float *stack, uint4 node, fl
/* fresnel */
float cosNO = dot(sd->N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
- bool refract = (fresnel < randb);
+ float roughness = param1;
+
+#ifdef __MULTI_CLOSURE__
+ /* reflection */
+ ShaderClosure *sc = svm_node_closure_get(sd);
+
+ float3 weight = sc->weight;
+ float sample_weight = sc->sample_weight;
+
+ svm_node_closure_set_mix_weight(sc, mix_weight*fresnel);
+ svm_node_glossy_setup(sd, sc, type, eta, roughness, false);
+
+ /* refraction */
+ sc = svm_node_closure_get(sd);
+
+ sc->weight = weight;
+ sc->sample_weight = sample_weight;
+
+ svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel));
+ svm_node_glossy_setup(sd, sc, type, eta, roughness, true);
+#else
+ ShaderClosure *sc = svm_node_closure_get(sd);
+
+ bool refract = (randb > fresnel);
+
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+ svm_node_glossy_setup(sd, sc, type, eta, roughness, refract);
+#endif
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFRACTION_ID) {
- if(refract)
- bsdf_refraction_setup(sd, sd->N, eta);
- else
- bsdf_reflection_setup(sd, sd->N);
- }
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) {
- float roughness = param1;
- bsdf_microfacet_beckmann_setup(sd, sd->N, roughness, eta, refract);
- }
- else {
- float roughness = param1;
- bsdf_microfacet_ggx_setup(sd, sd->N, roughness, eta, refract);
- }
break;
}
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID: {
+#ifdef __CAUSTICS_TRICKS__
+ if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
+ break;
+#endif
+
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+
float roughness_u = param1;
float roughness_v = param2;
- bsdf_ward_setup(sd, sd->N, normalize(sd->dPdu), roughness_u, roughness_v);
+
+ bsdf_ward_setup(sd, sc, normalize(sd->dPdu), roughness_u, roughness_v);
break;
}
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+
/* sigma */
float sigma = clamp(param1, 0.0f, 1.0f);
@@ -115,55 +199,107 @@ __device void svm_node_closure_bsdf(ShaderData *sd, float *stack, uint4 node, fl
float cosNO = dot(sd->N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
- sd->svm_closure_weight *= fresnel;
+ sc->weight *= fresnel;
- bsdf_ashikhmin_velvet_setup(sd, sd->N, sigma);
+ bsdf_ashikhmin_velvet_setup(sd, sc, sigma);
break;
}
default:
- return;
+ break;
}
}
-__device void svm_node_closure_emission(ShaderData *sd)
+__device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
{
- sd->svm_closure = CLOSURE_EMISSION_ID;
+#ifdef __MULTI_CLOSURE__
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ uint mix_weight_offset = node.y;
+
+ if(stack_valid(mix_weight_offset)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
+
+ if(mix_weight == 0.0f)
+ return;
+
+ sc->weight *= mix_weight;
+ }
+#else
+ ShaderClosure *sc = &sd->closure;
+#endif
+
+ sc->type = CLOSURE_EMISSION_ID;
sd->flag |= SD_EMISSION;
}
-__device void svm_node_closure_background(ShaderData *sd)
+__device void svm_node_closure_background(ShaderData *sd, uint4 node)
{
- sd->svm_closure = CLOSURE_BACKGROUND_ID;
+#ifdef __MULTI_CLOSURE__
+ ShaderClosure *sc = svm_node_closure_get(sd);
+#else
+ ShaderClosure *sc = &sd->closure;
+#endif
+
+ sc->type = CLOSURE_BACKGROUND_ID;
}
-__device void svm_node_closure_holdout(ShaderData *sd)
+__device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
{
- sd->svm_closure = CLOSURE_HOLDOUT_ID;
+#ifdef __MULTI_CLOSURE__
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ uint mix_weight_offset = node.y;
+
+ if(stack_valid(mix_weight_offset)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
+
+ if(mix_weight == 0.0f)
+ return;
+
+ sc->weight = make_float3(mix_weight, mix_weight, mix_weight);
+ }
+ else
+ sc->weight = make_float3(1.0f, 1.0f, 1.0f);
+
+ sc->sample_weight = 0.0f;
+#else
+ ShaderClosure *sc = &sd->closure;
+#endif
+
+ sc->type = CLOSURE_HOLDOUT_ID;
sd->flag |= SD_HOLDOUT;
}
/* Closure Nodes */
+__device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
+{
+#ifdef __MULTI_CLOSURE__
+ sd->closure[sd->num_closure].weight = weight;
+#else
+ sd->closure.weight = weight;
+#endif
+}
+
__device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
{
- sd->svm_closure_weight.x = __int_as_float(r);
- sd->svm_closure_weight.y = __int_as_float(g);
- sd->svm_closure_weight.z = __int_as_float(b);
+ float3 weight = make_float3(__int_as_float(r), __int_as_float(g), __int_as_float(b));
+ svm_node_closure_store_weight(sd, weight);
}
__device void svm_node_emission_set_weight_total(KernelGlobals *kg, ShaderData *sd, uint r, uint g, uint b)
{
- sd->svm_closure_weight.x = __int_as_float(r);
- sd->svm_closure_weight.y = __int_as_float(g);
- sd->svm_closure_weight.z = __int_as_float(b);
+ float3 weight = make_float3(__int_as_float(r), __int_as_float(g), __int_as_float(b));
if(sd->object != ~0)
- sd->svm_closure_weight /= object_surface_area(kg, sd->object);
+ weight /= object_surface_area(kg, sd->object);
+
+ svm_node_closure_store_weight(sd, weight);
}
__device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset)
{
- sd->svm_closure_weight = stack_load_float3(stack, weight_offset);
+ float3 weight = stack_load_float3(stack, weight_offset);
+
+ svm_node_closure_store_weight(sd, weight);
}
__device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
@@ -172,37 +308,59 @@ __device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float
uint strength_offset = node.z;
uint total_power = node.w;
- sd->svm_closure_weight = stack_load_float3(stack, color_offset)*stack_load_float(stack, strength_offset);
+ float3 weight = stack_load_float3(stack, color_offset)*stack_load_float(stack, strength_offset);
if(total_power && sd->object != ~0)
- sd->svm_closure_weight /= object_surface_area(kg, sd->object);
+ weight /= object_surface_area(kg, sd->object);
+
+ svm_node_closure_store_weight(sd, weight);
}
__device void svm_node_mix_closure(ShaderData *sd, float *stack,
- uint weight_offset, uint node_jump, int *offset, float *randb)
+ uint4 node, int *offset, float *randb)
{
+#ifdef __MULTI_CLOSURE__
+ /* fetch weight from blend input, previous mix closures,
+ and write to stack to be used by closure nodes later */
+ uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
+ decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
+
float weight = stack_load_float(stack, weight_offset);
- weight = clamp(weight, 0.0f, 1.0f);
+ float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f;
+ if(stack_valid(weight1_offset))
+ stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
+ if(stack_valid(weight2_offset))
+ stack_store_float(stack, weight2_offset, in_weight*weight);
+#else
/* pick a closure and make the random number uniform over 0..1 again.
closure 1 starts on the next node, for closure 2 the start is at an
offset from the current node, so we jump */
+ uint weight_offset = node.y;
+ uint node_jump = node.z;
+ float weight = stack_load_float(stack, weight_offset);
+ weight = clamp(weight, 0.0f, 1.0f);
+
if(*randb < weight) {
*offset += node_jump;
*randb = *randb/weight;
}
else
*randb = (*randb - weight)/(1.0f - weight);
+#endif
}
__device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused,
uint node_jump, int *offset, float *randb, float *closure_weight)
{
- float weight = 0.5f;
-
+#ifdef __MULTI_CLOSURE__
+ /* nothing to do, handled in compiler */
+#else
/* pick one of the two closures with probability 0.5. sampling quality
is not going to be great, for that we'd need to evaluate the weights
of the two closures being added */
+ float weight = 0.5f;
+
if(*randb < weight) {
*offset += node_jump;
*randb = *randb/weight;
@@ -211,6 +369,7 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused,
*randb = (*randb - weight)/(1.0f - weight);
*closure_weight *= 2.0f;
+#endif
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 758ba25c07a..98e4a5ee583 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -258,6 +258,7 @@ typedef enum ShaderType {
/* Closure */
typedef enum ClosureType {
+ CLOSURE_BSDF_ID,
CLOSURE_BSDF_DIFFUSE_ID,
CLOSURE_BSDF_TRANSLUCENT_ID,
CLOSURE_BSDF_REFLECTION_ID,
@@ -272,16 +273,25 @@ typedef enum ClosureType {
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
CLOSURE_BSDF_WESTIN_SHEEN_ID,
+
CLOSURE_BSSRDF_CUBIC_ID,
CLOSURE_EMISSION_ID,
CLOSURE_DEBUG_ID,
CLOSURE_BACKGROUND_ID,
CLOSURE_HOLDOUT_ID,
CLOSURE_SUBSURFACE_ID,
+ CLOSURE_VOLUME_ID,
NBUILTIN_CLOSURES
} ClosureType;
+/* watch this, being lazy with memory usage */
+#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_WESTIN_SHEEN_ID)
+#define CLOSURE_IS_VOLUME(type) (type == CLOSURE_VOLUME_ID)
+#define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
+#define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
+#define CLOSURE_IS_BACKGROUND(type) (type == CLOSURE_BACKGROUND_ID)
+
CCL_NAMESPACE_END
#endif /* __SVM_TYPES_H__ */
diff --git a/intern/cycles/kernel/svm/volume.h b/intern/cycles/kernel/svm/volume.h
index 32e0601ee00..dc377b5c595 100644
--- a/intern/cycles/kernel/svm/volume.h
+++ b/intern/cycles/kernel/svm/volume.h
@@ -34,7 +34,7 @@ CCL_NAMESPACE_BEGIN
/* VOLUME CLOSURE */
-__device float3 volume_eval_phase(ShaderData *sd, const float3 omega_in, const float3 omega_out)
+__device float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
return make_float3(1.0f, 1.0f, 1.0f);
}