forked from bartvdbraak/blender
Code refactor: sum transparent and absorption weights outside closures.
This commit is contained in:
parent
2c02a04c46
commit
c571be4e05
@ -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, ¶ms);
|
||||
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, ¶ms); \
|
||||
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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user