diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 5899d2136..3b4e136e2 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -63,4 +63,5 @@ runtime_add_hsh(Graphics Shaders/CThermalHotFilter.cpp Shaders/CElementGenShaders.cpp Shaders/CEnvFxShaders.cpp + Shaders/CFogVolumeFilter.cpp ) diff --git a/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp b/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp index e7d647c1d..768014dad 100644 --- a/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp +++ b/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp @@ -1,60 +1,81 @@ #include "Runtime/Graphics/Shaders/CFogVolumeFilter.hpp" #include +#include #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Graphics/CBooRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include -#include -#include +#include "CFogVolumeFilter.cpp.hshhead" namespace urde { +using namespace hsh::pipeline; + +template +struct CFogVolumeFilterPipeline +// FIXME replace BlendAttachment with ERglBlendFactor DstAlpha:One equivalent +: pipeline, std::conditional_t, BlendAttachment<>>, + depth_compare, depth_write> { + CFogVolumeFilterPipeline(hsh::vertex_buffer vbo, + hsh::uniform_buffer uniBuf, hsh::render_texture2d frontfaceTex, + hsh::render_texture2d backfaceTex, hsh::texture2d linearizer) { + this->position = hsh::float4(vbo->m_pos.x, -vbo->m_pos.y, 0.f, 1.f); + const float linScale = 65535.f / 65536.f * 256.f; + const float uvBias = 0.5f / 256.f; + if constexpr (TwoWay) { + float frontY; + float backY; + float frontX = hsh::modf((1.f - frontfaceTex.sample(vbo->m_uv).x) * linScale, frontY); + float backX = hsh::modf((1.f - backfaceTex.sample(vbo->m_uv).x) * linScale, backY); + float frontLin = + linearizer.sample(hsh::float2(frontX * 255.f / 256.f + uvBias, frontY / 256.f + uvBias)).x; + float backLin = linearizer.sample(hsh::float2(backX * 255.f / 256.f + uvBias, backY / 256.f + uvBias)).x; + this->color_out[0] = hsh::float4(uniBuf->m_color.xyz(), (frontLin - backLin) * 10.f); + } else { + float y; + float x = hsh::modf((1.f - frontfaceTex.sample(vbo->m_uv).x) * linScale, y); + float alpha = linearizer.sample(hsh::float2(x * 255.f / 256.f + uvBias, y / 256.f + uvBias)).x * 10.f; + this->color_out[0] = uniBuf->m_color * alpha; + } + } +}; +template struct CFogVolumeFilterPipeline; +template struct CFogVolumeFilterPipeline; CFogVolumeFilter::CFogVolumeFilter() { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - constexpr std::array verts{{ - {{-1.0, -1.0}, {0.0, 0.0}}, - {{-1.0, 1.0}, {0.0, 1.0}}, - {{1.0, -1.0}, {1.0, 0.0}}, - {{1.0, 1.0}, {1.0, 1.0}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CColor), 1); - const std::array, 3> texs{ - CGraphics::g_SpareTexture.get(), - CGraphics::g_SpareTexture.get(), - g_Renderer->GetFogRampTex().get(), - }; - constexpr std::array bindIdxs{0, 1, 0}; - constexpr std::array bindDepth{true, true, false}; - const std::array, 1> ubufs{m_uniBuf.get()}; + constexpr std::array verts{{ + {{-1.0, -1.0}, {0.0, 0.0}}, + {{-1.0, 1.0}, {0.0, 1.0}}, + {{1.0, -1.0}, {1.0, 0.0}}, + {{1.0, 1.0}, {1.0, 1.0}}, + }}; + m_vbo = hsh::create_vertex_buffer(verts); + m_uniBuf = hsh::create_dynamic_uniform_buffer(); - m_dataBind1Way = - ctx.newShaderDataBinding(s_1WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, - nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); - m_dataBind2Way = - ctx.newShaderDataBinding(s_2WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, - nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); - return true; - } BooTrace); + // FIXME hsh bug: can't bind all constant values + bool twoWay = false; + m_dataBind1Way.hsh_1way_bind( + CFogVolumeFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_depth(0), + CGraphics::g_SpareTexture.get_depth(1), g_Renderer->GetFogRampTex())); + twoWay = true; + m_dataBind2Way.hsh_2way_bind( + CFogVolumeFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_depth(0), + CGraphics::g_SpareTexture.get_depth(1), g_Renderer->GetFogRampTex())); } void CFogVolumeFilter::draw2WayPass(const zeus::CColor& color) { SCOPED_GRAPHICS_DEBUG_GROUP("CFogVolumeFilter::draw2WayPass", zeus::skMagenta); - m_uniBuf->load(&color, sizeof(zeus::CColor)); - CGraphics::SetShaderDataBinding(m_dataBind2Way); - CGraphics::DrawArray(0, 4); + m_uniBuf.load({color}); + m_dataBind2Way.draw(0, 4); } void CFogVolumeFilter::draw1WayPass(const zeus::CColor& color) { SCOPED_GRAPHICS_DEBUG_GROUP("CFogVolumeFilter::draw1WayPass", zeus::skMagenta); - m_uniBuf->load(&color, sizeof(zeus::CColor)); - CGraphics::SetShaderDataBinding(m_dataBind1Way); - CGraphics::DrawArray(0, 4); + m_uniBuf.load({color}); + m_dataBind1Way.draw(0, 4); } } // namespace urde diff --git a/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp b/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp index d55bde642..16cdd3d69 100644 --- a/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp +++ b/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp @@ -4,11 +4,12 @@ namespace zeus { class CColor; -} +} // namespace zeus namespace urde { class CFogVolumeFilter { +public: struct Vert { hsh::float2 m_pos; hsh::float2 m_uv; @@ -17,6 +18,7 @@ class CFogVolumeFilter { hsh::float4 m_color; }; +private: hsh::owner> m_vbo; hsh::dynamic_owner> m_uniBuf; hsh::binding m_dataBind1Way;