From b632885c812ea3b684f6bbde507dab1b98f83b81 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Fri, 2 Oct 2020 21:32:22 -0400 Subject: [PATCH] CEnvFxShaders: Convert to hsh pipeline --- Runtime/Graphics/CGraphics.hpp | 28 +++++++ Runtime/Graphics/CMakeLists.txt | 1 + Runtime/Graphics/Shaders/CEnvFxShaders.cpp | 74 ++++++++++--------- Runtime/Graphics/Shaders/CEnvFxShaders.hpp | 5 +- .../Graphics/Shaders/CThermalColdFilter.cpp | 3 +- Runtime/World/CEnvFxManager.cpp | 64 +++++++--------- 6 files changed, 101 insertions(+), 74 deletions(-) diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 8ae583688..64a896449 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -531,9 +531,37 @@ using NoColorAttachment = NoColorAttachmentExtm_A / ((fogUniBuf)->m_B - this->position.z)) - (fogUniBuf)->m_C); \ + switch ((fogUniBuf)->m_mode) { \ + case ERglFogMode::PerspLin: \ + fogZ = fogF; \ + break; \ + case ERglFogMode::PerspExp: \ + fogZ = 1.0 - hsh::exp2(-8.0 * fogF); \ + break; \ + case ERglFogMode::PerspExp2: \ + fogZ = 1.0 - hsh::exp2(-8.0 * fogF * fogF); \ + break; \ + case ERglFogMode::PerspRevExp: \ + fogZ = hsh::exp2(-8.0 * (1.0 - fogF)); \ + break; \ + case ERglFogMode::PerspRevExp2: \ + fogF = 1.0 - fogF; \ + fogZ = hsh::exp2(-8.0 * fogF * fogF); \ + break; \ + default: \ + fogZ = 0.0; \ + break; \ + } + #define FOG_OUT(out, fog, colorIn) \ out = hsh::float4(hsh::lerp((colorIn), (fog).m_color, hsh::saturate(fogZ)).xyz(), (colorIn).w); +#define FOG_OUT_UNIFORM(out, fogUniBuf, colorIn) \ + out = hsh::float4(hsh::lerp((colorIn), (fogUniBuf)->m_color, hsh::saturate(fogZ)).xyz(), (colorIn).w); + template struct ERglCullModeAttachmentExt { using type = hsh::pipeline::cull_mode<>; diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index f976126fe..5899d2136 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -62,4 +62,5 @@ runtime_add_hsh(Graphics Shaders/CThermalColdFilter.cpp Shaders/CThermalHotFilter.cpp Shaders/CElementGenShaders.cpp + Shaders/CEnvFxShaders.cpp ) diff --git a/Runtime/Graphics/Shaders/CEnvFxShaders.cpp b/Runtime/Graphics/Shaders/CEnvFxShaders.cpp index 3fd5b7f0e..1e7325208 100644 --- a/Runtime/Graphics/Shaders/CEnvFxShaders.cpp +++ b/Runtime/Graphics/Shaders/CEnvFxShaders.cpp @@ -2,44 +2,50 @@ #include "Runtime/World/CEnvFxManager.hpp" -#include +#include "CEnvFxShaders.cpp.hshhead" namespace urde { +using namespace hsh::pipeline; -void CEnvFxShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CEnvFxManager& fxMgr, - CEnvFxManagerGrid& grid) { - const auto uBufInfo = grid.m_uniformBuf.getBufferInfo(); - const auto iBufInfo = grid.m_instBuf.getBufferInfo(); +template +struct CEnvFxShadersPipeline +// FIXME replace MultiplyAttachment with ERglBlendFactor One:One equivalent +: pipeline, std::conditional_t, MultiplyAttachment>, + depth_compare, depth_write> { + CEnvFxShadersPipeline(hsh::vertex_buffer vbo, + hsh::uniform_buffer envFxUniBuf, + hsh::uniform_buffer fogUniBuf, hsh::texture2d texFlake, + hsh::texture2d texEnv) { + hsh::float4 posIn = hsh::float4(vbo->positions[this->vertex_id], 1.f); + hsh::float4 flakeTexel = texFlake.sample(vbo->uvs[this->vertex_id]); + hsh::float4 envTexel = texEnv.sample( + (envFxUniBuf->envMtx * posIn).xy(), + // FIXME hsh bug: this appears to be completely ignored + hsh::sampler{hsh::Linear, hsh::Linear, hsh::Linear, hsh::ClampToEdge, hsh::ClampToEdge, hsh::ClampToEdge}); + hsh::float4 color = vbo->color * envFxUniBuf->moduColor * flakeTexel * envTexel; + this->position = envFxUniBuf->proj * (envFxUniBuf->mv * posIn); + FOG_SHADER_UNIFORM(fogUniBuf) + // FIXME: hsh binds fog uniform to fragment stage + // only because of m_color reference in here. can/should we avoid that? + FOG_OUT_UNIFORM(this->color_out[0], fogUniBuf, color) + } +}; +template struct CEnvFxShadersPipeline; +template struct CEnvFxShadersPipeline; - const std::array, 2> uniforms{{ - uBufInfo.first.get(), - fxMgr.m_fogUniformBuf.get(), - }}; - const std::array ubufOffsets{ - size_t(uBufInfo.second), - 0, - }; - constexpr std::array ubufSizes{ - sizeof(CEnvFxShaders::Uniform), - sizeof(CGraphics::g_Fog), - }; - constexpr std::array uniformStages{ - boo::PipelineStage::Vertex, - boo::PipelineStage::Fragment, - }; - std::array, 2> textures{ - fxMgr.xb74_txtrSnowFlake->GetBooTexture(), - fxMgr.x40_txtrEnvGradient->GetBooTexture(), - }; - - grid.m_snowBinding = ctx.newShaderDataBinding( - m_snowPipeline, nullptr, iBufInfo.first.get(), nullptr, uniforms.size(), uniforms.data(), uniformStages.data(), - ubufOffsets.data(), ubufSizes.data(), textures.size(), textures.data(), nullptr, nullptr, 0, iBufInfo.second); - textures[0] = fxMgr.xc48_underwaterFlake->GetBooTexture(); - grid.m_underwaterBinding = - ctx.newShaderDataBinding(m_underwaterPipeline, nullptr, iBufInfo.first.get(), nullptr, uniforms.size(), - uniforms.data(), uniformStages.data(), ubufOffsets.data(), ubufSizes.data(), - textures.size(), textures.data(), nullptr, nullptr, 0, iBufInfo.second); +void CEnvFxShaders::BuildShaderDataBinding(CEnvFxManager& fxMgr, CEnvFxManagerGrid& grid) { + hsh::texture2d texFlake = fxMgr.xb74_txtrSnowFlake->GetBooTexture(); + hsh::texture2d texEnv = fxMgr.x40_txtrEnvGradient->GetBooTexture(); + hsh::vertex_buffer vboBuf = grid.m_instBuf.get(); + hsh::uniform_buffer envFxUniBuf = grid.m_uniformBuf.get(); + hsh::uniform_buffer fogUniBuf = fxMgr.m_fogUniformBuf.get(); + // FIXME hsh bug: can't bind all constant values + bool isUnderwater = false; + grid.m_snowBinding.hsh_snow_bind( + CEnvFxShadersPipeline(vboBuf, envFxUniBuf, fogUniBuf, texFlake, texEnv)); + isUnderwater = true; + grid.m_underwaterBinding.hsh_underwater_bind( + CEnvFxShadersPipeline(vboBuf, envFxUniBuf, fogUniBuf, texFlake, texEnv)); } } // namespace urde diff --git a/Runtime/Graphics/Shaders/CEnvFxShaders.hpp b/Runtime/Graphics/Shaders/CEnvFxShaders.hpp index b625f8ef1..58e175f60 100644 --- a/Runtime/Graphics/Shaders/CEnvFxShaders.hpp +++ b/Runtime/Graphics/Shaders/CEnvFxShaders.hpp @@ -2,6 +2,8 @@ #include +#include "hsh/hsh.h" + namespace urde { class CEnvFxManager; class CEnvFxManagerGrid; @@ -20,8 +22,7 @@ public: hsh::float4 moduColor; }; - static void BuildShaderDataBinding(CEnvFxManager& fxMgr, - CEnvFxManagerGrid& grid); + static void BuildShaderDataBinding(CEnvFxManager& fxMgr, CEnvFxManagerGrid& grid); }; } // namespace urde diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp index 6e6a8225e..3dc7de6a9 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp @@ -16,7 +16,8 @@ struct CThermalColdFilterPipeline : pipeline, CThermalColdFilterPipeline(hsh::vertex_buffer vbo, hsh::uniform_buffer ubo, hsh::render_texture2d sceneTex, hsh::texture2d noiseTex) { - static hsh::float4 kRGBToYPrime = {0.257f, 0.504f, 0.098f, 0.f}; + // FIXME hsh bug: cannot be const or static + hsh::float4 kRGBToYPrime{0.257f, 0.504f, 0.098f, 0.f}; this->position = hsh::float4(vbo->m_pos, 0.f, 1.f); hsh::float4 noiseTexel = noiseTex.read(Lookup8BPP(vbo->m_uvNoise, ubo->m_randOff)); diff --git a/Runtime/World/CEnvFxManager.cpp b/Runtime/World/CEnvFxManager.cpp index d6e43acb9..75be08d88 100644 --- a/Runtime/World/CEnvFxManager.cpp +++ b/Runtime/World/CEnvFxManager.cpp @@ -17,40 +17,34 @@ #include "TCastTo.hpp" // Generated file, do not modify include path - namespace urde { static rstl::reserved_vector g_SnowForces; CEnvFxManagerGrid::CEnvFxManagerGrid(const zeus::CVector2i& position, const zeus::CVector2i& extent, - std::vector initialParticles, int reserve, CEnvFxManager& parent, - boo::IGraphicsDataFactory::Context& ctx) + std::vector initialParticles, int reserve, CEnvFxManager& parent) : x4_position(position) , xc_extent(extent) , x1c_particles(std::move(initialParticles)) -, m_instBuf(parent.m_instPool.allocateBlock(CGraphics::g_BooFactory, reserve)) -, m_uniformBuf(parent.m_uniformPool.allocateBlock(CGraphics::g_BooFactory)) -, m_lineRenderer(ctx, CLineRenderer::EPrimitiveMode::Lines, reserve * 2, parent.x40_txtrEnvGradient->GetBooTexture(), - true, true) { +, m_instBuf(hsh::create_dynamic_vertex_buffer(reserve)) +, m_uniformBuf(hsh::create_dynamic_uniform_buffer()) +, m_lineRenderer(CLineRenderer::EPrimitiveMode::Lines, reserve * 2, parent.x40_txtrEnvGradient->GetBooTexture(), true, + hsh::LEqual) { x1c_particles.reserve(reserve); - CEnvFxShaders::BuildShaderDataBinding(ctx, parent, *this); + CEnvFxShaders::BuildShaderDataBinding(parent, *this); } CEnvFxManager::CEnvFxManager() { x40_txtrEnvGradient = g_SimplePool->GetObj("TXTR_EnvGradient"); - x40_txtrEnvGradient->GetBooTexture()->setClampMode(boo::TextureClampMode::ClampToEdge); xb58_envRainSplash = g_SimplePool->GetObj("PART_EnvRainSplash"); xb74_txtrSnowFlake = g_SimplePool->GetObj("TXTR_SnowFlake"); xc48_underwaterFlake = g_SimplePool->GetObj("TXTR_UnderwaterFlake"); CRandom16 random(0); - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - m_fogUniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(CGraphics::g_Fog), 1); - for (int i = 0; i < 8; ++i) - for (int j = 0; j < 8; ++j) - x50_grids.emplace_back(zeus::CVector2i{j * 2048, i * 2048}, zeus::CVector2i{2048, 2048}, - std::vector{}, 171, *this, ctx); - return true; - } BooTrace); + m_fogUniformBuf = hsh::create_dynamic_uniform_buffer(); + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + x50_grids.emplace_back(zeus::CVector2i{j * 2048, i * 2048}, zeus::CVector2i{2048, 2048}, + std::vector{}, 171, *this); for (int i = 0; i < 16; ++i) xb84_snowZDeltas.emplace_back(0.f, 0.f, random.Range(-2.f, -4.f)); } @@ -77,10 +71,10 @@ void CEnvFxManager::UpdateRainSounds(const CStateManager& mgr) { zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); float rainVol = CalcRainVolume(x30_fxDensity); if (!xb6a_rainSoundActive) { - xb6c_leftRainSound = CSfxManager::AddEmitter(SFXsfx09F0, zeus::skZero3f, zeus::skZero3f, false, - true, 0xff, kInvalidAreaId); - xb70_rightRainSound = CSfxManager::AddEmitter(SFXsfx09F1, zeus::skZero3f, zeus::skZero3f, false, - true, 0xff, kInvalidAreaId); + xb6c_leftRainSound = + CSfxManager::AddEmitter(SFXsfx09F0, zeus::skZero3f, zeus::skZero3f, false, true, 0xff, kInvalidAreaId); + xb70_rightRainSound = + CSfxManager::AddEmitter(SFXsfx09F1, zeus::skZero3f, zeus::skZero3f, false, true, 0xff, kInvalidAreaId); xb6a_rainSoundActive = true; } CSfxManager::UpdateEmitter(xb6c_leftRainSound, camXf.origin - camXf.basis[0], camXf.basis[0], rainVol); @@ -209,10 +203,9 @@ void CEnvFxManager::UpdateBlockedGrids(CStateManager& mgr, EEnvFxType type, cons constexpr auto filter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid, EMaterialTypes::Trigger}, {EMaterialTypes::ProjectilePassthrough, EMaterialTypes::SeeThrough}); - zeus::CVector3f pos = xf * zeus::CVector3f((grid.x4_position + grid.xc_extent * 0).toVec2f() / 256.f) + - zeus::skUp * 500.f; - CRayCastResult result = - CGameCollision::RayStaticIntersection(mgr, pos, zeus::skDown, 1000.f, filter); + zeus::CVector3f pos = + xf * zeus::CVector3f((grid.x4_position + grid.xc_extent * 0).toVec2f() / 256.f) + zeus::skUp * 500.f; + CRayCastResult result = CGameCollision::RayStaticIntersection(mgr, pos, zeus::skDown, 1000.f, filter); if (result.IsValid()) { if (!blockListBuilt) { BuildBlockObjectList(blockList, mgr); @@ -379,7 +372,7 @@ void CEnvFxManagerGrid::RenderSnowParticles(const zeus::CTransform& camXf) { const zeus::CVector3f xVec = 0.2f * camXf.basis[0]; const zeus::CVector3f zVec = 0.2f * camXf.basis[2]; const zeus::CMatrix4f mvp = CGraphics::GetPerspectiveProjectionMatrix(false) * CGraphics::g_GXModelView.toMatrix4f(); - auto* bufOut = m_instBuf.access(); + auto* bufOut = m_instBuf.map(); for (const auto& particle : x1c_particles) { bufOut->positions[0] = particle.toVec3f(); bufOut->uvs[0] = zeus::CVector2f(0.f, 0.f); @@ -392,8 +385,8 @@ void CEnvFxManagerGrid::RenderSnowParticles(const zeus::CTransform& camXf) { bufOut->color = GetFlakeColor(mvp, *bufOut); ++bufOut; } - CGraphics::SetShaderDataBinding(m_snowBinding); - CGraphics::DrawInstances(0, 4, x1c_particles.size()); + m_instBuf.unmap(); + m_snowBinding.draw_instanced(0, 4, x1c_particles.size()); } void CEnvFxManagerGrid::RenderRainParticles(const zeus::CTransform& camXf) { @@ -416,7 +409,7 @@ void CEnvFxManagerGrid::RenderUnderwaterParticles(const zeus::CTransform& camXf) const zeus::CVector3f xVec = 0.5f * camXf.basis[0]; const zeus::CVector3f zVec = 0.5f * camXf.basis[2]; const zeus::CMatrix4f mvp = CGraphics::GetPerspectiveProjectionMatrix(false) * CGraphics::g_GXModelView.toMatrix4f(); - auto* bufOut = m_instBuf.access(); + auto* bufOut = m_instBuf.map(); for (const auto& particle : x1c_particles) { bufOut->positions[0] = particle.toVec3f(); bufOut->uvs[0] = zeus::CVector2f(0.f, 0.f); @@ -429,8 +422,8 @@ void CEnvFxManagerGrid::RenderUnderwaterParticles(const zeus::CTransform& camXf) bufOut->color = GetFlakeColor(mvp, *bufOut); ++bufOut; } - CGraphics::SetShaderDataBinding(m_underwaterBinding); - CGraphics::DrawInstances(0, 4, x1c_particles.size()); + m_instBuf.unmap(); + m_underwaterBinding.draw_instanced(0, 4, x1c_particles.size()); } void CEnvFxManagerGrid::Render(const zeus::CTransform& xf, const zeus::CTransform& invXf, const zeus::CTransform& camXf, @@ -452,7 +445,7 @@ void CEnvFxManagerGrid::Render(const zeus::CTransform& xf, const zeus::CTransfor default: break; } - m_uniformBuf.access() = parent.m_uniformData; + m_uniformBuf.load(parent.m_uniformData); switch (fxType) { case EEnvFxType::Snow: RenderSnowParticles(camXf); @@ -561,20 +554,17 @@ void CEnvFxManager::Render(const CStateManager& mgr) { default: break; } - m_fogUniformBuf->load(&CGraphics::g_Fog, sizeof(CGraphics::g_Fog)); + m_fogUniformBuf.load(CGraphics::g_Fog); for (auto& grid : x50_grids) grid.Render(xf, invXf, camXf, x30_fxDensity, fxType, *this); // Backface cull - - m_uniformPool.updateBuffers(); - m_instPool.updateBuffers(); } } } void CEnvFxManager::AsyncLoadResources(CStateManager& mgr) { xb68_envRainSplashId = mgr.AllocateUniqueId(); - CHUDBillboardEffect* effect = + auto* effect = new CHUDBillboardEffect(xb58_envRainSplash, {}, xb68_envRainSplashId, true, "VisorRainSplashes", CHUDBillboardEffect::GetNearClipDistance(mgr), CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, zeus::skZero3f);