Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike-Leo-Smith committed Jan 13, 2024
1 parent f50aeef commit f8cb3cc
Show file tree
Hide file tree
Showing 14 changed files with 304 additions and 542 deletions.
93 changes: 35 additions & 58 deletions src/base/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,39 @@ void Geometry::_process_shape(
}
}

void Geometry::_alpha_skip(SurfaceCandidate &c) const noexcept {
$outline {
auto hit = c.hit();
auto ray = c.ray();
auto bary = make_float3(1.f - hit.bary.x - hit.bary.y, hit.bary);
auto it = interaction(hit.inst, hit.prim, bary, -ray->direction());
$if(it->shape().maybe_non_opaque() & it->shape().has_surface()) {
auto u = xxhash32(make_uint4(hit.inst, hit.prim, compute::as<uint2>(hit.bary))) * 0x1p-32f;
$switch(it->shape().surface_tag()) {
for (auto i = 0u; i < _pipeline.surfaces().size(); i++) {
if (auto surface = _pipeline.surfaces().impl(i);
surface->maybe_non_opaque()) {
$case(i) {
// TODO: pass the correct swl and time
if (auto opacity = surface->evaluate_opacity(*it, _pipeline.spectrum()->sample(.5f), 0.f)) {
$if (u < *opacity) {
c.commit();
};
} else {
c.commit();
}
};
}
}
$default { compute::unreachable(); };
};
}
$else {
c.commit();
};
};
}

