Code refactor: sum transparent and absorption weights outside closures.

This commit is contained in:
Brecht Van Lommel 2017-11-01 21:07:15 +01:00
parent 2c02a04c46
commit c571be4e05
9 changed files with 197 additions and 166 deletions

@ -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)

@ -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)

@ -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;
}
}

@ -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];

@ -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)))
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;
if(sd->flag & SD_EXTINCTION) {
*extinction = sd->closure_transparent_extinction;
return true;
}
else {
return false;
}
*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);

@ -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

@ -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__ */

@ -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__

@ -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(volume) {
volume->g = param2; /* g */
sd->flag |= volume_henyey_greenstein_setup(volume);
}
break;
}
default:
break;
if(type == CLOSURE_VOLUME_ABSORPTION_ID) {
weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
}
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);
}
}
/* Sum total extinction weight. */
volume_extinction_setup(sd, weight);
#endif
}