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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-11-01 23:07:15 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-11-05 20:13:44 +0300
commitc571be4e05788b8d3447a0bfe59942ebb4464750 (patch)
tree9ee997dee0a0d11b04cf1806f3ca5da9f06c3a78 /intern
parent2c02a04c464c2f5c6e211ceb7b21255eaca7e087 (diff)
Code refactor: sum transparent and absorption weights outside closures.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h18
-rw-r--r--intern/cycles/kernel/closure/volume.h26
-rw-r--r--intern/cycles/kernel/kernel_shader.h32
-rw-r--r--intern/cycles/kernel/kernel_types.h7
-rw-r--r--intern/cycles/kernel/kernel_volume.h76
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp87
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h38
-rw-r--r--intern/cycles/kernel/svm/svm.h8
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h65
9 files changed, 194 insertions, 163 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index 3c2fd8004df..22ca7f3847e 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -35,10 +35,22 @@
CCL_NAMESPACE_BEGIN
-ccl_device int bsdf_transparent_setup(ShaderClosure *sc)
+ccl_device void bsdf_transparent_setup(ShaderData *sd, const float3 weight)
{
- sc->type = CLOSURE_BSDF_TRANSPARENT_ID;
- return SD_BSDF|SD_TRANSPARENT;
+ if(sd->flag & SD_TRANSPARENT) {
+ sd->closure_transparent_extinction += weight;
+ }
+ else {
+ sd->flag |= SD_BSDF|SD_TRANSPARENT;
+ sd->closure_transparent_extinction = weight;
+ }
+
+ ShaderClosure *bsdf = bsdf_alloc(sd, sizeof(ShaderClosure), weight);
+
+ if(bsdf) {
+ bsdf->N = sd->N;
+ bsdf->type = CLOSURE_BSDF_TRANSPARENT_ID;
+ }
}
ccl_device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 01e67c7c2fd..4bb5e680723 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -19,14 +19,27 @@
CCL_NAMESPACE_BEGIN
+/* VOLUME EXTINCTION */
+
+ccl_device void volume_extinction_setup(ShaderData *sd, float3 weight)
+{
+ if(sd->flag & SD_EXTINCTION) {
+ sd->closure_transparent_extinction += weight;
+ }
+ else {
+ sd->flag |= SD_EXTINCTION;
+ sd->closure_transparent_extinction = weight;
+ }
+}
+
+/* HENYEY-GREENSTEIN CLOSURE */
+
typedef ccl_addr_space struct HenyeyGreensteinVolume {
SHADER_CLOSURE_BASE;
float g;
} HenyeyGreensteinVolume;
-/* HENYEY-GREENSTEIN CLOSURE */
-
/* Given cosine between rays, return probability density that a photon bounces
* to that direction. The g parameter controls how different it is from the
* uniform sphere. g=0 uniform diffuse-like, g=1 close to sharp single ray. */
@@ -110,15 +123,6 @@ ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, float3 I
return LABEL_VOLUME_SCATTER;
}
-/* ABSORPTION VOLUME CLOSURE */
-
-ccl_device int volume_absorption_setup(ShaderClosure *sc)
-{
- sc->type = CLOSURE_VOLUME_ABSORPTION_ID;
-
- return SD_ABSORPTION;
-}
-
/* VOLUME CLOSURE */
ccl_device float3 volume_phase_eval(const ShaderData *sd, const ShaderClosure *sc, float3 omega_in, float *pdf)
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 30195605f2e..1ba37eda8cc 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -764,30 +764,30 @@ ccl_device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughn
ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, const ShaderData *sd)
{
- if(sd->flag & SD_HAS_ONLY_VOLUME)
+ if(sd->flag & SD_HAS_ONLY_VOLUME) {
return make_float3(1.0f, 1.0f, 1.0f);
-
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
- eval += sc->weight;
}
-
- return eval;
+ 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)
{
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ 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);
+ 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;
}
}
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index acd06b57a81..cac3ef226f9 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -822,8 +822,8 @@ enum ShaderDataFlag {
SD_BSSRDF = (1 << 4),
/* Shader has holdout closure. */
SD_HOLDOUT = (1 << 5),
- /* Shader has volume absorption closure. */
- SD_ABSORPTION = (1 << 6),
+ /* Shader has non-zero volume extinction. */
+ SD_EXTINCTION = (1 << 6),
/* Shader has have volume phase (scatter) closure. */
SD_SCATTER = (1 << 7),
/* Shader has AO closure. */
@@ -838,7 +838,7 @@ enum ShaderDataFlag {
SD_BSDF_HAS_EVAL |
SD_BSSRDF |
SD_HOLDOUT |
- SD_ABSORPTION |
+ SD_EXTINCTION |
SD_SCATTER |
SD_AO |
SD_BSDF_NEEDS_LCG),
@@ -991,6 +991,7 @@ typedef ccl_addr_space struct ShaderData {
/* Closure weights summed directly, so we can evaluate
* emission and shadow transparency with MAX_CLOSURE 0. */
float3 closure_emission_background;
+ float3 closure_transparent_extinction;
/* At the end so we can adjust size in ShaderDataTinyStorage. */
struct ShaderClosure closure[MAX_CLOSURE];
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 657417e1642..89af16aa9be 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -30,7 +30,7 @@ typedef enum VolumeIntegrateResult {
* sigma_t = sigma_a + sigma_s */
typedef struct VolumeShaderCoefficients {
- float3 sigma_a;
+ float3 sigma_t;
float3 sigma_s;
float3 emission;
} VolumeShaderCoefficients;
@@ -45,20 +45,13 @@ ccl_device_inline bool volume_shader_extinction_sample(KernelGlobals *kg,
sd->P = P;
shader_eval_volume(kg, sd, state, state->volume_stack, PATH_RAY_SHADOW);
- if(!(sd->flag & (SD_ABSORPTION|SD_SCATTER)))
+ if(sd->flag & SD_EXTINCTION) {
+ *extinction = sd->closure_transparent_extinction;
+ return true;
+ }
+ else {
return false;
-
- float3 sigma_t = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_VOLUME(sc->type))
- sigma_t += sc->weight;
}
-
- *extinction = sigma_t;
- return true;
}
/* evaluate shader to get absorption, scattering and emission at P */
@@ -71,30 +64,27 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals *kg,
sd->P = P;
shader_eval_volume(kg, sd, state, state->volume_stack, state->flag);
- if(!(sd->flag & (SD_ABSORPTION|SD_SCATTER|SD_EMISSION)))
+ if(!(sd->flag & (SD_EXTINCTION|SD_SCATTER|SD_EMISSION)))
return false;
- coeff->sigma_a = make_float3(0.0f, 0.0f, 0.0f);
coeff->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ coeff->sigma_t = (sd->flag & SD_EXTINCTION)? sd->closure_transparent_extinction:
+ make_float3(0.0f, 0.0f, 0.0f);
coeff->emission = (sd->flag & SD_EMISSION)? sd->closure_emission_background:
make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i < sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
-
- if(sc->type == CLOSURE_VOLUME_ABSORPTION_ID)
- coeff->sigma_a += sc->weight;
- else if(CLOSURE_IS_VOLUME(sc->type))
- coeff->sigma_s += sc->weight;
- }
-
- /* when at the max number of bounces, treat scattering as absorption */
if(sd->flag & SD_SCATTER) {
- if(state->volume_bounce >= kernel_data.integrator.max_volume_bounce) {
- coeff->sigma_a += coeff->sigma_s;
- coeff->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ if(state->volume_bounce < kernel_data.integrator.max_volume_bounce) {
+ for(int i = 0; i < sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if(CLOSURE_IS_VOLUME(sc->type))
+ coeff->sigma_s += sc->weight;
+ }
+ }
+ else {
+ /* When at the max number of bounces, clear scattering. */
sd->flag &= ~SD_SCATTER;
- sd->flag |= SD_ABSORPTION;
}
}
@@ -335,8 +325,8 @@ ccl_device float3 kernel_volume_emission_integrate(VolumeShaderCoefficients *coe
* todo: we should use an epsilon to avoid precision issues near zero sigma_t */
float3 emission = coeff->emission;
- if(closure_flag & SD_ABSORPTION) {
- float3 sigma_t = coeff->sigma_a + coeff->sigma_s;
+ if(closure_flag & SD_EXTINCTION) {
+ float3 sigma_t = coeff->sigma_t;
emission.x *= (sigma_t.x > 0.0f)? (1.0f - transmittance.x)/sigma_t.x: t;
emission.y *= (sigma_t.y > 0.0f)? (1.0f - transmittance.y)/sigma_t.y: t;
@@ -374,7 +364,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
/* randomly scatter, and if we do t is shortened */
if(closure_flag & SD_SCATTER) {
/* extinction coefficient */
- float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ float3 sigma_t = coeff.sigma_t;
/* pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels */
@@ -425,22 +415,22 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
}
else
#endif
- if(closure_flag & SD_ABSORPTION) {
+ if(closure_flag & SD_EXTINCTION) {
/* absorption only, no sampling needed */
- float3 transmittance = volume_color_transmittance(coeff.sigma_a, t);
+ float3 transmittance = volume_color_transmittance(coeff.sigma_t, t);
new_tp = *throughput * transmittance;
}
/* integrate emission attenuated by extinction */
if(L && (closure_flag & SD_EMISSION)) {
- float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ float3 sigma_t = coeff.sigma_t;
float3 transmittance = volume_color_transmittance(sigma_t, ray->t);
float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, ray->t);
path_radiance_accum_emission(L, state, *throughput, emission);
}
/* modify throughput */
- if(closure_flag & (SD_ABSORPTION|SD_SCATTER)) {
+ if(closure_flag & SD_EXTINCTION) {
*throughput = new_tp;
/* prepare to scatter to new direction */
@@ -507,10 +497,10 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
/* distance sampling */
#ifdef __VOLUME_SCATTER__
- if((closure_flag & SD_SCATTER) || (has_scatter && (closure_flag & SD_ABSORPTION))) {
+ if((closure_flag & SD_SCATTER) || (has_scatter && (closure_flag & SD_EXTINCTION))) {
has_scatter = true;
- float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ float3 sigma_t = coeff.sigma_t;
float3 sigma_s = coeff.sigma_s;
/* compute transmittance over full step */
@@ -544,11 +534,9 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
}
else
#endif
- if(closure_flag & SD_ABSORPTION) {
+ if(closure_flag & SD_EXTINCTION) {
/* absorption only, no sampling needed */
- float3 sigma_a = coeff.sigma_a;
-
- transmittance = volume_color_transmittance(sigma_a, dt);
+ transmittance = volume_color_transmittance(coeff.sigma_t, dt);
new_tp = tp * transmittance;
}
@@ -559,7 +547,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
}
/* modify throughput */
- if(closure_flag & (SD_ABSORPTION|SD_SCATTER)) {
+ if(closure_flag & SD_EXTINCTION) {
tp = new_tp;
/* stop if nearly all light blocked */
@@ -734,7 +722,7 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
/* compute segment */
if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
int closure_flag = sd->flag;
- float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ float3 sigma_t = coeff.sigma_t;
/* compute accumulated transmittance */
float3 transmittance = volume_color_transmittance(sigma_t, dt);
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 14c5c1c3db5..68c707e6c3e 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -92,9 +92,6 @@ BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR)
CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior),
BSDF_CLOSURE_CLASS_END(Refraction, refraction)
-BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, ShaderClosure, LABEL_SINGULAR)
-BSDF_CLOSURE_CLASS_END(Transparent, transparent)
-
BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE)
CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N),
CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma),
@@ -171,13 +168,6 @@ BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GL
CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
-VOLUME_CLOSURE_CLASS_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein, HenyeyGreensteinVolume, LABEL_VOLUME_SCATTER)
- CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
-VOLUME_CLOSURE_CLASS_END(VolumeHenyeyGreenstein, henyey_greenstein)
-
-VOLUME_CLOSURE_CLASS_BEGIN(VolumeAbsorption, absorption, ShaderClosure, LABEL_SINGULAR)
-VOLUME_CLOSURE_CLASS_END(VolumeAbsorption, absorption)
-
BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse, principled_diffuse, PrincipledDiffuseBsdf, LABEL_DIFFUSE)
CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N),
CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness),
@@ -261,7 +251,7 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
register_closure(ss, "refraction", id++,
bsdf_refraction_params(), bsdf_refraction_prepare);
register_closure(ss, "transparent", id++,
- bsdf_transparent_params(), bsdf_transparent_prepare);
+ closure_bsdf_transparent_params(), closure_bsdf_transparent_prepare);
register_closure(ss, "microfacet_ggx", id++,
bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
register_closure(ss, "microfacet_ggx_aniso", id++,
@@ -332,9 +322,9 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
bsdf_hair_transmission_params(), bsdf_hair_transmission_prepare);
register_closure(ss, "henyey_greenstein", id++,
- volume_henyey_greenstein_params(), volume_henyey_greenstein_prepare);
+ closure_henyey_greenstein_params(), closure_henyey_greenstein_prepare);
register_closure(ss, "absorption", id++,
- volume_absorption_params(), volume_absorption_prepare);
+ closure_absorption_params(), closure_absorption_prepare);
}
/* BSDF Closure */
@@ -637,5 +627,76 @@ ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()
}
CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare, MicrofacetMultiGGXGlassFresnelClosure);
+/* Transparent */
+
+class TransparentClosure : public CBSDFClosure {
+public:
+ ShaderClosure params;
+ float3 unused;
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ bsdf_transparent_setup(sd, weight);
+ }
+};
+
+ClosureParam *closure_bsdf_transparent_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(TransparentClosure)
+ };
+ return params;
+}
+
+CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
+
+/* Volume */
+
+class VolumeAbsorptionClosure : public CBSDFClosure {
+public:
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ volume_extinction_setup(sd, weight);
+ }
+};
+
+ClosureParam *closure_absorption_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)
+ };
+ return params;
+}
+
+CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure)
+
+class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
+public:
+ HenyeyGreensteinVolume params;
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ volume_extinction_setup(sd, weight);
+
+ HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc_osl(sd, sizeof(HenyeyGreensteinVolume), weight, &params);
+ sd->flag |= (volume) ? volume_henyey_greenstein_setup(volume) : 0;
+ }
+};
+
+ClosureParam *closure_henyey_greenstein_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
+ CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)
+ };
+ return params;
+}
+
+CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure)
+
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index ff5fd9cc905..38943b77656 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -48,11 +48,13 @@ OSL::ClosureParam *closure_holdout_params();
OSL::ClosureParam *closure_ambient_occlusion_params();
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
+OSL::ClosureParam *closure_bsdf_transparent_params();
OSL::ClosureParam *closure_bssrdf_cubic_params();
OSL::ClosureParam *closure_bssrdf_gaussian_params();
OSL::ClosureParam *closure_bssrdf_burley_params();
OSL::ClosureParam *closure_bssrdf_principled_params();
-OSL::ClosureParam *closure_henyey_greenstein_volume_params();
+OSL::ClosureParam *closure_absorption_params();
+OSL::ClosureParam *closure_henyey_greenstein_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params();
@@ -69,11 +71,13 @@ void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data);
void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data);
void closure_bssrdf_gaussian_prepare(OSL::RendererServices *, int id, void *data);
void closure_bssrdf_burley_prepare(OSL::RendererServices *, int id, void *data);
void closure_bssrdf_principled_prepare(OSL::RendererServices *, int id, void *data);
-void closure_henyey_greenstein_volume_prepare(OSL::RendererServices *, int id, void *data);
+void closure_absorption_prepare(OSL::RendererServices *, int id, void *data);
+void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data);
@@ -147,36 +151,6 @@ static ClosureParam *bsdf_##lower##_params() \
\
CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
-/* Volume */
-
-#define VOLUME_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \
-\
-class Upper##Closure : public CBSDFClosure { \
-public: \
- structname params; \
-\
- void setup(ShaderData *sd, int path_flag, float3 weight) \
- { \
- structname *volume = (structname*)bsdf_alloc_osl(sd, sizeof(structname), weight, &params); \
- sd->flag |= (volume) ? volume_##lower##_setup(volume) : 0; \
- } \
-}; \
-\
-static ClosureParam *volume_##lower##_params() \
-{ \
- static ClosureParam params[] = {
-
-/* parameters */
-
-#define VOLUME_CLOSURE_CLASS_END(Upper, lower) \
- CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \
- CLOSURE_FINISH_PARAM(Upper##Closure) \
- }; \
- return params; \
-} \
-\
-CCLOSURE_PREPARE_STATIC(volume_##lower##_prepare, Upper##Closure)
-
CCL_NAMESPACE_END
#endif /* __OSL_CLOSURES_H__ */
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index d748e76fa80..f0b3adcdad5 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -207,7 +207,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
break;
}
case NODE_CLOSURE_BSDF:
- svm_node_closure_bsdf(kg, sd, stack, node, path_flag, &offset);
+ if(type == SHADER_TYPE_SURFACE) {
+ svm_node_closure_bsdf(kg, sd, stack, node, path_flag, &offset);
+ }
break;
case NODE_CLOSURE_EMISSION:
svm_node_closure_emission(sd, stack, node);
@@ -325,7 +327,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
break;
# if NODES_FEATURE(NODE_FEATURE_VOLUME)
case NODE_CLOSURE_VOLUME:
- svm_node_closure_volume(kg, sd, stack, node, path_flag);
+ if(type == SHADER_TYPE_VOLUME) {
+ svm_node_closure_volume(kg, sd, stack, node, path_flag);
+ }
break;
# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
# ifdef __EXTRA_NODES__
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index f1ed9af1064..4afb91e732b 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -446,12 +446,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
float3 weight = sd->svm_closure_weight * mix_weight;
- ShaderClosure *bsdf = bsdf_alloc(sd, sizeof(ShaderClosure), weight);
-
- if(bsdf) {
- bsdf->N = N;
- sd->flag |= bsdf_transparent_setup(bsdf);
- }
+ bsdf_transparent_setup(sd, weight);
break;
}
case CLOSURE_BSDF_REFLECTION_ID:
@@ -708,18 +703,12 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float3 weight = sd->svm_closure_weight * mix_weight;
if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
- ShaderClosure *bsdf = bsdf_alloc(sd, sizeof(ShaderClosure), weight);
-
- if(bsdf) {
- bsdf->N = N;
- /* todo: giving a fixed weight here will cause issues when
- * mixing multiple BSDFS. energy will not be conserved and
- * the throughput can blow up after multiple bounces. we
- * better figure out a way to skip backfaces from rays
- * spawned by transmission from the front */
- bsdf->weight = make_float3(1.0f, 1.0f, 1.0f);
- sd->flag |= bsdf_transparent_setup(bsdf);
- }
+ /* todo: giving a fixed weight here will cause issues when
+ * mixing multiple BSDFS. energy will not be conserved and
+ * the throughput can blow up after multiple bounces. we
+ * better figure out a way to skip backfaces from rays
+ * spawned by transmission from the front */
+ bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f));
}
else {
HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight);
@@ -831,32 +820,30 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
return;
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
- float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
- float density = fmaxf(param1, 0.0f);
- switch(type) {
- case CLOSURE_VOLUME_ABSORPTION_ID: {
- float3 weight = (make_float3(1.0f, 1.0f, 1.0f) - sd->svm_closure_weight) * mix_weight * density;
- ShaderClosure *sc = closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_NONE_ID, weight);
+ /* Compute scattering coefficient. */
+ float density = mix_weight * fmaxf(param1, 0.0f);
+ float3 weight = sd->svm_closure_weight;
- if(sc) {
- sd->flag |= volume_absorption_setup(sc);
- }
- break;
- }
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight * density;
- HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
+ if(type == CLOSURE_VOLUME_ABSORPTION_ID) {
+ weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
+ }
- if(volume) {
- volume->g = param2; /* g */
- sd->flag |= volume_henyey_greenstein_setup(volume);
- }
- break;
+ weight *= density;
+
+ /* Add closure for volume scattering. */
+ if(type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
+ float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
+ HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
+
+ if(volume) {
+ volume->g = param2; /* g */
+ sd->flag |= volume_henyey_greenstein_setup(volume);
}
- default:
- break;
}
+
+ /* Sum total extinction weight. */
+ volume_extinction_setup(sd, weight);
#endif
}