bool Geometry::update(CommandBuffer &command_buffer, float time) noexcept {
auto updated = false;
if (!_dynamic_transforms.empty()) {
Expand Down Expand Up @@ -195,35 +228,7 @@ Var<Hit> Geometry::trace_closest(const Var<Ray> &ray) const noexcept {
auto rq_hit =
_accel->traverse(ray, {})
.on_surface_candidate([&](compute::SurfaceCandidate &c) noexcept {
auto hit = c.hit();
auto bary = make_float3(1.f - hit.bary.x - hit.bary.y, hit.bary);
auto it = interaction(hit.inst, hit.prim, bary, -ray->direction());
$if(it->shape().maybe_non_opaque() & it->shape().has_surface()) {
PolymorphicCall<Surface::Closure> call;
_pipeline.surfaces().dispatch(it->shape().surface_tag(), [&](auto surface) noexcept {
if (surface->maybe_non_opaque()) {
// TODO: pass the correct time
surface->closure(call, *it, _pipeline.spectrum()->sample(.5f), -ray->direction(), 1.f, 0.f);
} else {
compute::unreachable();
}
});
auto u = xxhash32(make_uint4(hit.inst, hit.prim, compute::as<uint2>(hit.bary))) * 0x1p-32f;
call.execute([&](const Surface::Closure *closure) noexcept {
// apply opacity map
auto alpha_skip = def(false);
if (auto o = closure->opacity()) {
auto opacity = saturate(*o);
alpha_skip = u >= opacity;
}
$if(!alpha_skip) {
c.commit();
};
});
}
$else {
c.commit();
};
this->_alpha_skip(c);
})
.trace();
return Var<Hit>{rq_hit.inst, rq_hit.prim, rq_hit.bary};
Expand All @@ -237,35 +242,7 @@ Var<bool> Geometry::trace_any(const Var<Ray> &ray) const noexcept {
auto rq_hit =
_accel->traverse_any(ray, {})
.on_surface_candidate([&](compute::SurfaceCandidate &c) noexcept {
auto hit = c.hit();
auto bary = make_float3(1.f - hit.bary.x - hit.bary.y, hit.bary);
auto it = interaction(hit.inst, hit.prim, bary, -ray->direction());
$if(it->shape().maybe_non_opaque() & it->shape().has_surface()) {
PolymorphicCall<Surface::Closure> call;
_pipeline.surfaces().dispatch(it->shape().surface_tag(), [&](auto surface) noexcept {
if (surface->maybe_non_opaque()) {
// TODO: pass the correct time
surface->closure(call, *it, _pipeline.spectrum()->sample(.5f), -ray->direction(), 1.f, 0.f);
} else {
compute::unreachable();
}
});
auto u = xxhash32(make_uint4(hit.inst, hit.prim, compute::as<uint2>(hit.bary))) * 0x1p-32f;
call.execute([&](const Surface::Closure *closure) noexcept {
// apply opacity map
auto alpha_skip = def(false);
if (auto o = closure->opacity()) {
auto opacity = saturate(*o);
alpha_skip = u >= opacity;
}
$if(!alpha_skip) {
c.commit();
};
});
}
$else {
c.commit();
};
this->_alpha_skip(c);
})
.trace();
return !rq_hit->miss();
Expand Down
6 changes: 5 additions & 1 deletion src/base/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class Geometry {

static_assert(sizeof(MeshData) == 16u);

using SurfaceCandidate = compute::SurfaceCandidate;

private:
Pipeline &_pipeline;
Accel _accel;
Expand All @@ -69,7 +71,7 @@ class Geometry {
Buffer<uint4> _instance_buffer;
float3 _world_min;
float3 _world_max;
uint _triangle_count;// for debug
uint _triangle_count{};// for debug
bool _any_non_opaque{false};

private:
Expand All @@ -80,6 +82,8 @@ class Geometry {
const Medium *overridden_medium = nullptr,
bool overridden_visible = true) noexcept;

void _alpha_skip(SurfaceCandidate &c) const noexcept;

public:
explicit Geometry(Pipeline &pipeline) noexcept : _pipeline{pipeline} {};
void build(CommandBuffer &command_buffer,
Expand Down
97 changes: 12 additions & 85 deletions src/base/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ class Surface : public SceneNode {
TransportMode mode = TransportMode::RADIANCE) const noexcept;

// surface properties
[[nodiscard]] virtual luisa::optional<Float> opacity() const noexcept { return nullopt; } // nullopt if never possible to be non-opaque
[[nodiscard]] virtual luisa::optional<Float> eta() const noexcept { return nullopt; } // nullopt if never possible to be transmissive
[[nodiscard]] virtual luisa::optional<Bool> is_dispersive() const noexcept { return nullopt; }// nullopt if never possible to be dispersive
[[nodiscard]] virtual const Interaction &it() const noexcept = 0;
Expand Down Expand Up @@ -129,6 +128,10 @@ class Surface : public SceneNode {
[[nodiscard]] auto &pipeline() const noexcept { return _pipeline; }

[[nodiscard]] virtual bool maybe_non_opaque() const noexcept { return false; }
[[nodiscard]] virtual luisa::optional<Float> evaluate_opacity(
const Interaction &it,
const SampledWavelengths &swl,
Expr<float> time) const noexcept { return luisa::nullopt; }

void closure(PolymorphicCall<Closure> &call,
const Interaction &it, const SampledWavelengths &swl,
Expand Down Expand Up @@ -162,62 +165,6 @@ class OpacitySurfaceWrapper : public BaseSurface {
std::derived_from<BaseInstance, Surface::Instance>);

public:
class Closure final : public Surface::Closure {

private:
luisa::unique_ptr<Surface::Closure> _base;

public:
struct Context {
Float opacity;
};

public:
Closure(const Pipeline &pipeline,
const SampledWavelengths &swl,
Expr<float> time,
luisa::unique_ptr<Surface::Closure> base) noexcept
: Surface::Closure{pipeline, swl, time},
_base{std::move(base)} {}
[[nodiscard]] auto base() const noexcept { return _base.get(); }

public:
[[nodiscard]] SampledSpectrum albedo() const noexcept override {
return _base->albedo();
}
[[nodiscard]] Float2 roughness() const noexcept override {
return _base->roughness();
}
[[nodiscard]] const Interaction &it() const noexcept override {
return _base->it();
}
[[nodiscard]] luisa::optional<Float> opacity() const noexcept override {
return context<Context>().opacity;
}
[[nodiscard]] optional<Float> eta() const noexcept override {
return _base->eta();
}
[[nodiscard]] optional<Bool> is_dispersive() const noexcept override {
return _base->is_dispersive();
}

public:
void pre_eval() noexcept override { _base->pre_eval(); }
void post_eval() noexcept override { _base->post_eval(); }

private:
[[nodiscard]] Surface::Evaluation _evaluate(Expr<float3> wo,
Expr<float3> wi,
TransportMode mode) const noexcept override {
return _base->_evaluate(wo, wi, mode);
}
[[nodiscard]] Surface::Sample _sample(Expr<float3> wo,
Expr<float> u_lobe, Expr<float2> u,
TransportMode mode) const noexcept override {
return _base->_sample(wo, u_lobe, u, mode);
}
};

class Instance : public BaseInstance {

private:
Expand All @@ -227,39 +174,19 @@ class OpacitySurfaceWrapper : public BaseSurface {
Instance(BaseInstance &&base, const Texture::Instance *opacity) noexcept
: BaseInstance{std::move(base)}, _opacity{opacity} {}

public:
[[nodiscard]] luisa::string closure_identifier() const noexcept override {
auto base_identifier = BaseInstance::closure_identifier();
if (_opacity == nullptr) { return base_identifier; }
return luisa::format("opacity<{}>", base_identifier);
}
[[nodiscard]] luisa::unique_ptr<Surface::Closure> create_closure(
const SampledWavelengths &swl, Expr<float> time) const noexcept override {
auto base = BaseInstance::create_closure(swl, time);
if (_opacity == nullptr) { return base; }
Closure cls{this->pipeline(), swl, time, std::move(base)};
return luisa::make_unique<Closure>(std::move(cls));
}
void populate_closure(Surface::Closure *closure_in, const Interaction &it,
Expr<float3> wo, Expr<float> eta_i) const noexcept override {
if (_opacity == nullptr) {
BaseInstance::populate_closure(closure_in, it, wo, eta_i);
return;
}
auto closure = static_cast<Closure *>(closure_in);
auto &swl = closure->swl();
auto time = closure->time();
BaseInstance::populate_closure(closure->base(), it, wo, eta_i);
auto o = _opacity->evaluate(it, swl, time).x;
typename Closure::Context ctx{.opacity = o};
closure->bind(std::move(ctx));
}

[[nodiscard]] bool maybe_non_opaque() const noexcept override {
if (BaseInstance::maybe_non_opaque()) { return true; }
return _opacity != nullptr &&
_opacity->node()->evaluate_static().value_or(make_float4(0.f)).x < 1.f;
}

[[nodiscard]] luisa::optional<Float> evaluate_opacity(const Interaction &it,
const SampledWavelengths &swl,
Expr<float> time) const noexcept override {
if (!maybe_non_opaque()) { return luisa::nullopt; }
auto base_alpha = BaseInstance::evaluate_opacity(it, swl, time).value_or(1.f);
return base_alpha * _opacity->evaluate(it, swl, time).x;
}
};

private:
Expand Down
64 changes: 24 additions & 40 deletions src/integrators/aov.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,49 +329,33 @@ void AuxiliaryBufferPathTracingInstance::_render_one_camera(
if (auto dispersive = closure->is_dispersive()) {
$if(*dispersive) { swl.terminate_secondary(); };
}

// apply opacity map
auto alpha_skip = def(false);
if (auto o = closure->opacity()) {
auto opacity = saturate(*o);
alpha_skip = u_lobe >= opacity;
u_lobe = ite(alpha_skip, (u_lobe - opacity) / (1.f - opacity), u_lobe / opacity);
}

$if(alpha_skip) {
ray = it->spawn_ray(ray->direction());
pdf_bsdf = 1e16f;
}
$else {

// direct lighting
$if(light_sample.eval.pdf > 0.0f & !occluded) {
auto wi = light_sample.shadow_ray->direction();
auto eval = closure->evaluate(wo, wi);
auto w = balance_heuristic(light_sample.eval.pdf, eval.pdf) /
light_sample.eval.pdf;
Li += w * beta * eval.f * light_sample.eval.L;
$if(!specular_bounce) {
Li_diffuse += w * beta_diffuse * eval.f * light_sample.eval.L;
};
};

// sample material
auto sample = closure->sample(wo, u_lobe, u_bsdf);
ray = it->spawn_ray(sample.wi);
pdf_bsdf = sample.eval.pdf;
auto w = ite(sample.eval.pdf > 0.f, 1.f / sample.eval.pdf, 0.f);
beta *= w * sample.eval.f;
// direct lighting
$if(light_sample.eval.pdf > 0.0f & !occluded) {
auto wi = light_sample.shadow_ray->direction();
auto eval = closure->evaluate(wo, wi);
auto w = balance_heuristic(light_sample.eval.pdf, eval.pdf) /
light_sample.eval.pdf;
Li += w * beta * eval.f * light_sample.eval.L;
$if(!specular_bounce) {
beta_diffuse *= w * sample.eval.f;
Li_diffuse += w * beta_diffuse * eval.f * light_sample.eval.L;
};
};

// apply eta scale
auto eta = closure->eta().value_or(1.f);
$switch(sample.event) {
$case(Surface::event_enter) { eta_scale = sqr(eta); };
$case(Surface::event_exit) { eta_scale = sqr(1.f / eta); };
};
// sample material
auto sample = closure->sample(wo, u_lobe, u_bsdf);
ray = it->spawn_ray(sample.wi);
pdf_bsdf = sample.eval.pdf;
auto w = ite(sample.eval.pdf > 0.f, 1.f / sample.eval.pdf, 0.f);
beta *= w * sample.eval.f;
$if(!specular_bounce) {
beta_diffuse *= w * sample.eval.f;
};

// apply eta scale
auto eta = closure->eta().value_or(1.f);
$switch(sample.event) {
$case(Surface::event_enter) { eta_scale = sqr(eta); };
$case(Surface::event_exit) { eta_scale = sqr(1.f / eta); };
};
specular_bounce = all(closure->roughness() < .05f);
});
Expand Down
Loading

0 comments on commit f8cb3cc

Please sign in to comment.