Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
OldNew777 committed Apr 24, 2024
2 parents 13a1e4f + 53a4e38 commit 47f277e
Showing 1 changed file with 103 additions and 41 deletions.
144 changes: 103 additions & 41 deletions src/films/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Created by Mike Smith on 2023/6/14.
//

#include <imgui.h>

#include <runtime/image.h>
#include <runtime/swapchain.h>

#include <gui/window.h>
#include <gui/imgui_window.h>

#include <base/film.h>
#include <base/scene.h>
Expand Down Expand Up @@ -96,15 +98,20 @@ class DisplayInstance final : public Film::Instance {

private:
luisa::unique_ptr<Film::Instance> _base;
luisa::unique_ptr<Window> _window;
luisa::unique_ptr<ImGuiWindow> _window;
Image<float> _framebuffer;
Swapchain _swapchain;
Shader2D<> _blit;
Shader2D<int, bool, float> _blit;
Shader2D<Image<float>> _clear;
Clock _clock;
mutable double _last_frame_time;
Stream *_stream{};
ImTextureID _background{};
mutable double _last_frame_time{};
mutable int _tone_mapping{};
mutable float _exposure{};
mutable int _background_fit{};

private:
[[nodiscard]] auto _tone_mapping_uncharted2(Expr<float3> color) noexcept {
[[nodiscard]] static auto _tone_mapping_uncharted2(Expr<float3> color) noexcept {
static constexpr auto a = 0.15f;
static constexpr auto b = 0.50f;
static constexpr auto c = 0.10f;
Expand All @@ -117,25 +124,27 @@ class DisplayInstance final : public Film::Instance {
};
return op(1.6f * color) / op(white);
}
[[nodiscard]] auto _tone_mapping_aces(Expr<float3> color) noexcept {
[[nodiscard]] static auto _tone_mapping_aces(Expr<float3> color) noexcept {
constexpr auto a = 2.51f;
constexpr auto b = 0.03f;
constexpr auto c = 2.43f;
constexpr auto d = 0.59f;
constexpr auto e = 0.14f;
return (color * (a * color + b)) / (color * (c * color + d) + e);
}
[[nodiscard]] auto _linear_to_srgb(Expr<float3> color) noexcept {
[[nodiscard]] static auto _linear_to_srgb(Expr<float3> color) noexcept {
return ite(color <= .0031308f,
color * 12.92f,
1.055f * pow(color, 1.f / 2.4f) - .055f);
}

public:
DisplayInstance(const Pipeline &pipeline, const Film *film,
DisplayInstance(const Pipeline &pipeline, const Display *film,
luisa::unique_ptr<Film::Instance> base) noexcept
: Film::Instance{pipeline, film},
_base{std::move(base)} {}
_base{std::move(base)},
_tone_mapping{luisa::to_underlying(film->tone_mapping())},
_exposure{film->exposure().x} {}

[[nodiscard]] Film::Accumulation read(Expr<uint2> pixel) const noexcept override {
return _base->read(pixel);
Expand All @@ -146,32 +155,37 @@ class DisplayInstance final : public Film::Instance {
auto &&device = pipeline().device();
auto size = node()->resolution();
if (!_window) {
_window = luisa::make_unique<Window>("Display", size);
auto d = node<Display>();
auto option = SwapchainOption{
.display = _window->native_display(),
.window = _window->native_handle(),
.size = size,
.wants_hdr = d->hdr(),
.wants_vsync = d->vsync(),
.back_buffer_count = d->back_buffers()};
_swapchain = device.create_swapchain(*command_buffer.stream(), option);
_framebuffer = device.create_image<float>(
_swapchain.backend_storage(), size);
_blit = device.compile<2>([&] {
_stream = command_buffer.stream();
auto window_size = size;
while (std::max(window_size.x, window_size.y) > 2048u) {
window_size /= 2u;
}
_window = luisa::make_unique<ImGuiWindow>(
device, *command_buffer.stream(), "Display",
ImGuiWindow::Config{
.size = window_size,
.vsync = d->vsync(),
.hdr = d->hdr(),
.back_buffers = d->back_buffers()});
_framebuffer = device.create_image<float>(_window->swapchain().backend_storage(), size);
_background = reinterpret_cast<ImTextureID>(_window->register_texture(_framebuffer, TextureSampler::linear_point_zero()));
_blit = device.compile<2>([base = _base.get(), &framebuffer = _framebuffer](Int tonemapping, Bool ldr, Float scale) noexcept {
auto p = dispatch_id().xy();
auto exposure = d->exposure();
exposure = make_float3(std::exp2(exposure.x), std::exp2(exposure.y), std::exp2(exposure.z));
auto color = _base->read(p).average * exposure;
switch (d->tone_mapping()) {
case Display::ToneMapping::NONE: break;
case Display::ToneMapping::UNCHARTED2: color = _tone_mapping_uncharted2(color); break;
case Display::ToneMapping::ACES: color = _tone_mapping_aces(color); break;
}
if (_framebuffer.storage() == PixelStorage::BYTE4) {// LDR
auto color = base->read(p).average * scale;
$switch (tonemapping) {
$case (static_cast<int>(Display::ToneMapping::NONE)) {};
$case (static_cast<int>(Display::ToneMapping::UNCHARTED2)) { color = _tone_mapping_uncharted2(color); };
$case (static_cast<int>(Display::ToneMapping::ACES)) { color = _tone_mapping_aces(color); };
$default { unreachable(); };
};
$if (ldr) {// LDR
color = _linear_to_srgb(color);
}
_framebuffer->write(p, make_float4(color, 1.f));
};
framebuffer->write(p, make_float4(color, 1.f));
});
_clear = device.compile<2>([](ImageFloat image) noexcept {
image.write(dispatch_id().xy(), make_float4(0.f));
});
}
_last_frame_time = _clock.toc();
Expand All @@ -186,27 +200,75 @@ class DisplayInstance final : public Film::Instance {
}

void release() noexcept override {
while (_window && !_window->should_close()) {
_window->poll_events();
}
_window = nullptr;
_framebuffer = {};
_swapchain = {};
_window.reset();
_base->release();
}

private:
[[nodiscard]] float2 _compute_background_size(const ImGuiViewport *viewport, int fit) const noexcept {
auto frame_size = make_float2(_framebuffer.size());
auto viewport_size = make_float2(viewport->Size.x, viewport->Size.y);
switch (fit) {
case 0: {// aspect fill
auto aspect = frame_size.x / frame_size.y;
auto viewport_aspect = viewport_size.x / viewport_size.y;
auto ratio = aspect < viewport_aspect ? viewport_size.x / frame_size.x : viewport_size.y / frame_size.y;
return frame_size * ratio;
}
case 1: {// aspect fit
auto aspect = frame_size.x / frame_size.y;
auto viewport_aspect = viewport_size.x / viewport_size.y;
auto ratio = aspect > viewport_aspect ? viewport_size.x / frame_size.x : viewport_size.y / frame_size.y;
return frame_size * ratio;
}
case 2: {// stretch
return viewport_size;
}
default: break;
}
return viewport_size;
}

void _display() const noexcept {
auto scale = luisa::exp2(_exposure);
auto is_ldr = _window->framebuffer().storage() != PixelStorage::FLOAT4;
auto size = _framebuffer.size();
*_stream << _blit(_tone_mapping, is_ldr, scale).dispatch(size);
auto viewport = ImGui::GetMainViewport();
auto bg_size = _compute_background_size(viewport, _background_fit);
auto p_min = make_float2(viewport->Pos.x, viewport->Pos.y) +
.5f * (make_float2(viewport->Size.x, viewport->Size.y) - bg_size);
ImGui::GetBackgroundDrawList()->AddImage(_background,
ImVec2{p_min.x, p_min.y},
ImVec2{p_min.x + bg_size.x, p_min.y + bg_size.y});
ImGui::Begin("Console", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
{
ImGui::Text("Display FPS: %.2f", ImGui::GetIO().Framerate);
ImGui::SliderFloat("Exposure", &_exposure, -10.f, 10.f);
constexpr const char *const tone_mapping_names[] = {"None", "Uncharted2", "ACES"};
ImGui::Combo("Tone Mapping", &_tone_mapping, tone_mapping_names, std::size(tone_mapping_names));
constexpr const char *const fit_names[] = {"Fill", "Fit", "Stretch"};
ImGui::Combo("Background Fit", &_background_fit, fit_names, std::size(fit_names));
}
ImGui::End();
}

bool show(CommandBuffer &command_buffer) const noexcept override {
LUISA_ASSERT(command_buffer.stream() == _stream, "Command buffer stream mismatch.");
auto interval = 1. / node<Display>()->target_fps();
if (auto current_time = _clock.toc();
current_time - _last_frame_time >= interval) {
_last_frame_time = current_time;
_window->poll_events();
if (_window->should_close()) {
command_buffer << synchronize();
exit(0);// FIXME: exit gracefully
}
command_buffer << _blit().dispatch(node()->resolution())
<< _swapchain.present(_framebuffer);
command_buffer << commit();
_window->prepare_frame();
*_stream << _clear(_window->framebuffer()).dispatch(_window->framebuffer().size());
_display();
_window->render_frame();
return true;
}
return false;
Expand Down

0 comments on commit 47f277e

Please sign in to comment.