diff --git a/.gitignore b/.gitignore index 240fbf0c..ab3030ac 100644 --- a/.gitignore +++ b/.gitignore @@ -299,6 +299,7 @@ CMakeSettings.json *.png /outputs/ +/outputs_ref/ /imgui.ini /set_accel_kernel /results.txt diff --git a/cbox_diff/meshes/cbox-parts/back-wall.obj b/cbox-diff/meshes/cbox-parts/back-wall.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/back-wall.obj rename to cbox-diff/meshes/cbox-parts/back-wall.obj diff --git a/cbox_diff/meshes/cbox-parts/ceiling.obj b/cbox-diff/meshes/cbox-parts/ceiling.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/ceiling.obj rename to cbox-diff/meshes/cbox-parts/ceiling.obj diff --git a/cbox_diff/meshes/cbox-parts/floor.obj b/cbox-diff/meshes/cbox-parts/floor.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/floor.obj rename to cbox-diff/meshes/cbox-parts/floor.obj diff --git a/cbox_diff/meshes/cbox-parts/left-wall.obj b/cbox-diff/meshes/cbox-parts/left-wall.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/left-wall.obj rename to cbox-diff/meshes/cbox-parts/left-wall.obj diff --git a/cbox_diff/meshes/cbox-parts/light.obj b/cbox-diff/meshes/cbox-parts/light.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/light.obj rename to cbox-diff/meshes/cbox-parts/light.obj diff --git a/cbox_diff/meshes/cbox-parts/right-wall.obj b/cbox-diff/meshes/cbox-parts/right-wall.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/right-wall.obj rename to cbox-diff/meshes/cbox-parts/right-wall.obj diff --git a/cbox_diff/meshes/cbox-parts/short-box.obj b/cbox-diff/meshes/cbox-parts/short-box.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/short-box.obj rename to cbox-diff/meshes/cbox-parts/short-box.obj diff --git a/cbox_diff/meshes/cbox-parts/tall-box.obj b/cbox-diff/meshes/cbox-parts/tall-box.obj similarity index 100% rename from cbox_diff/meshes/cbox-parts/tall-box.obj rename to cbox-diff/meshes/cbox-parts/tall-box.obj diff --git a/cbox_diff/renders/cbox-diff.exr b/cbox-diff/renders/cbox-diff.exr similarity index 59% rename from cbox_diff/renders/cbox-diff.exr rename to cbox-diff/renders/cbox-diff.exr index a410c4c1..43e88e00 100644 Binary files a/cbox_diff/renders/cbox-diff.exr and b/cbox-diff/renders/cbox-diff.exr differ diff --git a/cbox_diff/renders/cbox-ref.exr b/cbox-diff/renders/cbox-ref.exr similarity index 100% rename from cbox_diff/renders/cbox-ref.exr rename to cbox-diff/renders/cbox-ref.exr diff --git a/cbox_diff/cbox-diff/cbox-diff-2.luisa b/cbox-diff/scenes/cbox-diff/cbox-diff-2.luisa similarity index 96% rename from cbox_diff/cbox-diff/cbox-diff-2.luisa rename to cbox-diff/scenes/cbox-diff/cbox-diff-2.luisa index 5a7653fe..bafe5f00 100644 --- a/cbox_diff/cbox-diff/cbox-diff-2.luisa +++ b/cbox-diff/scenes/cbox-diff/cbox-diff-2.luisa @@ -124,11 +124,15 @@ Film film : Color { exposure { 0 } } +FIlm display : Display { + base { @film } +} + Camera camera : Pinhole { position { 0.0, 1.0, 5.0 } fov { 27.8 } - spp { 1024 } - film { @film } + spp { 64 } + film { @display } file { "../../renders/cbox-diff.exr" } filter : Gaussian { radius { 1 } @@ -150,7 +154,7 @@ Integrator pt : MegaReplayDiff { iterations { 100 } optimizer : Adam { - learning_rate { 0.003 } + learning_rate { 0.03 } } } diff --git a/cbox_diff/cbox-diff/cbox-ref-2.luisa b/cbox-diff/scenes/cbox-diff/cbox-ref-2.luisa similarity index 100% rename from cbox_diff/cbox-diff/cbox-ref-2.luisa rename to cbox-diff/scenes/cbox-diff/cbox-ref-2.luisa diff --git a/data/scenes/cbox-diff/cbox-diff-2.luisa b/data/scenes/cbox-diff/cbox-diff-2.luisa index 586cfc24..bafe5f00 100644 --- a/data/scenes/cbox-diff/cbox-diff-2.luisa +++ b/data/scenes/cbox-diff/cbox-diff-2.luisa @@ -151,10 +151,10 @@ Integrator pt : MegaReplayDiff { display_camera_index { 0 } save_process { true } loss : L2 {} - iterations { 1000 } + iterations { 100 } optimizer : Adam { - learning_rate { 0.3 } + learning_rate { 0.03 } } } diff --git a/src/base/differentiation.cpp b/src/base/differentiation.cpp index 736a8215..dafa3de5 100644 --- a/src/base/differentiation.cpp +++ b/src/base/differentiation.cpp @@ -50,7 +50,7 @@ Differentiation::Differentiation(Pipeline &pipeline) noexcept #ifdef LUISA_RENDER_USE_BP_TIMES_NORMALIZATION grad /= Float(max(count, 1u)); #endif - device_log("grad accumulated: ({}, {}, {})", grad[0u], grad[1u], grad[2u]); + // device_log("grad accumulated: ({}, {}, {})", grad[0u], grad[1u], grad[2u]); auto param_offset = thread * 4u; param_gradients.write(param_offset + 0u, grad.x); @@ -77,7 +77,6 @@ Differentiation::Differentiation(Pipeline &pipeline) noexcept Differentiation::ConstantParameter Differentiation::parameter(float4 x, uint channels, float2 range) noexcept { auto index = static_cast(_constant_params.size()); - LUISA_INFO("index: {}", index); _constant_params.emplace_back(x); _constant_ranges.emplace_back(range); return {index, channels}; diff --git a/src/base/surface.cpp b/src/base/surface.cpp index 1c415e89..309315b1 100644 --- a/src/base/surface.cpp +++ b/src/base/surface.cpp @@ -70,6 +70,7 @@ Surface::Sample Surface::Closure::sample(Expr wo, void Surface::Closure::backward( Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept { + compute::device_log("ok till before backward surface"); if (instance()->node()->is_differentiable()) { _backward(wo, wi, df, mode); } diff --git a/src/integrators/mega_replay_diff.cpp b/src/integrators/mega_replay_diff.cpp index 561bea0b..29818c83 100644 --- a/src/integrators/mega_replay_diff.cpp +++ b/src/integrators/mega_replay_diff.cpp @@ -2,6 +2,7 @@ // Created by ChenXin on 2022/2/23. // // #include +#include "core/logging.h" #include #include #include @@ -14,7 +15,7 @@ namespace luisa::render { // #define LUISA_RENDER_PATH_REPLAY_DEBUG -#define LUISA_RENDER_PATH_REPLAY_DEBUG_2 +// #define LUISA_RENDER_PATH_REPLAY_DEBUG_2 using namespace luisa::compute; diff --git a/src/surfaces/glass.cpp b/src/surfaces/glass.cpp index 56f3f2d4..f191aa46 100644 --- a/src/surfaces/glass.cpp +++ b/src/surfaces/glass.cpp @@ -252,7 +252,7 @@ class GlassClosure : public Surface::Closure { $if(same_hemisphere(wo_local, wi_local)) { // Kr if (_instance->Kr() && _instance->Kr()->node()->requires_gradients()) { - auto d_f = refl.backward(wo_local, wi_local, df); + auto d_f = refl.backward(wo_local, wi_local, df, mode); d_alpha = d_f.dAlpha; _instance->Kr()->backward_albedo_spectrum(it, swl(), time(), zero_if_any_nan(d_f.dR)); } diff --git a/src/surfaces/matte.cpp b/src/surfaces/matte.cpp index f20ff025..98a64e74 100644 --- a/src/surfaces/matte.cpp +++ b/src/surfaces/matte.cpp @@ -125,7 +125,8 @@ class MatteClosure : public Surface::Closure { auto wo_local = ctx.it.shading().world_to_local(wo); auto wi_local = ctx.it.shading().world_to_local(wi); auto df = df_in * abs_cos_theta(wi_local); - auto grad = _refl->backward(wo_local, wi_local, df); + compute::device_log("ok till before backward matte"); + auto grad = _refl->backward(wo_local, wi_local, df, mode); // device_log("grad in matte: ({}, {}, {})", grad.dR[0u], grad.dR[1u], grad.dR[2u]); if (auto kd = _instance->Kd()) { kd->backward_albedo_spectrum(ctx.it, swl(), time(), zero_if_any_nan(grad.dR)); diff --git a/src/surfaces/mirror.cpp b/src/surfaces/mirror.cpp index 664cf1ec..5b7bc01d 100644 --- a/src/surfaces/mirror.cpp +++ b/src/surfaces/mirror.cpp @@ -159,7 +159,7 @@ class MirrorClosure : public Surface::Closure { auto wo_local = it.shading().world_to_local(wo); auto wi_local = it.shading().world_to_local(wi); auto df = df_in * abs_cos_theta(wi_local); - auto grad = refl.backward(wo_local, wi_local, df); + auto grad = refl.backward(wo_local, wi_local, df, mode); auto d_fresnel = dynamic_cast(grad.dFresnel.get()); if (auto color = _instance->color()) { color->backward_albedo_spectrum(it, swl(), time(), zero_if_any_nan(grad.dR + d_fresnel->dR0)); diff --git a/src/util/scattering.cpp b/src/util/scattering.cpp index bd6155a3..66796f82 100644 --- a/src/util/scattering.cpp +++ b/src/util/scattering.cpp @@ -2,6 +2,9 @@ // Created by Mike Smith on 2022/1/31. // +#include "dsl/builtin.h" +#include "dsl/stmt.h" +#include "util/spec.h" #include #include #include @@ -9,7 +12,10 @@ namespace luisa::render { +using compute::backward; using compute::Callable; +using compute::grad; +using compute::requires_grad; Bool refract(Float3 wi, Float3 n, Float eta, Float3 *wt) noexcept { static Callable impl = [](Float3 wi, Float3 n, Float eta) noexcept { @@ -317,7 +323,7 @@ SampledSpectrum LambertianReflection::evaluate( } LambertianReflection::Gradient LambertianReflection::backward( - Expr wo, Expr wi, const SampledSpectrum &df) const noexcept { + Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept { return {.dR = df * ite(same_hemisphere(wo, wi), inv_pi, 0.f)}; } @@ -337,7 +343,7 @@ Float LambertianTransmission::pdf(Expr wo, Expr wi, TransportMod } LambertianTransmission::Gradient LambertianTransmission::backward( - Expr wo, Expr wi, const SampledSpectrum &df) noexcept { + Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) noexcept { return {.dT = df * ite(!same_hemisphere(wo, wi), inv_pi, 0.f)}; } @@ -378,7 +384,7 @@ Float MicrofacetReflection::pdf(Expr wo, Expr wi, TransportMode } MicrofacetReflection::Gradient MicrofacetReflection::backward( - Expr wo, Expr wi, const SampledSpectrum &df) const noexcept { + Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept { using compute::any; using compute::normalize; auto wh = wi + wo; @@ -500,6 +506,11 @@ OrenNayar::OrenNayar(const SampledSpectrum &R, Expr sigma) noexcept SampledSpectrum OrenNayar::evaluate( Expr wo, Expr wi, TransportMode mode) const noexcept { + return forward_compute(wo, wi, mode, _a, _b, _r); +} + +SampledSpectrum OrenNayar::forward_compute( + Expr wo, Expr wi, TransportMode mode, Float a, Float b, SampledSpectrum r) const noexcept { auto valid = same_hemisphere(wo, wi); auto s = ite(valid, inv_pi, 0.f); static Callable scale = [](Float3 wo, Float3 wi, Float a, Float b) noexcept { @@ -520,39 +531,28 @@ SampledSpectrum OrenNayar::evaluate( sinThetaI / absCosThetaI, sinThetaO / absCosThetaO); return (a + b * maxCos * sinAlpha * tanBeta); }; - return s * scale(wo, wi, _a, _b) * _r; + return s * scale(wo, wi, a, b) * r; } OrenNayar::Gradient OrenNayar::backward( - Expr wo, Expr wi, const SampledSpectrum &df) const noexcept { - auto sinThetaI = sin_theta(wi); - auto sinThetaO = sin_theta(wo); - // Compute cosine term of Oren-Nayar model - auto sinPhiI = sin_phi(wi); - auto cosPhiI = cos_phi(wi); - auto sinPhiO = sin_phi(wo); - auto cosPhiO = cos_phi(wo); - auto dCos = cosPhiI * cosPhiO + sinPhiI * sinPhiO; - auto maxCos = ite(sinThetaI > 1e-4f & sinThetaO > 1e-4f, max(0.f, dCos), 0.f); - // Compute sine and tangent terms of Oren-Nayar model - auto absCosThetaI = abs_cos_theta(wi); - auto absCosThetaO = abs_cos_theta(wo); - auto sinAlpha = ite(absCosThetaI > absCosThetaO, sinThetaO, sinThetaI); - auto tanBeta = ite(absCosThetaI > absCosThetaO, - sinThetaI / absCosThetaI, sinThetaO / absCosThetaO); - auto sigma2 = sqr(radians(_sigma)); - - // backward - auto sigma2_sigma = radians(_sigma) * pi / 90.f; - auto a_sigma2 = -0.165f / sqr(sigma2 + 0.33f); - auto b_sigma2 = 0.0405f / sqr(sigma2 + 0.09f); - auto k0 = maxCos * sinAlpha * tanBeta; - auto d_r = df * inv_pi * (_a + _b * k0); - auto k1 = inv_pi * (df * _r).sum(); - auto d_a = k1; - auto d_b = k1 * k0; - auto d_sigma2 = d_a * a_sigma2 + d_b * b_sigma2; - auto d_sigma = d_sigma2 * sigma2_sigma; + Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept { + auto d_r = _r; + auto d_sigma = _sigma; + compute::device_log("ok till before backward"); + $autodiff { + auto r = _r; + auto sigma = _sigma; + r.requires_grad(); + requires_grad(sigma); + auto sigma2 = sqr(radians(sigma)); + auto a = 1.f - (sigma2 / (2.f * sigma2 + 0.66f)); + auto b = 0.45f * sigma2 / (sigma2 + 0.09f); + auto y = forward_compute(wo, wi, mode, a, b, r); + y.backward(df); + d_r = r.grad(); + d_sigma = grad(sigma); + }; + compute::device_log("ok after backward"); return {.dR = d_r, .dSigma = d_sigma}; } @@ -604,7 +604,7 @@ Float FresnelBlend::pdf(Expr wo, Expr wi, TransportMode mode) co } FresnelBlend::Gradient FresnelBlend::backward( - Expr wo, Expr wi, const SampledSpectrum &df) const noexcept { + Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept { auto pow5 = [](auto &&v) noexcept { return sqr(sqr(v)) * v; }; auto absCosThetaI = abs_cos_theta(wi); diff --git a/src/util/scattering.h b/src/util/scattering.h index d4ae7067..f9d5cb4a 100644 --- a/src/util/scattering.h +++ b/src/util/scattering.h @@ -152,7 +152,7 @@ class LambertianReflection : public BxDF { public: explicit LambertianReflection(const SampledSpectrum &R) noexcept : _r{R} {} [[nodiscard]] SampledSpectrum evaluate(Expr wo, Expr wi, TransportMode mode) const noexcept override; - [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df) const noexcept; + [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept; [[nodiscard]] SampledSpectrum albedo() const noexcept override { return _r; } }; @@ -171,7 +171,7 @@ class LambertianTransmission : public BxDF { [[nodiscard]] SampledSpectrum evaluate(Expr wo, Expr wi, TransportMode mode) const noexcept override; [[nodiscard]] SampledDirection sample_wi(Expr wo, Expr u, TransportMode mode) const noexcept override; [[nodiscard]] Float pdf(Expr wo, Expr wi, TransportMode mode) const noexcept override; - [[nodiscard]] static Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df) noexcept; + [[nodiscard]] static Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) noexcept; [[nodiscard]] SampledSpectrum albedo() const noexcept override { return SampledSpectrum(0.f); } }; @@ -196,7 +196,7 @@ class MicrofacetReflection : public BxDF { [[nodiscard]] SampledSpectrum evaluate(Expr wo, Expr wi, TransportMode mode) const noexcept override; [[nodiscard]] SampledDirection sample_wi(Expr wo, Expr u, TransportMode mode) const noexcept override; [[nodiscard]] Float pdf(Expr wo, Expr wi, TransportMode mode) const noexcept override; - [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df) const noexcept; + [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept; [[nodiscard]] SampledSpectrum albedo() const noexcept override { return _r; } }; @@ -245,7 +245,8 @@ class OrenNayar : public BxDF { public: OrenNayar(const SampledSpectrum &R, Expr sigma) noexcept; [[nodiscard]] SampledSpectrum evaluate(Expr wo, Expr wi, TransportMode mode) const noexcept override; - [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df) const noexcept; + [[nodiscard]] SampledSpectrum forward_compute(Expr wo, Expr wi, TransportMode mode, Float a, Float b, SampledSpectrum r) const noexcept; + [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept; [[nodiscard]] SampledSpectrum albedo() const noexcept override { return _r; } }; @@ -275,7 +276,7 @@ class FresnelBlend : public BxDF { [[nodiscard]] SampledSpectrum evaluate(Expr wo, Expr wi, TransportMode mode) const noexcept override; [[nodiscard]] SampledDirection sample_wi(Expr wo, Expr u, TransportMode mode) const noexcept override; [[nodiscard]] Float pdf(Expr wo, Expr wi, TransportMode mode) const noexcept override; - [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df) const noexcept; + [[nodiscard]] Gradient backward(Expr wo, Expr wi, const SampledSpectrum &df, TransportMode mode) const noexcept; [[nodiscard]] SampledSpectrum albedo() const noexcept override { return _rd; } };