Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vectorize BSDFContext #731

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 72 additions & 13 deletions include/mitsuba/render/bsdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ MI_DECLARE_ENUM_OPERATORS(BSDFFlags)
* The \ref BSDFContext data structure encodes these preferences and is
* supplied to most \ref BSDF methods.
*/
struct MI_EXPORT_LIB BSDFContext {
template <typename Float, typename Spectrum> struct BSDFContext {
using Index = dr::uint32_array_t<Float>;

// =============================================================
//! @{ \name Fields
// =============================================================
Expand All @@ -141,18 +143,16 @@ struct MI_EXPORT_LIB BSDFContext {
* Bit mask for requested BSDF component types to be sampled/evaluated
* The default value (equal to \ref BSDFFlags::All) enables all components.
*/
uint32_t type_mask = (uint32_t) 0x1FFu;
Index type_mask = (Index) 0x1FFu;

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

//! @}
// =============================================================

BSDFContext() = default;

BSDFContext(TransportMode mode, uint32_t type_mask = (uint32_t) 0x1FFu,
uint32_t component = (uint32_t) -1)
BSDFContext(TransportMode mode, Index type_mask = (Index) 0x1FFu,
Index component = (Index) -1)
: mode(mode), type_mask(type_mask), component(component) { }

/**
Expand All @@ -168,11 +168,13 @@ struct MI_EXPORT_LIB BSDFContext {
* Checks whether a given BSDF component type and BSDF component index are
* enabled in this context.
*/
bool is_enabled(BSDFFlags type_, uint32_t component_ = 0) const {
uint32_t type = (uint32_t) type_;
return (type_mask == (uint32_t) -1 || (type_mask & type) == type)
&& (component == (uint32_t) -1 || component == component_);
dr::mask_t<Float> is_enabled(Index type_, Index component_ = 0) const {
Index type = (Index) type_;
return (dr::eq(type_mask, (Index) -1) || dr::eq(type_mask & type, type))
&& (dr::eq(component, (Index) -1) || dr::eq(component, component_));
}

DRJIT_STRUCT(BSDFContext, mode, type_mask, component);
};

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

extern MI_EXPORT_LIB std::ostream &operator<<(std::ostream &os,
const BSDFContext& ctx);
template <typename Index>
std::string type_mask_to_string(Index type_mask) {
std::ostringstream oss;
oss << "{ ";

#define PROCESS(flag, name) \
if (has_flag(type_mask, flag)) { \
oss << #name << " "; \
type_mask = type_mask & ~flag; \
}
PROCESS(BSDFFlags::All, all)
PROCESS(BSDFFlags::Reflection, reflection)
PROCESS(BSDFFlags::Transmission, transmission)
PROCESS(BSDFFlags::Smooth, smooth)
PROCESS(BSDFFlags::Diffuse, diffuse)
PROCESS(BSDFFlags::Glossy, glossy)
PROCESS(BSDFFlags::Delta, delta)
PROCESS(BSDFFlags::Delta1D, delta_1d)
PROCESS(BSDFFlags::DiffuseReflection, diffuse_reflection)
PROCESS(BSDFFlags::DiffuseTransmission, diffuse_transmission)
PROCESS(BSDFFlags::GlossyReflection, glossy_reflection)
PROCESS(BSDFFlags::GlossyTransmission, glossy_transmission)
PROCESS(BSDFFlags::DeltaReflection, delta_reflection)
PROCESS(BSDFFlags::DeltaTransmission, delta_transmission)
PROCESS(BSDFFlags::Delta1DReflection, delta_1d_reflection)
PROCESS(BSDFFlags::Delta1DTransmission, delta_1d_transmission)
PROCESS(BSDFFlags::Null, null)
PROCESS(BSDFFlags::Anisotropic, anisotropic)
PROCESS(BSDFFlags::FrontSide, front_side)
PROCESS(BSDFFlags::BackSide, back_side)
PROCESS(BSDFFlags::SpatiallyVarying, spatially_varying)
PROCESS(BSDFFlags::NonSymmetric, non_symmetric)
#undef PROCESS

Assert(type_mask == 0);
oss << "}";
return oss.str();
}

template <typename Float, typename Spectrum>
std::ostream &operator<<(std::ostream &os, const BSDFContext<Float, Spectrum>& ctx) {
if constexpr (dr::is_jit_v<Float>) {
os << "BSDFContext[" << std::endl
<< " mode = " << ctx.mode << "," << std::endl
<< " type_mask = " << ctx.type_mask << "," << std::endl
<< " component = " << ctx.component;
} else {
os << "BSDFContext[" << std::endl
<< " mode = " << ctx.mode << "," << std::endl
<< " type_mask = " << type_mask_to_string(ctx.type_mask) << "," << std::endl
<< " component = ";
if (ctx.component == (uint32_t) -1)
os << "all";
else
os << ctx.component;
}
os << std::endl << "]";
return os;
}

template <typename Float, typename Spectrum>
std::ostream &operator<<(std::ostream &os, const BSDFSample3<Float, Spectrum>& bs) {
Expand Down
4 changes: 3 additions & 1 deletion include/mitsuba/render/fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

NAMESPACE_BEGIN(mitsuba)

struct BSDFContext;
template <typename Float, typename Spectrum> class BSDF;
template <typename Float, typename Spectrum> class OptixDenoiser;
template <typename Float, typename Spectrum> class Emitter;
Expand Down Expand Up @@ -37,6 +36,7 @@ template <typename Float, typename Spectrum> class MeshAttribute;
template <typename Float, typename Spectrum> struct DirectionSample;
template <typename Float, typename Spectrum> struct PositionSample;
template <typename Float, typename Spectrum> struct BSDFSample3;
template <typename Float, typename Spectrum> struct BSDFContext;
template <typename Float, typename Spectrum> struct PhaseFunctionContext;
template <typename Float, typename Spectrum> struct Interaction;
template <typename Float, typename Spectrum> struct MediumInteraction;
Expand Down Expand Up @@ -64,6 +64,7 @@ template <typename Float_, typename Spectrum_> struct RenderAliases {
using PositionSample3f = PositionSample<Float, Spectrum>;
using DirectionSample3f = DirectionSample<Float, Spectrum>;
using BSDFSample3f = BSDFSample3<Float, Spectrum>;
using BSDFContext = mitsuba::BSDFContext<Float, Spectrum>;
using PhaseFunctionContext = mitsuba::PhaseFunctionContext<Float, Spectrum>;
using Interaction3f = Interaction<Float, Spectrum>;
using MediumInteraction3f = MediumInteraction<Float, Spectrum>;
Expand Down Expand Up @@ -155,6 +156,7 @@ template <typename Float_, typename Spectrum_> struct RenderAliases {
using MediumInteraction3f = typename RenderAliases::MediumInteraction3f; \
using PreliminaryIntersection3f = typename RenderAliases::PreliminaryIntersection3f; \
using BSDFSample3f = typename RenderAliases::BSDFSample3f; \
using BSDFContext = typename RenderAliases::BSDFContext; \
DRJIT_MAP(MI_IMPORT_TYPES_MACRO, __VA_ARGS__)

#define MI_IMPORT_OBJECT_TYPES() \
Expand Down
4 changes: 2 additions & 2 deletions src/bsdfs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ add_plugin(dielectric dielectric.cpp)
add_plugin(diffuse diffuse.cpp)
add_plugin(mask mask.cpp)
add_plugin(measured measured.cpp)
add_plugin(measured_polarized measured_polarized.cpp)
add_plugin(normalmap normalmap.cpp)
add_plugin(null null.cpp)
add_plugin(plastic plastic.cpp)
add_plugin(pplastic pplastic.cpp)
add_plugin(roughconductor roughconductor.cpp)
add_plugin(roughdielectric roughdielectric.cpp)
add_plugin(roughplastic roughplastic.cpp)
Expand All @@ -18,8 +20,6 @@ add_plugin(twosided twosided.cpp)
add_plugin(polarizer polarizer.cpp)
add_plugin(retarder retarder.cpp)
add_plugin(circular circular.cpp)
add_plugin(measured_polarized measured_polarized.cpp)
add_plugin(pplastic pplastic.cpp)
add_plugin(principled principled.cpp)
add_plugin(principledthin principledthin.cpp)

Expand Down
121 changes: 77 additions & 44 deletions src/bsdfs/blendbsdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,27 @@ class BlendBSDF final : public BSDF<Float, Spectrum> {
Mask active) const override {
MI_MASKED_FUNCTION(ProfilerPhase::BSDFSample, active);

BSDFSample3f bs = dr::zeros<BSDFSample3f>();
Spectrum result(0.f);

Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);

Float weight = eval_weight(si, active);
if (unlikely(ctx.component != (uint32_t) -1)) {
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();

if (dr::any_or<true>(!sample_all)) {
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
BSDFContext ctx2(ctx);
if (!sample_first)
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
else
weight = 1.f - weight;
auto [bs, result] = m_nested_bsdf[sample_first ? 0 : 1]->sample(ctx2, si, sample1, sample2, active);
result *= weight;
return { bs, result };
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
dr::masked(weight, sample_first) = 1.f - weight;
auto [bs_, result_] = dr::select(sample_first,
m_nested_bsdf[0]->sample(ctx2, si, sample1, sample2, active),
m_nested_bsdf[1]->sample(ctx2, si, sample1, sample2, active));
dr::masked(bs, !sample_all) = bs_;
dr::masked(result, !sample_all) = result_ * weight;
}

BSDFSample3f bs = dr::zeros<BSDFSample3f>();
Spectrum result(0.f);

Mask m0 = active && sample1 > weight,
m1 = active && sample1 <= weight;
Mask m0 = active && sample1 > weight && sample_all,
m1 = active && sample1 <= weight && sample_all;

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

Spectrum result(0.f);

Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);
Float weight = eval_weight(si, active);
if (unlikely(ctx.component != (uint32_t) -1)) {
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();

if (dr::any_or<true>(!sample_all)) {
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
BSDFContext ctx2(ctx);
if (!sample_first)
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
else
weight = 1.f - weight;
return weight * m_nested_bsdf[sample_first ? 0 : 1]->eval(ctx2, si, wo, active);
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
dr::masked(weight, sample_first) = 1.f - weight;
dr::masked(result, !sample_all) =
weight * dr::select(sample_first,
m_nested_bsdf[0]->eval(ctx2, si, wo, active),
m_nested_bsdf[1]->eval(ctx2, si, wo, active));
}

return m_nested_bsdf[0]->eval(ctx, si, wo, active) * (1 - weight) +
m_nested_bsdf[1]->eval(ctx, si, wo, active) * weight;
if (dr::any_or<true>(sample_all)) {
dr::masked(result, sample_all) =
m_nested_bsdf[0]->eval(ctx, si, wo, active) * (1 - weight) +
m_nested_bsdf[1]->eval(ctx, si, wo, active) * weight;
}

return result;
}

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

if (unlikely(ctx.component != (uint32_t) -1)) {
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();
Float result(0.f);

Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);

if (dr::any_or<true>(!sample_all)) {
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
BSDFContext ctx2(ctx);
if (!sample_first)
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
return m_nested_bsdf[sample_first ? 0 : 1]->pdf(ctx2, si, wo, active);
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
dr::masked(result, !sample_all) =
dr::select(sample_first,
m_nested_bsdf[0]->pdf(ctx2, si, wo, active),
m_nested_bsdf[1]->pdf(ctx2, si, wo, active));
}

Float weight = eval_weight(si, active);
return m_nested_bsdf[0]->pdf(ctx, si, wo, active) * (1 - weight) +
m_nested_bsdf[1]->pdf(ctx, si, wo, active) * weight;
if (dr::any_or<true>(sample_all)) {
Float weight = eval_weight(si, active);
dr::masked(result, sample_all) =
m_nested_bsdf[0]->pdf(ctx, si, wo, active) * (1 - weight) +
m_nested_bsdf[1]->pdf(ctx, si, wo, active) * weight;
}

return result;
}

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

Spectrum val(0.f);
Float pdf(0.f);

Mask sample_all = dr::eq(ctx.component, (uint32_t) -1);
Float weight = eval_weight(si, active);
if (unlikely(ctx.component != (uint32_t) -1)) {
bool sample_first = ctx.component < m_nested_bsdf[0]->component_count();
BSDFContext ctx2(ctx);
if (!sample_first)
ctx2.component -= (uint32_t) m_nested_bsdf[0]->component_count();
else
weight = 1.f - weight;

auto [val, pdf] = m_nested_bsdf[sample_first ? 0 : 1]->eval_pdf(ctx2, si, wo, active);
return { weight * val, pdf };
if (dr::any_or<true>(!sample_all)) {
Mask sample_first = ctx.component < m_nested_bsdf[0]->component_count();
BSDFContext ctx2(ctx);
dr::masked(ctx2.component, !sample_first) -= (uint32_t) m_nested_bsdf[0]->component_count();
dr::masked(weight, sample_first) = 1.f - weight;
auto [val_, pdf_] =
dr::select(sample_first,
m_nested_bsdf[0]->eval_pdf(ctx2, si, wo, active),
m_nested_bsdf[1]->eval_pdf(ctx2, si, wo, active));
dr::masked(val, !sample_all) = weight * val_;
dr::masked(pdf, !sample_all) = pdf_;
}

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

return { val_0 * (1 - weight) + val_1 * weight,
pdf_0 * (1 - weight) + pdf_1 * weight };
return { val, pdf };
}

MI_INLINE Float eval_weight(const SurfaceInteraction3f &si, const Mask &active) const {
Expand Down
5 changes: 4 additions & 1 deletion src/bsdfs/conductor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ class SmoothConductor final : public BSDF<Float, Spectrum> {

BSDFSample3f bs = dr::zeros<BSDFSample3f>();
Spectrum value(0.f);
if (unlikely(dr::none_or<false>(active) || !ctx.is_enabled(BSDFFlags::DeltaReflection)))

active &= ctx.is_enabled(+BSDFFlags::DeltaReflection);

if (unlikely(dr::none_or<false>(active)))
return { bs, value };

bs.sampled_component = 0;
Expand Down
Loading