Skip to content

Commit 2808967

Browse files
author
Sebastien Speierer
committed
Vectorize BSDFContext
1 parent 3875f9a commit 2808967

23 files changed

+458
-415
lines changed

include/mitsuba/render/bsdf.h

+72-13
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ MI_DECLARE_ENUM_OPERATORS(BSDFFlags)
129129
* The \ref BSDFContext data structure encodes these preferences and is
130130
* supplied to most \ref BSDF methods.
131131
*/
132-
struct MI_EXPORT_LIB BSDFContext {
132+
template <typename Float, typename Spectrum> struct BSDFContext {
133+
using Index = dr::uint32_array_t<Float>;
134+
133135
// =============================================================
134136
//! @{ \name Fields
135137
// =============================================================
@@ -141,18 +143,16 @@ struct MI_EXPORT_LIB BSDFContext {
141143
* Bit mask for requested BSDF component types to be sampled/evaluated
142144
* The default value (equal to \ref BSDFFlags::All) enables all components.
143145
*/
144-
uint32_t type_mask = (uint32_t) 0x1FFu;
146+
Index type_mask = (Index) 0x1FFu;
145147

146148
/// Integer value of requested BSDF component index to be sampled/evaluated.
147-
uint32_t component = (uint32_t) -1;
149+
Index component = (Index) -1;
148150

149151
//! @}
150152
// =============================================================
151153

152-
BSDFContext() = default;
153-
154-
BSDFContext(TransportMode mode, uint32_t type_mask = (uint32_t) 0x1FFu,
155-
uint32_t component = (uint32_t) -1)
154+
BSDFContext(TransportMode mode, Index type_mask = (Index) 0x1FFu,
155+
Index component = (Index) -1)
156156
: mode(mode), type_mask(type_mask), component(component) { }
157157

158158
/**
@@ -168,11 +168,13 @@ struct MI_EXPORT_LIB BSDFContext {
168168
* Checks whether a given BSDF component type and BSDF component index are
169169
* enabled in this context.
170170
*/
171-
bool is_enabled(BSDFFlags type_, uint32_t component_ = 0) const {
172-
uint32_t type = (uint32_t) type_;
173-
return (type_mask == (uint32_t) -1 || (type_mask & type) == type)
174-
&& (component == (uint32_t) -1 || component == component_);
171+
dr::mask_t<Float> is_enabled(Index type_, Index component_ = 0) const {
172+
Index type = (Index) type_;
173+
return (dr::eq(type_mask, (Index) -1) || dr::eq(type_mask & type, type))
174+
&& (dr::eq(component, (Index) -1) || dr::eq(component, component_));
175175
}
176+
177+
DRJIT_STRUCT(BSDFContext, mode, type_mask, component);
176178
};
177179

178180
/// Data structure holding the result of BSDF sampling operations.
@@ -550,8 +552,65 @@ class MI_EXPORT_LIB BSDF : public Object {
550552
extern MI_EXPORT_LIB std::ostream &operator<<(std::ostream &os,
551553
const TransportMode &mode);
552554

553-
extern MI_EXPORT_LIB std::ostream &operator<<(std::ostream &os,
554-
const BSDFContext& ctx);
555+
template <typename Index>
556+
std::string type_mask_to_string(Index type_mask) {
557+
std::ostringstream oss;
558+
oss << "{ ";
559+
560+
#define PROCESS(flag, name) \
561+
if (has_flag(type_mask, flag)) { \
562+
oss << #name << " "; \
563+
type_mask = type_mask & ~flag; \
564+
}
565+
PROCESS(BSDFFlags::All, all)
566+
PROCESS(BSDFFlags::Reflection, reflection)
567+
PROCESS(BSDFFlags::Transmission, transmission)
568+
PROCESS(BSDFFlags::Smooth, smooth)
569+
PROCESS(BSDFFlags::Diffuse, diffuse)
570+
PROCESS(BSDFFlags::Glossy, glossy)
571+
PROCESS(BSDFFlags::Delta, delta)
572+
PROCESS(BSDFFlags::Delta1D, delta_1d)
573+
PROCESS(BSDFFlags::DiffuseReflection, diffuse_reflection)
574+
PROCESS(BSDFFlags::DiffuseTransmission, diffuse_transmission)
575+
PROCESS(BSDFFlags::GlossyReflection, glossy_reflection)
576+
PROCESS(BSDFFlags::GlossyTransmission, glossy_transmission)
577+
PROCESS(BSDFFlags::DeltaReflection, delta_reflection)
578+
PROCESS(BSDFFlags::DeltaTransmission, delta_transmission)
579+
PROCESS(BSDFFlags::Delta1DReflection, delta_1d_reflection)
580+
PROCESS(BSDFFlags::Delta1DTransmission, delta_1d_transmission)
581+
PROCESS(BSDFFlags::Null, null)
582+
PROCESS(BSDFFlags::Anisotropic, anisotropic)
583+
PROCESS(BSDFFlags::FrontSide, front_side)
584+
PROCESS(BSDFFlags::BackSide, back_side)
585+
PROCESS(BSDFFlags::SpatiallyVarying, spatially_varying)
586+
PROCESS(BSDFFlags::NonSymmetric, non_symmetric)
587+
#undef PROCESS
588+
589+
Assert(type_mask == 0);
590+
oss << "}";
591+
return oss.str();
592+
}
593+
594+
template <typename Float, typename Spectrum>
595+
std::ostream &operator<<(std::ostream &os, const BSDFContext<Float, Spectrum>& ctx) {
596+
if constexpr (dr::is_jit_v<Float>) {
597+
os << "BSDFContext[" << std::endl
598+
<< " mode = " << ctx.mode << "," << std::endl
599+
<< " type_mask = " << ctx.type_mask << "," << std::endl
600+
<< " component = " << ctx.component;
601+
} else {
602+
os << "BSDFContext[" << std::endl
603+
<< " mode = " << ctx.mode << "," << std::endl
604+
<< " type_mask = " << type_mask_to_string(ctx.type_mask) << "," << std::endl
605+
<< " component = ";
606+
if (ctx.component == (uint32_t) -1)
607+
os << "all";
608+
else
609+
os << ctx.component;
610+
}
611+
os << std::endl << "]";
612+
return os;
613+
}
555614

556615
template <typename Float, typename Spectrum>
557616
std::ostream &operator<<(std::ostream &os, const BSDFSample3<Float, Spectrum>& bs) {

include/mitsuba/render/fwd.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
NAMESPACE_BEGIN(mitsuba)
88

9-
struct BSDFContext;
109
template <typename Float, typename Spectrum> class BSDF;
1110
template <typename Float, typename Spectrum> class OptixDenoiser;
1211
template <typename Float, typename Spectrum> class Emitter;
@@ -37,6 +36,7 @@ template <typename Float, typename Spectrum> class MeshAttribute;
3736
template <typename Float, typename Spectrum> struct DirectionSample;
3837
template <typename Float, typename Spectrum> struct PositionSample;
3938
template <typename Float, typename Spectrum> struct BSDFSample3;
39+
template <typename Float, typename Spectrum> struct BSDFContext;
4040
template <typename Float, typename Spectrum> struct PhaseFunctionContext;
4141
template <typename Float, typename Spectrum> struct Interaction;
4242
template <typename Float, typename Spectrum> struct MediumInteraction;
@@ -64,6 +64,7 @@ template <typename Float_, typename Spectrum_> struct RenderAliases {
6464
using PositionSample3f = PositionSample<Float, Spectrum>;
6565
using DirectionSample3f = DirectionSample<Float, Spectrum>;
6666
using BSDFSample3f = BSDFSample3<Float, Spectrum>;
67+
using BSDFContext = mitsuba::BSDFContext<Float, Spectrum>;
6768
using PhaseFunctionContext = mitsuba::PhaseFunctionContext<Float, Spectrum>;
6869
using Interaction3f = Interaction<Float, Spectrum>;
6970
using MediumInteraction3f = MediumInteraction<Float, Spectrum>;
@@ -155,6 +156,7 @@ template <typename Float_, typename Spectrum_> struct RenderAliases {
155156
using MediumInteraction3f = typename RenderAliases::MediumInteraction3f; \
156157
using PreliminaryIntersection3f = typename RenderAliases::PreliminaryIntersection3f; \
157158
using BSDFSample3f = typename RenderAliases::BSDFSample3f; \
159+
using BSDFContext = typename RenderAliases::BSDFContext; \
158160
DRJIT_MAP(MI_IMPORT_TYPES_MACRO, __VA_ARGS__)
159161

160162
#define MI_IMPORT_OBJECT_TYPES() \

src/bsdfs/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ add_plugin(dielectric dielectric.cpp)
77
add_plugin(diffuse diffuse.cpp)
88
add_plugin(mask mask.cpp)
99
add_plugin(measured measured.cpp)
10+
add_plugin(measured_polarized measured_polarized.cpp)
1011
add_plugin(normalmap normalmap.cpp)
1112
add_plugin(null null.cpp)
1213
add_plugin(plastic plastic.cpp)
14+
add_plugin(pplastic pplastic.cpp)
1315
add_plugin(roughconductor roughconductor.cpp)
1416
add_plugin(roughdielectric roughdielectric.cpp)
1517
add_plugin(roughplastic roughplastic.cpp)
@@ -18,8 +20,6 @@ add_plugin(twosided twosided.cpp)
1820
add_plugin(polarizer polarizer.cpp)
1921
add_plugin(retarder retarder.cpp)
2022
add_plugin(circular circular.cpp)
21-
add_plugin(measured_polarized measured_polarized.cpp)
22-
add_plugin(pplastic pplastic.cpp)
2323
add_plugin(principled principled.cpp)
2424
add_plugin(principledthin principledthin.cpp)
2525

src/bsdfs/blendbsdf.cpp

+77-44
Original file line numberDiff line numberDiff line change
@@ -115,24 +115,27 @@ class BlendBSDF final : public BSDF<Float, Spectrum> {
115115
Mask active) const override {
116116
MI_MASKED_FUNCTION(ProfilerPhase::BSDFSample, active);
117117

118+
BSDFSample3f bs = dr::zeros<BSDFSample3f>();
119+
Spectrum result(0.f);
120+
121+
Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);
122+
118123
Float weight = eval_weight(si, active);
119-
if (unlikely(ctx.component != (uint32_t) -1)) {
120-
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();
124+
125+
if (dr::any_or<true>(!sample_all)) {
126+
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
121127
BSDFContext ctx2(ctx);
122-
if (!sample_first)
123-
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
124-
else
125-
weight = 1.f - weight;
126-
auto [bs, result] = m_nested_bsdf[sample_first ? 0 : 1]->sample(ctx2, si, sample1, sample2, active);
127-
result *= weight;
128-
return { bs, result };
128+
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
129+
dr::masked(weight, sample_first) = 1.f - weight;
130+
auto [bs_, result_] = dr::select(sample_first,
131+
m_nested_bsdf[0]->sample(ctx2, si, sample1, sample2, active),
132+
m_nested_bsdf[1]->sample(ctx2, si, sample1, sample2, active));
133+
dr::masked(bs, !sample_all) = bs_;
134+
dr::masked(result, !sample_all) = result_ * weight;
129135
}
130136

131-
BSDFSample3f bs = dr::zeros<BSDFSample3f>();
132-
Spectrum result(0.f);
133-
134-
Mask m0 = active && sample1 > weight,
135-
m1 = active && sample1 <= weight;
137+
Mask m0 = active && sample1 > weight && sample_all,
138+
m1 = active && sample1 <= weight && sample_all;
136139

137140
if (dr::any_or<true>(m0)) {
138141
auto [bs0, result0] = m_nested_bsdf[0]->sample(
@@ -155,36 +158,57 @@ class BlendBSDF final : public BSDF<Float, Spectrum> {
155158
const Vector3f &wo, Mask active) const override {
156159
MI_MASKED_FUNCTION(ProfilerPhase::BSDFEvaluate, active);
157160

161+
Spectrum result(0.f);
162+
163+
Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);
158164
Float weight = eval_weight(si, active);
159-
if (unlikely(ctx.component != (uint32_t) -1)) {
160-
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();
165+
166+
if (dr::any_or<true>(!sample_all)) {
167+
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
161168
BSDFContext ctx2(ctx);
162-
if (!sample_first)
163-
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
164-
else
165-
weight = 1.f - weight;
166-
return weight * m_nested_bsdf[sample_first ? 0 : 1]->eval(ctx2, si, wo, active);
169+
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
170+
dr::masked(weight, sample_first) = 1.f - weight;
171+
dr::masked(result, !sample_all) =
172+
weight * dr::select(sample_first,
173+
m_nested_bsdf[0]->eval(ctx2, si, wo, active),
174+
m_nested_bsdf[1]->eval(ctx2, si, wo, active));
167175
}
168176

169-
return m_nested_bsdf[0]->eval(ctx, si, wo, active) * (1 - weight) +
170-
m_nested_bsdf[1]->eval(ctx, si, wo, active) * weight;
177+
if (dr::any_or<true>(sample_all)) {
178+
dr::masked(result, sample_all) =
179+
m_nested_bsdf[0]->eval(ctx, si, wo, active) * (1 - weight) +
180+
m_nested_bsdf[1]->eval(ctx, si, wo, active) * weight;
181+
}
182+
183+
return result;
171184
}
172185

173186
Float pdf(const BSDFContext &ctx, const SurfaceInteraction3f &si,
174187
const Vector3f &wo, Mask active) const override {
175188
MI_MASKED_FUNCTION(ProfilerPhase::BSDFEvaluate, active);
176189

177-
if (unlikely(ctx.component != (uint32_t) -1)) {
178-
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();
190+
Float result(0.f);
191+
192+
Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);
193+
194+
if (dr::any_or<true>(!sample_all)) {
195+
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
179196
BSDFContext ctx2(ctx);
180-
if (!sample_first)
181-
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
182-
return m_nested_bsdf[sample_first ? 0 : 1]->pdf(ctx2, si, wo, active);
197+
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
198+
dr::masked(result, !sample_all) =
199+
dr::select(sample_first,
200+
m_nested_bsdf[0]->pdf(ctx2, si, wo, active),
201+
m_nested_bsdf[1]->pdf(ctx2, si, wo, active));
183202
}
184203

185-
Float weight = eval_weight(si, active);
186-
return m_nested_bsdf[0]->pdf(ctx, si, wo, active) * (1 - weight) +
187-
m_nested_bsdf[1]->pdf(ctx, si, wo, active) * weight;
204+
if (dr::any_or<true>(sample_all)) {
205+
Float weight = eval_weight(si, active);
206+
dr::masked(result, sample_all) =
207+
m_nested_bsdf[0]->pdf(ctx, si, wo, active) * (1 - weight) +
208+
m_nested_bsdf[1]->pdf(ctx, si, wo, active) * weight;
209+
}
210+
211+
return result;
188212
}
189213

190214
std::pair<Spectrum, Float> eval_pdf(const BSDFContext &ctx,
@@ -193,24 +217,33 @@ class BlendBSDF final : public BSDF<Float, Spectrum> {
193217
Mask active) const override {
194218
MI_MASKED_FUNCTION(ProfilerPhase::BSDFEvaluate, active);
195219

220+
Spectrum val(0.f);
221+
Float pdf(0.f);
222+
223+
Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);
196224
Float weight = eval_weight(si, active);
197-
if (unlikely(ctx.component != (uint32_t) -1)) {
198-
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();
199-
BSDFContext ctx2(ctx);
200-
if (!sample_first)
201-
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
202-
else
203-
weight = 1.f - weight;
204225

205-
auto [val, pdf] = m_nested_bsdf[sample_first ? 0 : 1]->eval_pdf(ctx2, si, wo, active);
206-
return { weight * val, pdf };
226+
if (dr::any_or<true>(!sample_all)) {
227+
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
228+
BSDFContext ctx2(ctx);
229+
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
230+
dr::masked(weight, sample_first) = 1.f - weight;
231+
auto [val_, pdf_] =
232+
dr::select(sample_first,
233+
m_nested_bsdf[0]->eval_pdf(ctx2, si, wo, active),
234+
m_nested_bsdf[1]->eval_pdf(ctx2, si, wo, active));
235+
dr::masked(val, !sample_all) = weight * val_;
236+
dr::masked(pdf, !sample_all) = pdf_;
207237
}
208238

209-
auto [val_0, pdf_0] = m_nested_bsdf[0]->eval_pdf(ctx, si, wo, active);
210-
auto [val_1, pdf_1] = m_nested_bsdf[1]->eval_pdf(ctx, si, wo, active);
239+
if (dr::any_or<true>(sample_all)) {
240+
auto [val_0, pdf_0] = m_nested_bsdf[0]->eval_pdf(ctx, si, wo, active);
241+
auto [val_1, pdf_1] = m_nested_bsdf[1]->eval_pdf(ctx, si, wo, active);
242+
dr::masked(val, sample_all) = val_0 * (1 - weight) + val_1 * weight;
243+
dr::masked(pdf, sample_all) = pdf_0 * (1 - weight) + pdf_1 * weight;
244+
}
211245

212-
return { val_0 * (1 - weight) + val_1 * weight,
213-
pdf_0 * (1 - weight) + pdf_1 * weight };
246+
return { val, pdf };
214247
}
215248

216249
MI_INLINE Float eval_weight(const SurfaceInteraction3f &si, const Mask &active) const {

src/bsdfs/conductor.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,10 @@ class SmoothConductor final : public BSDF<Float, Spectrum> {
257257

258258
BSDFSample3f bs = dr::zeros<BSDFSample3f>();
259259
Spectrum value(0.f);
260-
if (unlikely(dr::none_or<false>(active) || !ctx.is_enabled(BSDFFlags::DeltaReflection)))
260+
261+
active &= ctx.is_enabled(+BSDFFlags::DeltaReflection);
262+
263+
if (unlikely(dr::none_or<false>(active)))
261264
return { bs, value };
262265

263266
bs.sampled_component = 0;

0 commit comments

Comments
 (0)