Skip to content

Commit 75a805c

Browse files
committed
Added priority handling for overlapping media
1 parent 78ae0fc commit 75a805c

5 files changed

Lines changed: 253 additions & 204 deletions

File tree

src/testrender/shading.cpp

Lines changed: 112 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,7 +1513,7 @@ struct ZeltnerBurleySheen final : public BSDF, MxSheenParams {
15131513
}
15141514
};
15151515

1516-
/// @name Mediums
1516+
15171517
struct HenyeyGreenstein final : public BSDF {
15181518
const float g;
15191519
OSL_HOSTDEVICE HenyeyGreenstein(float g)
@@ -1559,29 +1559,25 @@ struct HenyeyGreenstein final : public BSDF {
15591559

15601560
};
15611561

1562-
struct HomogeneousVolume final : public Medium, MediumParams {
1562+
struct HomogeneousVolume final : public Medium {
1563+
MediumParams params;
15631564

15641565
OSL_HOSTDEVICE HomogeneousVolume(const MediumParams& params)
1565-
: Medium(this), MediumParams(params)
1566+
: Medium(this), params(params)
15661567
{
15671568
}
15681569

15691570
OSL_HOSTDEVICE static HomogeneousVolume* create(void* storage, const MediumParams& params) {
15701571
HomogeneousVolume* volume = new (storage) HomogeneousVolume(params);
1571-
volume->phase_func = new HenyeyGreenstein(params.medium_g); // assuming g is anisotropy parameter
1572+
volume->phase_func = new HenyeyGreenstein(params.medium_g);
15721573
return volume;
15731574
}
15741575

15751576
OSL_HOSTDEVICE Medium::Sample sample(const Ray &ray, Sampler &sampler, Intersection& hit) const
15761577
{
15771578
Vec3 rand_vol = sampler.get();
1578-
float max_sigma_t = std::max(std::max(sigma_t.x, sigma_t.y), sigma_t.z);
1579-
/*
1580-
if (max_sigma_t <= 0.0f) {
1581-
// vacuum: no attenuation, pdf irrelevant
1582-
return Medium::Sample { hit.t, false, Color3(1.0f) };
1583-
}
1584-
*/
1579+
float max_sigma_t = fmaxf(fmaxf(params.sigma_t.x, params.sigma_t.y), params.sigma_t.z);
1580+
15851581
float t_volume = -logf(1.0f - rand_vol.x) / max_sigma_t;
15861582
bool volume_scatter = (t_volume < hit.t);
15871583

@@ -1592,9 +1588,9 @@ struct HomogeneousVolume final : public Medium, MediumParams {
15921588
tr = transmittance(t_volume);
15931589

15941590
Color3 albedo = Color3(
1595-
sigma_s.x / sigma_t.x,
1596-
sigma_s.y / sigma_t.y,
1597-
sigma_s.z / sigma_t.z
1591+
params.sigma_s.x / params.sigma_t.x,
1592+
params.sigma_s.y / params.sigma_t.y,
1593+
params.sigma_s.z / params.sigma_t.z
15981594
);
15991595

16001596
weight = albedo / tr;
@@ -1606,30 +1602,46 @@ struct HomogeneousVolume final : public Medium, MediumParams {
16061602
1.0 / tr.z
16071603
);
16081604
}
1609-
/*
1610-
if (pdf <= 0.0f) {
1611-
// ensure Tr is black in this degenerate case if we expected absorption
1612-
return Medium::Sample { hit.t, false, tr };
1613-
}
1614-
*/
1605+
16151606
return Medium::Sample { volume_scatter, t_volume, tr, weight };
16161607
}
16171608

1609+
OSL_HOSTDEVICE const MediumParams* get_params() const {
1610+
return &params;
1611+
}
1612+
16181613
OSL_HOSTDEVICE Color3 transmittance(float distance) const
1619-
{ //Beer-Lambert law
1620-
return Color3(expf(-sigma_t.x * distance),
1621-
expf(-sigma_t.y * distance),
1622-
expf(-sigma_t.z * distance));
1614+
{ // Beer-Lambert law
1615+
return Color3(expf(-params.sigma_t.x * distance),
1616+
expf(-params.sigma_t.y * distance),
1617+
expf(-params.sigma_t.z * distance));
16231618
}
16241619
};
16251620

16261621
struct EmptyVolume final : public Medium {
1627-
OSL_HOSTDEVICE EmptyVolume() :
1628-
Medium(this)
1622+
MediumParams params;
1623+
1624+
OSL_HOSTDEVICE EmptyVolume(const MediumParams& params)
1625+
: Medium(this), params(params)
1626+
{
1627+
}
1628+
1629+
OSL_HOSTDEVICE static EmptyVolume* create(void* storage, const MediumParams& params) {
1630+
EmptyVolume* volume = new (storage) EmptyVolume(params);
1631+
return volume;
1632+
}
1633+
1634+
OSL_HOSTDEVICE Medium::Sample sample(const Ray &ray, Sampler &sampler, Intersection& hit) const
16291635
{
1636+
return { false, 0.0f, Color3(1.0f), Color3(1.0f) };
1637+
}
1638+
1639+
OSL_HOSTDEVICE const MediumParams* get_params() const {
1640+
return &params;
16301641
}
16311642
};
16321643

1644+
16331645
OSL_HOSTDEVICE Color3
16341646
evaluate_layer_opacity(const ShaderGlobalsType& sg, float path_roughness,
16351647
const ClosureColor* closure)
@@ -1769,9 +1781,14 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
17691781
result.medium_data.sigma_t = cw * params.extinction;
17701782
result.medium_data.sigma_s = params.albedo * result.medium_data.sigma_t;
17711783
result.medium_data.medium_g = params.anisotropy;
1784+
result.medium_data.priority = 0;
17721785

17731786
if (!sg.backfacing) { // if entering
1774-
medium_stack.push_medium<HomogeneousVolume>(result.medium_data);
1787+
if (result.medium_data.is_vaccum()) {
1788+
medium_stack.add_medium<EmptyVolume>(result.medium_data);
1789+
} else {
1790+
medium_stack.add_medium<HomogeneousVolume>(result.medium_data);
1791+
}
17751792
}
17761793

17771794
closure = nullptr;
@@ -1781,7 +1798,7 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
17811798
const ClosureComponent* comp = closure->as_comp();
17821799
Color3 cw = weight * comp->w;
17831800
const auto& params = *comp->as<MxMediumVdfParams>();
1784-
1801+
17851802
result.medium_data.sigma_t = Color3(
17861803
-OIIO::fast_log(params.transmission_color.x),
17871804
-OIIO::fast_log(params.transmission_color.y),
@@ -1792,44 +1809,56 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
17921809
result.medium_data.sigma_s = params.albedo * result.medium_data.sigma_t;
17931810
result.medium_data.medium_g = params.anisotropy;
17941811

1795-
// Track IOR and priority here
1796-
result.medium_data.refraction_ior = sg.backfacing ? 1.0f / params.ior
1797-
: params.ior;
1798-
1812+
result.medium_data.refraction_ior = sg.backfacing ? 1.0f / params.ior : params.ior;
1813+
result.medium_data.priority = params.priority;
1814+
17991815
if (!sg.backfacing) { // if entering
1800-
medium_stack.push_medium<HomogeneousVolume>(result.medium_data);
1816+
if (result.medium_data.is_vaccum()) {
1817+
medium_stack.add_medium<EmptyVolume>(result.medium_data);
1818+
} else {
1819+
medium_stack.add_medium<HomogeneousVolume>(result.medium_data);
1820+
}
18011821
}
1802-
1803-
//result.medium_data.priority = params.priority;
1822+
18041823
closure = nullptr;
18051824
break;
18061825
}
18071826
case MxDielectric::closureid(): {
18081827
const ClosureComponent* comp = closure->as_comp();
18091828
const MxDielectric::Data& params = *comp->as<MxDielectric::Data>();
18101829
if (!is_black(weight * comp->w * params.refr_tint)) {
1811-
// TODO: properly track a medium stack here ...
1812-
result.medium_data.refraction_ior = sg.backfacing ? 1.0f / params.IOR
1813-
: params.IOR;
1830+
float new_ior = sg.backfacing ? 1.0f / params.IOR : params.IOR;
1831+
1832+
result.medium_data.refraction_ior = new_ior;
1833+
1834+
const MediumParams* current_params = medium_stack.current_params();
1835+
if (current_params && result.medium_data.priority <= current_params->priority) {
1836+
result.medium_data.refraction_ior = current_params->refraction_ior;
1837+
}
18141838
}
18151839
closure = nullptr;
18161840
break;
18171841
}
18181842
case MX_GENERALIZED_SCHLICK_ID: {
1819-
const ClosureComponent* comp = closure->as_comp();
1820-
const auto& params = *comp->as<MxGeneralizedSchlickParams>();
1821-
if (!is_black(weight * comp->w * params.transmission_tint)) {
1822-
// TODO: properly track a medium stack here ...
1823-
float avg_F0 = clamp((params.f0.x + params.f0.y + params.f0.z)
1824-
/ 3.0f,
1825-
0.0f, 0.99f);
1826-
float sqrt_F0 = sqrtf(avg_F0);
1827-
float ior = (1 + sqrt_F0) / (1 - sqrt_F0);
1828-
result.medium_data.refraction_ior = sg.backfacing ? 1.0f / ior : ior;
1843+
const ClosureComponent* comp = closure->as_comp();
1844+
const auto& params = *comp->as<MxGeneralizedSchlickParams>();
1845+
if (!is_black(weight * comp->w * params.transmission_tint)) {
1846+
float avg_F0 = clamp((params.f0.x + params.f0.y + params.f0.z) / 3.0f,
1847+
0.0f, 0.99f);
1848+
float sqrt_F0 = sqrtf(avg_F0);
1849+
float ior = (1 + sqrt_F0) / (1 - sqrt_F0);
1850+
float new_ior = sg.backfacing ? 1.0f / ior : ior;
1851+
1852+
result.medium_data.refraction_ior = new_ior;
1853+
1854+
const MediumParams* current_params = medium_stack.current_params();
1855+
if (current_params && result.medium_data.priority <= current_params->priority) {
1856+
result.medium_data.refraction_ior = current_params->refraction_ior;
18291857
}
1830-
closure = nullptr;
1831-
break;
18321858
}
1859+
closure = nullptr;
1860+
break;
1861+
}
18331862
default: closure = nullptr; break;
18341863
}
18351864
if (closure == nullptr && stack_idx > 0) {
@@ -1842,8 +1871,9 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
18421871
// recursively walk through the closure tree, creating bsdfs as we go
18431872
OSL_HOSTDEVICE void
18441873
process_bsdf_closure(const ShaderGlobalsType& sg, float path_roughness,
1845-
ShadingResult& result, const ClosureColor* closure,
1846-
const Color3& w, bool light_only)
1874+
ShadingResult& result, MediumStack& medium_stack,
1875+
const ClosureColor* closure, const Color3& w,
1876+
bool light_only)
18471877
{
18481878
static const ustringhash uh_ggx("ggx");
18491879
static const ustringhash uh_beckmann("beckmann");
@@ -1976,9 +2006,13 @@ process_bsdf_closure(const ShaderGlobalsType& sg, float path_roughness,
19762006
case MxDielectric::closureid(): {
19772007
const MxDielectric::Data& params
19782008
= *comp->as<MxDielectric::Data>();
1979-
ok = result.bsdf.add_bsdf<MxDielectric>(cw, params, -sg.I,
1980-
sg.backfacing,
1981-
path_roughness);
2009+
2010+
if (medium_stack.false_intersection_with(result.medium_data)) {
2011+
ok = result.bsdf.add_bsdf<Transparent>(cw);
2012+
} else {
2013+
ok = result.bsdf.add_bsdf<MxDielectric>(cw, params, -sg.I,
2014+
sg.backfacing, path_roughness);
2015+
}
19822016
break;
19832017
}
19842018
case MxConductor::closureid(): {
@@ -1991,17 +2025,23 @@ process_bsdf_closure(const ShaderGlobalsType& sg, float path_roughness,
19912025
case MX_GENERALIZED_SCHLICK_ID: {
19922026
const MxGeneralizedSchlickParams& params
19932027
= *comp->as<MxGeneralizedSchlickParams>();
1994-
if (is_black(params.transmission_tint))
1995-
ok = result.bsdf.add_bsdf<MxMicrofacet<
1996-
MxGeneralizedSchlickParams, GGXDist, false>>(cw,
1997-
params,
1998-
1.0f);
1999-
else
2000-
ok = result.bsdf.add_bsdf<MxMicrofacet<
2001-
MxGeneralizedSchlickParams, GGXDist, true>>(
2002-
cw, params, result.medium_data.refraction_ior);
2028+
2029+
if (medium_stack.false_intersection_with(result.medium_data)) {
2030+
ok = result.bsdf.add_bsdf<Transparent>(cw);
2031+
} else {
2032+
if (is_black(params.transmission_tint)) {
2033+
ok = result.bsdf.add_bsdf<MxMicrofacet<
2034+
MxGeneralizedSchlickParams, GGXDist, false>>(cw,
2035+
params,
2036+
1.0f);
2037+
} else {
2038+
ok = result.bsdf.add_bsdf<MxMicrofacet<
2039+
MxGeneralizedSchlickParams, GGXDist, true>>(
2040+
cw, params, result.medium_data.refraction_ior);
2041+
}
2042+
}
20032043
break;
2004-
};
2044+
}
20052045
case MX_TRANSLUCENT_ID: {
20062046
const MxTranslucentParams* srcparams
20072047
= comp->as<MxTranslucentParams>();
@@ -2093,7 +2133,7 @@ process_closure(const ShaderGlobalsType& sg, float path_roughness,
20932133
{
20942134
if (!light_only)
20952135
process_medium_closure(sg, path_roughness, result, medium_stack, Ci, Color3(1));
2096-
process_bsdf_closure(sg, path_roughness, result, Ci, Color3(1), light_only);
2136+
process_bsdf_closure(sg, path_roughness, result, medium_stack, Ci, Color3(1), light_only);
20972137
}
20982138

20992139
OSL_HOSTDEVICE Vec3
@@ -2156,7 +2196,12 @@ BSDF::sample_vrtl(const Vec3& wo, float rx, float ry, float rz) const
21562196

21572197
Medium::Sample Medium::sample_vrtl(const Ray &ray, Sampler &sampler, Intersection& hit) const
21582198
{
2159-
return dispatch([&](auto volume) { return volume.sample(ray, sampler, hit); });
2199+
return dispatch([&](const auto& medium) { return medium.sample(ray, sampler, hit); });
2200+
}
2201+
2202+
const MediumParams* Medium::get_params_vrtl() const
2203+
{
2204+
return dispatch([&](const auto& medium) { return medium.get_params(); });
21602205
}
21612206

21622207
OSL_NAMESPACE_END

0 commit comments

Comments
 (0)