Program Listing for File tonemapping.cpp

Return to documentation for file (/home/runner/work/Legion-Engine/Legion-Engine/legion/engine/rendering/pipeline/default/postfx/tonemapping.cpp)

#include <rendering/pipeline/default/postfx/tonemapping.hpp>

namespace legion::rendering
{
    std::atomic<id_type> Tonemapping::m_currentShader = { nameHash("aces tonemapping") };

    void Tonemapping::setAlgorithm(tonemapping_type type)
    {
        OPTICK_EVENT();
        static id_type acesId = nameHash("aces tonemapping");
        static id_type reinhardId = nameHash("reinhard tonemapping");
        static id_type reinhardJodieId = nameHash("reinhard jodie tonemapping");
        static id_type legionId = nameHash("legion tonemapping");
        static id_type unreal3Id = nameHash("unreal3 tonemapping");

        switch (type)
        {
        case tonemapping_type::aces:
            m_currentShader.store(acesId, std::memory_order_relaxed);
            break;
        case tonemapping_type::reinhard:
            m_currentShader.store(reinhardId, std::memory_order_relaxed);
            break;
        case tonemapping_type::reinhard_jodie:
            m_currentShader.store(reinhardJodieId, std::memory_order_relaxed);
            break;
        case tonemapping_type::legion:
            m_currentShader.store(legionId, std::memory_order_relaxed);
            break;
        case tonemapping_type::unreal3:
            m_currentShader.store(unreal3Id, std::memory_order_relaxed);
            break;
        default:
            m_currentShader.store(legionId, std::memory_order_relaxed);
            break;
        }
    }

    void Tonemapping::setup(app::window& context)
    {
        OPTICK_EVENT();
        using namespace legion::core::fs::literals;
        rendering::ShaderCache::create_shader("aces tonemapping", "engine://shaders/aces.shs"_view);
        rendering::ShaderCache::create_shader("reinhard tonemapping", "engine://shaders/reinhard.shs"_view);
        rendering::ShaderCache::create_shader("reinhard jodie tonemapping", "engine://shaders/reinhardjodie.shs"_view);
        rendering::ShaderCache::create_shader("legion tonemapping", "engine://shaders/legiontonemap.shs"_view);
        rendering::ShaderCache::create_shader("unreal3 tonemapping", "engine://shaders/unreal3.shs"_view);
        addRenderPass<&Tonemapping::renderPass>();
        exposure = 0.5f;
    }

    void Tonemapping::renderPass(framebuffer& fbo, RenderPipelineBase* pipeline, camera& cam, const camera::camera_input& camInput, time::span deltaTime)
    {
        //Try to get color attachment.
        auto color_attachment = fbo.getAttachment(FRAGMENT_ATTACHMENT);
        if (!std::holds_alternative<texture_handle>(color_attachment)) return;

        //Get color texture.
        auto color_texture = std::get<texture_handle>(color_attachment);

        OPTICK_EVENT();
        static id_type exposureId = nameHash("exposure");
        //static bool firstFrame = true;

        /*auto tex = std::get<texture_handle>(fbo.getAttachment(GL_COLOR_ATTACHMENT0)).get_texture();

        auto size = tex.size();

        size_type maxMip = math::floor(math::log2(math::max(size.x, size.y)));

        static std::vector<math::color> colors = { math::color() };

        if (!firstFrame)
        {
            OPTICK_EVENT("Read mip pixel data");
            glBindTexture(static_cast<GLenum>(tex.type), tex.textureId);
            glGetTexImage(static_cast<GLenum>(tex.type), maxMip, components_to_format[static_cast<int>(tex.channels)], GL_FLOAT, colors.data());
            glBindTexture(static_cast<GLenum>(tex.type), 0);
        }
        else
            firstFrame = false;*/

        /*float luminance = math::dot(math::vec3(colors[0].r, colors[0].g, colors[0].b), math::vec3(0.2126f, 0.7152f, 0.0722f));

        float newExposure = math::clamp(math::pow(math::max((1.0f - luminance), 0.f), 2.2f) * 10.f, 0.f, 10.f);

        if (newExposure < exposure)
            exposure = math::lerp(exposure, newExposure, deltaTime.seconds());
        else
            exposure = math::lerp(exposure, newExposure, deltaTime.seconds() * 0.5f);*/

        auto shader = ShaderCache::get_handle(m_currentShader.load(std::memory_order_relaxed));

        fbo.bind();
        shader.bind();

        shader.get_uniform<float>(exposureId).set_value(exposure);

        shader.get_uniform_with_location<texture_handle>(SV_SCENECOLOR).set_value(color_texture);
        renderQuad();
        shader.release();
        fbo.release();

        //{
        //    OPTICK_EVENT("Generate scene color mipmaps");
        //    glGenerateTextureMipmap(tex.textureId);
        //}
    }
}