Skip to content

Commit 17c509e

Browse files
committed
Update render loop, added priority test in render-mx-medium-vdf-glass
1 parent 75a805c commit 17c509e

18 files changed

Lines changed: 304 additions & 147 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
---

src/cmake/testing.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ macro (osl_add_all_tests)
373373
render-mx-layer
374374
render-mx-sheen
375375
render-mx-medium-vdf
376+
render-mx-medium-vdf-glass
376377
render-microfacet render-oren-nayar
377378
render-spi-thinlayer
378379
render-uv render-veachmis render-ward

src/testrender/shading.cpp

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,25 +1573,21 @@ struct HomogeneousVolume final : public Medium {
15731573
return volume;
15741574
}
15751575

1576-
OSL_HOSTDEVICE Medium::Sample sample(const Ray &ray, Sampler &sampler, Intersection& hit) const
1576+
OSL_HOSTDEVICE Medium::Sample sample(Ray& r, Sampler &sampler, Intersection& hit) const
15771577
{
15781578
Vec3 rand_vol = sampler.get();
1579-
float max_sigma_t = fmaxf(fmaxf(params.sigma_t.x, params.sigma_t.y), params.sigma_t.z);
15801579

1581-
float t_volume = -logf(1.0f - rand_vol.x) / max_sigma_t;
1580+
float t_volume = -logf(1.0f - rand_vol.x) / params.avg_sigma_t();
15821581
bool volume_scatter = (t_volume < hit.t);
15831582

15841583
Color3 weight;
15851584
Color3 tr;
15861585

15871586
if (volume_scatter) {
1587+
r.origin = r.point(t_volume);
15881588
tr = transmittance(t_volume);
15891589

1590-
Color3 albedo = Color3(
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
1594-
);
1590+
Color3 albedo = params.sigma_s / params.sigma_t;
15951591

15961592
weight = albedo / tr;
15971593
} else {
@@ -1631,7 +1627,7 @@ struct EmptyVolume final : public Medium {
16311627
return volume;
16321628
}
16331629

1634-
OSL_HOSTDEVICE Medium::Sample sample(const Ray &ray, Sampler &sampler, Intersection& hit) const
1630+
OSL_HOSTDEVICE Medium::Sample sample(Ray& ray, Sampler &sampler, Intersection& hit) const
16351631
{
16361632
return { false, 0.0f, Color3(1.0f), Color3(1.0f) };
16371633
}
@@ -1783,7 +1779,7 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
17831779
result.medium_data.medium_g = params.anisotropy;
17841780
result.medium_data.priority = 0;
17851781

1786-
if (!sg.backfacing) { // if entering
1782+
if (!sg.backfacing) { // if entering
17871783
if (result.medium_data.is_vaccum()) {
17881784
medium_stack.add_medium<EmptyVolume>(result.medium_data);
17891785
} else {
@@ -1812,7 +1808,7 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
18121808
result.medium_data.refraction_ior = sg.backfacing ? 1.0f / params.ior : params.ior;
18131809
result.medium_data.priority = params.priority;
18141810

1815-
if (!sg.backfacing) { // if entering
1811+
if (!sg.backfacing) { // if entering
18161812
if (result.medium_data.is_vaccum()) {
18171813
medium_stack.add_medium<EmptyVolume>(result.medium_data);
18181814
} else {
@@ -1840,25 +1836,25 @@ process_medium_closure(const ShaderGlobalsType& sg, float path_roughness,
18401836
break;
18411837
}
18421838
case MX_GENERALIZED_SCHLICK_ID: {
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;
1839+
const ClosureComponent* comp = closure->as_comp();
1840+
const auto& params = *comp->as<MxGeneralizedSchlickParams>();
1841+
if (!is_black(weight * comp->w * params.transmission_tint)) {
1842+
float avg_F0 = clamp((params.f0.x + params.f0.y + params.f0.z) / 3.0f,
1843+
0.0f, 0.99f);
1844+
float sqrt_F0 = sqrtf(avg_F0);
1845+
float ior = (1 + sqrt_F0) / (1 - sqrt_F0);
1846+
float new_ior = sg.backfacing ? 1.0f / ior : ior;
1847+
1848+
result.medium_data.refraction_ior = new_ior;
18531849

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;
1850+
const MediumParams* current_params = medium_stack.current_params();
1851+
if (current_params && result.medium_data.priority <= current_params->priority) {
1852+
result.medium_data.refraction_ior = current_params->refraction_ior;
1853+
}
18571854
}
1855+
closure = nullptr;
1856+
break;
18581857
}
1859-
closure = nullptr;
1860-
break;
1861-
}
18621858
default: closure = nullptr; break;
18631859
}
18641860
if (closure == nullptr && stack_idx > 0) {
@@ -2194,7 +2190,7 @@ BSDF::sample_vrtl(const Vec3& wo, float rx, float ry, float rz) const
21942190
return dispatch([&](auto bsdf) { return bsdf.sample(wo, rx, ry, rz); });
21952191
}
21962192

2197-
Medium::Sample Medium::sample_vrtl(const Ray &ray, Sampler &sampler, Intersection& hit) const
2193+
Medium::Sample Medium::sample_vrtl(Ray& ray, Sampler &sampler, Intersection& hit) const
21982194
{
21992195
return dispatch([&](const auto& medium) { return medium.sample(ray, sampler, hit); });
22002196
}

src/testrender/shading.h

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ struct MxMediumVdfParams {
230230

231231
struct MediumParams {
232232
Color3 sigma_t = Color3(0.0f); // extinction coefficient
233-
Color3 sigma_s = Color3(0.0f); //scattering
233+
Color3 sigma_s = Color3(0.0f); // scattering
234234
float medium_g = 0.0f; // volumetric anisotropy
235235
float refraction_ior = 1.0f;
236236
int priority = 0;
@@ -244,6 +244,10 @@ struct MediumParams {
244244
return priority == 0;
245245
}
246246

247+
OSL_HOSTDEVICE float avg_sigma_t() const {
248+
return (sigma_t.x + sigma_t.y + sigma_t.z) / 3;
249+
}
250+
247251
OSL_HOSTDEVICE bool operator==(const MediumParams &rhs) const {
248252
return refraction_ior == rhs.refraction_ior &&
249253
medium_g == rhs.medium_g &&
@@ -377,16 +381,16 @@ struct has_equal<T, std::void_t<decltype(std::declval<const T&>() == std::declva
377381

378382
struct Medium : public AbstractMedium {
379383
struct Sample {
380-
OSL_HOSTDEVICE Sample()
381-
: scatter(false), t(0.0f), transmittance(0.0f), weight(0.0f)
384+
OSL_HOSTDEVICE Sample() :
385+
scatter(false), t(0.0f), transmittance(0.0f), weight(0.0f)
382386
{
383387
}
384-
OSL_HOSTDEVICE Sample(const Sample& o)
385-
: scatter(o.scatter), t(o.t), transmittance(o.transmittance), weight(o.weight)
388+
OSL_HOSTDEVICE Sample(const Sample& o) :
389+
scatter(o.scatter), t(o.t), transmittance(o.transmittance), weight(o.weight)
386390
{
387391
}
388-
OSL_HOSTDEVICE Sample(bool scatter, float t, Color3 transmittance, Color3 weight)
389-
: scatter(scatter), t(t), transmittance(transmittance), weight(weight)
392+
OSL_HOSTDEVICE Sample(bool scatter, float t, Color3 transmittance, Color3 weight) :
393+
scatter(scatter), t(t), transmittance(transmittance), weight(weight)
390394
{
391395
}
392396
bool scatter;
@@ -396,7 +400,7 @@ struct Medium : public AbstractMedium {
396400
};
397401

398402
template<typename LOBE>
399-
OSL_HOSTDEVICE Medium(LOBE* lobe) : AbstractMedium(lobe)
403+
OSL_HOSTDEVICE Medium(LOBE* lobe) : AbstractMedium(lobe), phase_func(nullptr)
400404
{
401405
}
402406

@@ -410,11 +414,11 @@ struct Medium : public AbstractMedium {
410414
return {};
411415
}
412416

413-
OSL_HOSTDEVICE Sample sample(const Ray &ray, Sampler &sampler, Intersection& hit) const {
417+
OSL_HOSTDEVICE Sample sample(Ray &r, Sampler &sampler, Intersection& hit) const {
414418
return {};
415419
}
416420

417-
OSL_HOSTDEVICE Sample sample_vrtl(const Ray &ray, Sampler &sampler, Intersection& hit) const;
421+
OSL_HOSTDEVICE Sample sample_vrtl(Ray &r, Sampler &sampler, Intersection& hit) const;
418422

419423
OSL_HOSTDEVICE const MediumParams* get_params_vrtl() const;
420424

@@ -554,7 +558,7 @@ struct MediumStack {
554558
}
555559

556560
OSL_HOSTDEVICE const MediumParams* current_params() const {
557-
if (depth > 0) {
561+
if (depth > 0 && mediums[0]) {
558562
const MediumParams* params = mediums[0]->get_params_vrtl();
559563
if (params) {
560564
return params;
@@ -567,21 +571,77 @@ struct MediumStack {
567571

568572
OSL_HOSTDEVICE int size() const { return depth; }
569573

574+
OSL_HOSTDEVICE bool integrate(Ray& r, Sampler& sampler, Intersection& hit, Color3& path_weight, Color3& path_radiance, float& bsdf_pdf) const
575+
{
576+
if (depth <= 0) {
577+
return false;
578+
}
579+
580+
Medium::Sample combined_sample{ false, 1.0f, Color3(1.0f), Color3(1.0f) };
581+
582+
for (int i = 0; i < depth; ++i) {
583+
Medium::Sample s = mediums[i]->sample_vrtl(r, sampler, hit);
584+
585+
combined_sample.transmittance *= s.transmittance;
586+
combined_sample.weight *= s.weight;
587+
588+
combined_sample.scatter = s.scatter || combined_sample.scatter;
589+
combined_sample.t = s.t < combined_sample.t ? s.t : combined_sample.t;
590+
}
591+
592+
if (!(combined_sample.transmittance.x > 0 || combined_sample.transmittance.y > 0 || combined_sample.transmittance.z > 0)) {
593+
return false;
594+
}
595+
596+
path_weight *= combined_sample.transmittance;
597+
598+
Vec3 rand_phase = sampler.get();
599+
if (combined_sample.scatter) {
600+
if (!mediums[0]->phase_func) {
601+
return false;
602+
}
603+
BSDF::Sample phase_sample = mediums[0]->phase_func->sample_vrtl(-r.direction,
604+
rand_phase.x,
605+
rand_phase.y,
606+
rand_phase.z);
607+
if (phase_sample.pdf <= 0.0f) {
608+
return false;
609+
}
610+
611+
path_weight *= phase_sample.weight;
612+
r.direction = phase_sample.wi;
613+
bsdf_pdf = phase_sample.pdf;
614+
return true;
615+
}
616+
617+
return false;
618+
}
619+
570620
template<typename Medium_Type, typename... Medium_Args>
571621
OSL_HOSTDEVICE bool add_medium(Medium_Args&&... args) {
572622

573-
Medium_Type* new_medium = Medium_Type::create(pool + num_bytes, std::forward<Medium_Args>(args)...);
574-
575623
if (depth >= MaxEntries)
576624
return false;
577625

578626
if (num_bytes + sizeof(Medium_Type) > MaxSize)
579627
return false;
580628

629+
Medium_Type* new_medium = Medium_Type::create(pool + num_bytes, std::forward<Medium_Args>(args)...);
630+
631+
if (!new_medium) {
632+
return false;
633+
}
634+
635+
const MediumParams* new_params = new_medium->get_params_vrtl();
581636
int insert_pos = depth;
582637

583638
for (int i = 0; i < depth; ++i) {
584-
if (new_medium->get_params_vrtl()->priority > mediums[i]->get_params_vrtl()->priority) {
639+
if (!mediums[i]) {
640+
continue;
641+
}
642+
643+
const MediumParams* existing_params = mediums[i]->get_params_vrtl();
644+
if (existing_params && new_params->priority > existing_params->priority) {
585645
insert_pos = i;
586646
break;
587647
}
@@ -601,12 +661,6 @@ struct MediumStack {
601661
OSL_HOSTDEVICE void pop_medium()
602662
{
603663
if (depth > 0) {
604-
mediums[0]->~Medium();
605-
606-
for (int i = 1; i < depth; ++i) {
607-
mediums[i - 1] = mediums[i];
608-
}
609-
610664
depth--;
611665
}
612666
}
@@ -615,6 +669,7 @@ struct MediumStack {
615669
const MediumParams* current = current_params();
616670
return (current && ((params.priority < current->priority) || (params.is_special_priority() && current->is_special_priority() && depth > 1)));
617671
}
672+
618673
private:
619674
/// Never try to copy this struct because it would invalidate the medium pointers
620675
OSL_HOSTDEVICE MediumStack(const MediumStack& c);
@@ -624,6 +679,7 @@ struct MediumStack {
624679
enum { MaxSize = 256 * sizeof(float) };
625680

626681
Medium* mediums[MaxEntries];
682+
float cdf[MaxEntries];
627683
char pool[MaxSize];
628684
int depth, num_bytes;
629685
};

src/testrender/simpleraytracer.cpp

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -994,36 +994,8 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
994994
break;
995995
}
996996

997-
const Medium* medium = medium_stack.current();
998-
bool in_medium = medium_stack.in_medium();
999-
1000-
if (in_medium && medium) {
1001-
Medium::Sample medium_sample = medium->sample_vrtl(r, sampler, hit);
1002-
1003-
path_weight *= medium_sample.transmittance;
1004-
1005-
if (!(path_weight.x > 0 || path_weight.y > 0 || path_weight.z > 0)) {
1006-
break;
1007-
}
1008-
1009-
if (medium_sample.scatter) {
1010-
r.origin = r.point(medium_sample.t);
1011-
1012-
Vec3 rand_phase = sampler.get();
1013-
BSDF::Sample phase_sample = medium->phase_func->sample_vrtl(-r.direction,
1014-
rand_phase.x,
1015-
rand_phase.y,
1016-
rand_phase.z);
1017-
if (phase_sample.pdf <= 0.0f) {
1018-
break;
1019-
}
1020-
1021-
path_weight *= phase_sample.weight;
1022-
r.direction = phase_sample.wi;
1023-
bsdf_pdf = phase_sample.pdf;
1024-
continue;
1025-
}
1026-
997+
if (medium_stack.integrate(r, sampler, hit, path_weight, path_radiance, bsdf_pdf)) {
998+
continue;
1027999
}
10281000

10291001
// construct a shader globals for the hit point
@@ -1191,7 +1163,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
11911163
r.spread = std::max(r.spread, p.roughness);
11921164
r.roughness = p.roughness;
11931165

1194-
if (sg.backfacing) {
1166+
if (sg.backfacing) { // if exiting
11951167
medium_stack.pop_medium();
11961168
}
11971169

testsuite/render-mx-medium-vdf/glossy.osl renamed to testsuite/render-mx-anisotropic-vdf/glossy.osl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,20 @@ glossy
2222
float anisotropy = 0.0
2323
[[ string description = "Anisotropy of the surface",
2424
float UImin = 0, float UImax = 1 ]],
25+
float transmission_depth = 1.0
26+
[[ string description = "Mean free path (0.0 is black, infinity is transparent)",
27+
float UImin = 0, float UImax = 100 ]],
28+
float medium_anisotropy = 1.0
29+
[[ string description = "Anisotropy of the medium",
30+
float UImin = 0, float UImax = 100 ]],
2531
int priority = 0
26-
[[ string description = "Priority of the medium. Zero is a special 'off' priority",
32+
[[ string description = "Priority for overlapping mediums. Zero is a special 'off' priority",
2733
float UImin = 0, float UImax = 8 ]], // Same as MaxEntries in MediumStack
2834
)
2935
{
3036
float alpha = roughness * roughness;
3137
float alpha_x = alpha * (1.0 - anisotropy);
3238
float alpha_y = alpha;
3339
vector U = normalize(cross(N, dPdv));
34-
Ci = dielectric_bsdf(N, U, Cr, Ct, alpha_x, alpha_y, ior, "ggx") + medium_vdf(Cr, 1.0, color(0.5), 0.0, ior, priority);
40+
Ci = dielectric_bsdf(N, U, Cr, Ct, alpha_x, alpha_y, ior, "ggx") + medium_vdf(color(0.5), transmission_depth, Cr, 0.0, ior, priority);
3541
}

testsuite/render-mx-anisotropic-vdf/run.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@
77
failthresh = 0.01
88
failpercent = 1
99
outputs = [ "out.exr" ]
10-
command = testrender("-r 256 256 -aa 16 scene.xml out.exr")
11-
12-
# Note: we pick this test arbitrarily as the one to verify llvm_opt=12 works
10+
command = testrender("-r 196 196 -aa 48 scene.xml out.exr")

0 commit comments

Comments
 (0)