From 30ae3474205a7736b4a60ad9434478fc3c019ae5 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 30 Sep 2017 18:26:46 -1000 Subject: [PATCH] Implement CWorldShadow and texture clamp mode --- Editor/badging/Badging.cpp | 2 +- Editor/icons/icons.cpp | 1 + Runtime/CStateManager.cpp | 8 +- Runtime/Character/CActorLights.cpp | 6 + Runtime/Graphics/CBooRenderer.cpp | 10 +- Runtime/Graphics/CBooRenderer.hpp | 4 +- Runtime/Graphics/CMakeLists.txt | 7 +- Runtime/Graphics/CModel.hpp | 14 ++ Runtime/Graphics/CModelBoo.cpp | 51 +++++-- Runtime/Graphics/CMoviePlayer.cpp | 35 ++--- Runtime/Graphics/CPVSAreaSet.hpp | 10 ++ Runtime/Graphics/CTextureBoo.cpp | 28 ++-- Runtime/Graphics/IRenderer.hpp | 2 +- .../Shaders/CColoredQuadFilterGLSL.cpp | 2 - .../Shaders/CColoredQuadFilterHLSL.cpp | 2 - .../Shaders/CColoredQuadFilterMetal.cpp | 2 - Runtime/Graphics/Shaders/CModelShaders.cpp | 5 + Runtime/Graphics/Shaders/CModelShaders.hpp | 4 +- .../Graphics/Shaders/CModelShadersGLSL.cpp | 74 ++++++++++ .../Graphics/Shaders/CModelShadersHLSL.cpp | 68 ++++++++- .../Graphics/Shaders/CModelShadersMetal.cpp | 69 +++++++++- Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp | 4 +- .../Graphics/Shaders/CThermalColdFilter.cpp | 2 +- .../Graphics/Shaders/CWorldShadowShader.cpp | 59 ++++++++ .../Graphics/Shaders/CWorldShadowShader.hpp | 55 ++++++++ .../Shaders/CWorldShadowShaderGLSL.cpp | 129 ++++++++++++++++++ .../Shaders/CWorldShadowShaderHLSL.cpp | 89 ++++++++++++ .../Shaders/CWorldShadowShaderMetal.cpp | 91 ++++++++++++ Runtime/MP1/MP1.cpp | 4 + Runtime/Weapon/CPlayerGun.cpp | 27 ++-- Runtime/World/CMorphBall.cpp | 10 +- Runtime/World/CMorphBall.hpp | 13 +- Runtime/World/CPlayer.cpp | 2 +- Runtime/World/CWorldLight.hpp | 6 +- Runtime/World/CWorldShadow.cpp | 111 ++++++++++++++- Runtime/World/CWorldShadow.hpp | 15 +- hecl | 2 +- specter | 2 +- 38 files changed, 915 insertions(+), 110 deletions(-) create mode 100644 Runtime/Graphics/Shaders/CWorldShadowShader.cpp create mode 100644 Runtime/Graphics/Shaders/CWorldShadowShader.hpp create mode 100644 Runtime/Graphics/Shaders/CWorldShadowShaderGLSL.cpp create mode 100644 Runtime/Graphics/Shaders/CWorldShadowShaderHLSL.cpp create mode 100644 Runtime/Graphics/Shaders/CWorldShadowShaderMetal.cpp diff --git a/Editor/badging/Badging.cpp b/Editor/badging/Badging.cpp index 38560ff2d..de50a5aeb 100644 --- a/Editor/badging/Badging.cpp +++ b/Editor/badging/Badging.cpp @@ -33,7 +33,7 @@ boo::GraphicsDataToken InitializeBadging(specter::ViewResources& viewRes) specter::IconAtlas<1, 1> atlas; atlas.initializeAtlas(ctx.newStaticTexture(width, height, mips, - boo::TextureFormat::RGBA8, + boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, texels.get(), destSz)); g_BadgeIcon = atlas.getIcon(0, 0); return true; diff --git a/Editor/icons/icons.cpp b/Editor/icons/icons.cpp index 2a2604d42..3a17609bc 100644 --- a/Editor/icons/icons.cpp +++ b/Editor/icons/icons.cpp @@ -32,6 +32,7 @@ boo::GraphicsDataToken InitializeIcons(specter::ViewResources& viewRes) { g_IconAtlas.initializeAtlas(ctx.newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8, + boo::TextureClampMode::Repeat, texels.get(), destSz)); return true; }); diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 77945a6a3..22425c32c 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -694,7 +694,7 @@ void CStateManager::DrawWorld() const { const CGameArea& area = *areaArr[i]; SetupFogForArea(area); - g_Renderer->EnablePVS(&pvsArr[i], area.x4_selfIdx); + g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx); g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, targetMask); } @@ -767,7 +767,7 @@ void CStateManager::DrawWorld() const if (xf7c_projectedShadow) xf7c_projectedShadow->Render(*this); - g_Renderer->EnablePVS(&pvs, area.x4_selfIdx); + g_Renderer->EnablePVS(pvs, area.x4_selfIdx); g_Renderer->DrawSortedGeometry(area.x4_selfIdx, mask, targetMask); } @@ -801,7 +801,7 @@ void CStateManager::DrawWorld() const const CGameArea& area = *areaArr[i]; CPVSVisSet& pvs = pvsArr[i]; - g_Renderer->EnablePVS(&pvs, area.x4_selfIdx); + g_Renderer->EnablePVS(pvs, area.x4_selfIdx); g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, 0x20); g_Renderer->DrawAreaGeometry(area.x4_selfIdx, mask, 0x10); } @@ -832,7 +832,7 @@ void CStateManager::DrawWorld() const ++const_cast(*this).x8dc_objectDrawToken; - g_Renderer->EnablePVS(&pvs, area.x4_selfIdx); + g_Renderer->EnablePVS(pvs, area.x4_selfIdx); g_Renderer->DrawSortedGeometry(area.x4_selfIdx, mask, 0x10); } diff --git a/Runtime/Character/CActorLights.cpp b/Runtime/Character/CActorLights.cpp index 84e85da5e..ee3fb3fed 100644 --- a/Runtime/Character/CActorLights.cpp +++ b/Runtime/Character/CActorLights.cpp @@ -523,6 +523,12 @@ std::vector CActorLights::BuildLightVector() const { lights.push_back(*it); } + + if (x29c_shadowLightArrIdx > 0) + { + /* Ensure shadow light comes first for shader extension */ + std::swap(lights[0], lights[x29c_shadowLightArrIdx]); + } } for (const CLight& light : x144_dynamicLights) diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 4c5c3455c..30a31ccec 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -589,7 +589,7 @@ void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& } } x1b8_fogVolumeRamp = ctx.newStaticTexture(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, - boo::TextureFormat::I8, data[0], + boo::TextureFormat::I8, boo::TextureClampMode::Repeat, data[0], FOGVOL_RAMP_RES * FOGVOL_RAMP_RES); } @@ -606,7 +606,7 @@ void CBooRenderer::GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx } } x220_sphereRamp = ctx.newStaticTexture(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, - boo::TextureFormat::I8, data[0], + boo::TextureFormat::I8, boo::TextureClampMode::Repeat, data[0], SPHERE_RAMP_RES * SPHERE_RAMP_RES); } @@ -676,7 +676,7 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) { GenerateFogVolumeRampTex(ctx); GenerateSphereRampTex(ctx); - m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, true, false); + m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, boo::TextureClampMode::Repeat, 1, 0); GenerateScanLinesVBO(ctx); return true; }); @@ -734,9 +734,9 @@ void CBooRenderer::AddStaticGeometry(const std::vector* g } } -void CBooRenderer::EnablePVS(const CPVSVisSet* set, u32 areaIdx) +void CBooRenderer::EnablePVS(const CPVSVisSet& set, u32 areaIdx) { - xc8_pvs.emplace(*set); + xc8_pvs.emplace(set); xe0_pvsAreaIdx = areaIdx; } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 13038bb6f..afdf5e508 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -205,7 +205,7 @@ public: std::list::iterator FindStaticGeometry(const std::vector*); void AddStaticGeometry(const std::vector*, const CAreaRenderOctTree*, int areaIdx); - void EnablePVS(const CPVSVisSet*, u32); + void EnablePVS(const CPVSVisSet&, u32); void DisablePVS(); void RemoveStaticGeometry(const std::vector*); void DrawAreaGeometry(int areaIdx, int mask, int targetMask); @@ -279,7 +279,7 @@ public: boo::IGraphicsBuffer* GetScanLinesEvenVBO() const {return m_scanLinesEvenVBO;} boo::IGraphicsBuffer* GetScanLinesOddVBO() const {return m_scanLinesOddVBO;} - void BindMainDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture);} + static void BindMainDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture);} void BindReflectionDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex);} void BindBallShadowIdTarget() { diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 77084dcbe..852dd36cf 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -21,7 +21,8 @@ if(WIN32) Shaders/CElementGenShadersHLSL.cpp Shaders/CParticleSwooshShadersHLSL.cpp Shaders/CFluidPlaneShaderHLSL.cpp - Shaders/CAABoxShaderHLSL.cpp) + Shaders/CAABoxShaderHLSL.cpp + Shaders/CWorldShadowShaderHLSL.cpp) elseif(BOO_HAS_METAL) set(PLAT_SRCS Shaders/CLineRendererShadersMetal.cpp @@ -45,7 +46,8 @@ elseif(BOO_HAS_METAL) Shaders/CElementGenShadersMetal.cpp Shaders/CParticleSwooshShadersMetal.cpp Shaders/CFluidPlaneShaderMetal.cpp - Shaders/CAABoxShaderMetal.cpp) + Shaders/CAABoxShaderMetal.cpp + Shaders/CWorldShadowShaderMetal.cpp) endif() set(GRAPHICS_SOURCES @@ -92,6 +94,7 @@ set(GRAPHICS_SOURCES Shaders/CParticleSwooshShaders.hpp Shaders/CParticleSwooshShaders.cpp Shaders/CParticleSwooshShadersGLSL.cpp Shaders/CFluidPlaneShader.hpp Shaders/CFluidPlaneShader.cpp Shaders/CFluidPlaneShaderGLSL.cpp Shaders/CAABoxShader.hpp Shaders/CAABoxShader.cpp Shaders/CAABoxShaderGLSL.cpp + Shaders/CWorldShadowShader.hpp Shaders/CWorldShadowShader.cpp Shaders/CWorldShadowShaderGLSL.cpp ${PLAT_SRCS}) runtime_add_list(Graphics GRAPHICS_SOURCES) diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 9fc855de1..74381ce09 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -144,6 +144,8 @@ private: boo::ITexture* m_txtrOverrides[8] = {}; + boo::ITexture* m_lastDrawnShadowMap = nullptr; + ModelInstance* PushNewModelInstance(); void DrawAlphaSurfaces(const CModelFlags& flags) const; void DrawNormalSurfaces(const CModelFlags& flags) const; @@ -209,6 +211,18 @@ public: static void KillCachedViewDepState(); static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, zeus::CMatrix4f* mtxsOut, float& alphaOut); + + static boo::ITexture* g_shadowMap; + static zeus::CTransform g_shadowTexXf; + static void EnableShadowMaps(boo::ITexture* map, const zeus::CTransform& texXf) + { + g_shadowMap = map; + g_shadowTexXf = texXf; + } + static void DisableShadowMaps() + { + g_shadowMap = nullptr; + } }; class CModel diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index b06992d14..d2dba2be0 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -123,6 +123,9 @@ void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurfa } } +boo::ITexture* CBooModel::g_shadowMap = nullptr; +zeus::CTransform CBooModel::g_shadowTexXf; + CBooModel::~CBooModel() { if (m_prev) @@ -334,7 +337,6 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() texs[texCount++] = tex.GetObj()->GetBooTexture(); } } - texs[7] = g_Renderer->x220_sphereRamp; if (skinBankCount) { @@ -380,6 +382,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() if (idx == EExtendedShader::Thermal) { texCount = 8; + texs[7] = g_Renderer->x220_sphereRamp; ltexs = texs; } else if (idx == EExtendedShader::MorphBallShadow) @@ -387,6 +390,12 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() texCount = 3; ltexs = mbShadowTexs; } + else if (idx == EExtendedShader::WorldShadow) + { + texCount = 8; + texs[7] = g_shadowMap; + ltexs = texs; + } else if (useReflection) { texCount = mat.textureIdxs.size() + 1; @@ -698,31 +707,47 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet return; } - /* Special Mode0 matrix for exclusive Thermal Visor use */ - std::experimental::optional> thermalMtxOut; + std::experimental::optional> specialMtxOut; if (flags.m_extendedShader == EExtendedShader::Thermal) { - thermalMtxOut.emplace(); + /* Special Mode0 matrix for exclusive Thermal Visor use */ + specialMtxOut.emplace(); - zeus::CMatrix4f& texMtxOut = (*thermalMtxOut)[0]; + zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0]; texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); texMtxOut.vec[3].zeroOut(); texMtxOut.vec[3].w = 1.f; - zeus::CMatrix4f& postMtxOut = (*thermalMtxOut)[1]; + zeus::CMatrix4f& postMtxOut = (*specialMtxOut)[1]; postMtxOut.vec[0].x = 0.5f; postMtxOut.vec[1].y = 0.5f; postMtxOut.vec[3].x = 0.5f; postMtxOut.vec[3].y = 0.5f; } + else if (flags.m_extendedShader == EExtendedShader::WorldShadow) + { + /* Special matrix for mapping world shadow */ + specialMtxOut.emplace(); + + zeus::CMatrix4f mat = g_shadowTexXf.toMatrix4f(); + zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0]; + texMtxOut[0][0] = mat[0][0]; + texMtxOut[1][0] = mat[1][0]; + texMtxOut[2][0] = mat[2][0]; + texMtxOut[3][0] = mat[3][0]; + texMtxOut[0][1] = mat[0][2]; + texMtxOut[1][1] = mat[1][2]; + texMtxOut[2][1] = mat[2][2]; + texMtxOut[3][1] = mat[3][2]; + } for (const MaterialSet::Material& mat : matSet->materials) { - if (thermalMtxOut) + if (specialMtxOut) { std::array* mtxs = reinterpret_cast*>(bufOut); - mtxs[7][0] = (*thermalMtxOut)[0]; - mtxs[7][1] = (*thermalMtxOut)[1]; + mtxs[7][0] = (*specialMtxOut)[0]; + mtxs[7][1] = (*specialMtxOut)[1]; } u8* bufOrig = bufOut; for (const UVAnimation& anim : mat.uvAnims) @@ -744,6 +769,14 @@ boo::IGraphicsBufferD* CBooModel::UpdateUniformData(const CModelFlags& flags, weightVecCount = model->m_hmdlMeta.weightCount; } + /* Invalidate instances if new shadow being drawn */ + if (flags.m_extendedShader == EExtendedShader::WorldShadow && + m_lastDrawnShadowMap != g_shadowMap) + { + const_cast(this)->m_lastDrawnShadowMap = g_shadowMap; + const_cast(this)->m_instances.clear(); + } + const ModelInstance* inst; if (m_instances.size() <= m_uniUpdateCount) { diff --git a/Runtime/Graphics/CMoviePlayer.cpp b/Runtime/Graphics/CMoviePlayer.cpp index a6c2e96ab..a888f8f72 100644 --- a/Runtime/Graphics/CMoviePlayer.cpp +++ b/Runtime/Graphics/CMoviePlayer.cpp @@ -449,18 +449,14 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo if (deinterlace) { /* urde addition: this way interlaced THPs don't look horrible */ - set.Y[0] = ctx.newDynamicTexture(x6c_videoInfo.width, - x6c_videoInfo.height / 2, - boo::TextureFormat::I8); - set.Y[1] = ctx.newDynamicTexture(x6c_videoInfo.width, - x6c_videoInfo.height / 2, - boo::TextureFormat::I8); - set.U = ctx.newDynamicTexture(x6c_videoInfo.width / 2, - x6c_videoInfo.height / 2, - boo::TextureFormat::I8); - set.V = ctx.newDynamicTexture(x6c_videoInfo.width / 2, - x6c_videoInfo.height / 2, - boo::TextureFormat::I8); + set.Y[0] = ctx.newDynamicTexture(x6c_videoInfo.width, x6c_videoInfo.height / 2, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); + set.Y[1] = ctx.newDynamicTexture(x6c_videoInfo.width, x6c_videoInfo.height / 2, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); + set.U = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); + set.V = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); boo::IGraphicsBuffer* bufs[] = {m_blockBuf}; for (int j=0 ; j<2 ; ++j) @@ -474,15 +470,12 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo else { /* normal progressive presentation */ - set.Y[0] = ctx.newDynamicTexture(x6c_videoInfo.width, - x6c_videoInfo.height, - boo::TextureFormat::I8); - set.U = ctx.newDynamicTexture(x6c_videoInfo.width / 2, - x6c_videoInfo.height / 2, - boo::TextureFormat::I8); - set.V = ctx.newDynamicTexture(x6c_videoInfo.width / 2, - x6c_videoInfo.height / 2, - boo::TextureFormat::I8); + set.Y[0] = ctx.newDynamicTexture(x6c_videoInfo.width, x6c_videoInfo.height, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); + set.U = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); + set.V = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, + boo::TextureFormat::I8, boo::TextureClampMode::Repeat); boo::IGraphicsBuffer* bufs[] = {m_blockBuf}; boo::ITexture* texs[] = {set.Y[0], set.U, set.V}; diff --git a/Runtime/Graphics/CPVSAreaSet.hpp b/Runtime/Graphics/CPVSAreaSet.hpp index fda5f0969..2ae458ee4 100644 --- a/Runtime/Graphics/CPVSAreaSet.hpp +++ b/Runtime/Graphics/CPVSAreaSet.hpp @@ -19,6 +19,14 @@ class CPVSAreaSet const u8* x1c_lightLeaves; CPVSVisOctree x20_octree; + CPVSVisSet _GetLightSet(u32 lightIdx) const + { + CPVSVisSet ret; + ret.SetFromMemory(x20_octree.GetTotalBits(), x20_octree.GetLightBits(), + x1c_lightLeaves + x10_leafSize * lightIdx); + return ret; + } + public: CPVSAreaSet(const u8* data, u32 len); u32 GetNumFeatures() const { return x0_numFeatures; } @@ -28,6 +36,8 @@ public: bool Has2ndLayerLights() const { return x8_num2ndLights != 0; } u32 GetEntityIdByIndex(int idx) const { return x18_entityIndex[idx]; } const CPVSVisOctree& GetVisOctree() const { return x20_octree; } + CPVSVisSet Get1stLightSet(u32 lightIdx) const { return _GetLightSet(x8_num2ndLights + lightIdx); } + CPVSVisSet Get2ndLightSet(u32 lightIdx) const { return _GetLightSet(lightIdx); } }; } diff --git a/Runtime/Graphics/CTextureBoo.cpp b/Runtime/Graphics/CTextureBoo.cpp index b3e8b3ae4..3921d6211 100644 --- a/Runtime/Graphics/CTextureBoo.cpp +++ b/Runtime/Graphics/CTextureBoo.cpp @@ -115,7 +115,7 @@ void CTexture::BuildI4FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -163,7 +163,7 @@ void CTexture::BuildI8FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -212,7 +212,7 @@ void CTexture::BuildIA4FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -261,7 +261,7 @@ void CTexture::BuildIA8FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -369,7 +369,7 @@ void CTexture::BuildC4FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -413,7 +413,7 @@ void CTexture::BuildC8FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -465,7 +465,7 @@ void CTexture::BuildRGB565FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -522,7 +522,7 @@ void CTexture::BuildRGB5A3FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -579,7 +579,7 @@ void CTexture::BuildRGBA8FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * 4); return true; }); } @@ -643,7 +643,7 @@ void CTexture::BuildDXT1FromGCN(CInputStream& in) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::DXT1, - buf.get(), blockCount * 8); + boo::TextureClampMode::Repeat, buf.get(), blockCount * 8); return true; }); } @@ -659,7 +659,7 @@ void CTexture::BuildRGBA8(const void* data, size_t length) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - data, expectedSize); + boo::TextureClampMode::Repeat, data, expectedSize); return true; }); } @@ -677,9 +677,9 @@ void CTexture::BuildC8(const void* data, size_t length) const u8* paletteTexels = reinterpret_cast(data) + 4; const u8* texels = reinterpret_cast(data) + 4 + nentries * 4; m_paletteTex = ctx.newStaticTexture(nentries, 1, 1, boo::TextureFormat::RGBA8, - paletteTexels, nentries * 4); + boo::TextureClampMode::Repeat, paletteTexels, nentries * 4); m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::I8, - texels, texelCount); + boo::TextureClampMode::Repeat, texels, texelCount); return true; }); } @@ -781,7 +781,7 @@ void CTexture::BuildC8Font(const void* data, EFontType ftype) m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_booTex = ctx.newStaticArrayTexture(x4_w, x6_h, layerCount, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * layerCount * 4); + boo::TextureClampMode::Repeat, buf.get(), texelCount * layerCount * 4); return true; }); } diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index 300786d20..7da7069a1 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -45,7 +45,7 @@ public: virtual ~IRenderer() = default; virtual void AddStaticGeometry(const std::vector*, const CAreaRenderOctTree*, int)=0; - virtual void EnablePVS(const CPVSVisSet*, u32)=0; + virtual void EnablePVS(const CPVSVisSet&, u32)=0; virtual void DisablePVS()=0; virtual void RemoveStaticGeometry(const std::vector*)=0; virtual void DrawAreaGeometry(int areaIdx, int mask, int targetMask)=0; diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilterGLSL.cpp b/Runtime/Graphics/Shaders/CColoredQuadFilterGLSL.cpp index cf2c7b7de..1da906d84 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilterGLSL.cpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilterGLSL.cpp @@ -1,6 +1,4 @@ #include "CColoredQuadFilter.hpp" -#include "TMultiBlendShader.hpp" -#include "Graphics/CTexture.hpp" namespace urde { diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilterHLSL.cpp b/Runtime/Graphics/Shaders/CColoredQuadFilterHLSL.cpp index a61fb9bc7..30dd7230c 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilterHLSL.cpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilterHLSL.cpp @@ -1,6 +1,4 @@ #include "CColoredQuadFilter.hpp" -#include "TMultiBlendShader.hpp" -#include "Graphics/CTexture.hpp" namespace urde { diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilterMetal.cpp b/Runtime/Graphics/Shaders/CColoredQuadFilterMetal.cpp index e1bef2acb..b15e9e0b3 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilterMetal.cpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilterMetal.cpp @@ -1,6 +1,4 @@ #include "CColoredQuadFilter.hpp" -#include "TMultiBlendShader.hpp" -#include "Graphics/CTexture.hpp" namespace urde { diff --git a/Runtime/Graphics/Shaders/CModelShaders.cpp b/Runtime/Graphics/Shaders/CModelShaders.cpp index 54cb7e761..90ccb8472 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.cpp +++ b/Runtime/Graphics/Shaders/CModelShaders.cpp @@ -87,6 +87,11 @@ const hecl::Backend::TextureInfo CModelShaders::BallFadeTextures[] = {hecl::Backend::TexGenSrc::Position, 2, 0, 1, false} // TXTR_BallFade }; +const hecl::Backend::TextureInfo CModelShaders::WorldShadowTextures[] = +{ + {hecl::Backend::TexGenSrc::Position, 7, 0, 7, false} // Shadow tex +}; + CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr, boo::IGraphicsDataFactory* gfxFactory) : m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {} diff --git a/Runtime/Graphics/Shaders/CModelShaders.hpp b/Runtime/Graphics/Shaders/CModelShaders.hpp index 0c6eb0ff4..31d687f17 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.hpp +++ b/Runtime/Graphics/Shaders/CModelShaders.hpp @@ -25,7 +25,8 @@ enum EExtendedShader : uint8_t SolidColorFrontfaceCullAlwaysAlphaOnly, // No Z-write or test SolidColorBackfaceCullLEqualAlphaOnly, SolidColorBackfaceCullGreaterAlphaOnly, // No Z-write - MorphBallShadow + MorphBallShadow, + WorldShadow }; class CModelShaders @@ -39,6 +40,7 @@ class CModelShaders static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat); static const hecl::Backend::TextureInfo ThermalTextures[]; static const hecl::Backend::TextureInfo BallFadeTextures[]; + static const hecl::Backend::TextureInfo WorldShadowTextures[]; public: struct Light { diff --git a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp index 2477c7bde..d92ee9395 100644 --- a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp @@ -52,6 +52,66 @@ static const char* LightingGLSL = " return clamp(ret, vec4(0.0,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1.0));\n" "}\n"; +static const char* LightingShadowGLSL = +"struct Light\n" +"{\n" +" vec4 pos;\n" +" vec4 dir;\n" +" vec4 color;\n" +" vec4 linAtt;\n" +" vec4 angAtt;\n" +"};\n" +"struct Fog\n" +"{\n" +" vec4 color;\n" +" float rangeScale;\n" +" float start;\n" +"};\n" +"\n" +"UBINDING2 uniform LightingUniform\n" +"{\n" +" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n" +" vec4 ambient;\n" +" vec4 colorReg0;\n" +" vec4 colorReg1;\n" +" vec4 colorReg2;\n" +" vec4 mulColor;\n" +" Fog fog;\n" +"};\n" +"\n" +"vec4 LightingShadowFunc(vec4 mvPosIn, vec4 mvNormIn)\n" +"{\n" +" vec4 ret = ambient;\n" +" \n" +" vec3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n" +" float dist = length(delta);\n" +" float angDot = clamp(dot(normalize(delta), lights[i].dir.xyz), 0.0, 1.0);\n" +" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n" +" lights[i].linAtt[1] * dist +\n" +" lights[i].linAtt[0]);\n" +" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n" +" lights[i].angAtt[1] * angDot +\n" +" lights[i].angAtt[0];\n" +" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn.xyz), 0.0, 1.0) *\n" +" texture(extTex0, vtf.extTcgs[0]).r;\n" +" \n" +" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n" +" {\n" +" vec3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n" +" float dist = length(delta);\n" +" float angDot = clamp(dot(normalize(delta), lights[i].dir.xyz), 0.0, 1.0);\n" +" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n" +" lights[i].linAtt[1] * dist +\n" +" lights[i].linAtt[0]);\n" +" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n" +" lights[i].angAtt[1] * angDot +\n" +" lights[i].angAtt[0];\n" +" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn.xyz), 0.0, 1.0);\n" +" }\n" +" \n" +" return clamp(ret, vec4(0.0,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1.0));\n" +"}\n"; + static const char* MainPostGLSL = "vec4 MainPostFunc(vec4 colorIn)\n" "{\n" @@ -190,6 +250,20 @@ CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat) hecl::Backend::ZTest::Equal, false, false, false, true); + /* MorphBall shadow shading */ + ext.registerExtensionSlot({}, {MBShadowPostGLSL, "MBShadowPostFunc"}, + 3, MBShadowBlockNames, 3, BallFadeTextures, + hecl::Backend::BlendFactor::SrcAlpha, + hecl::Backend::BlendFactor::InvSrcAlpha, + hecl::Backend::ZTest::Equal, + false, false, false, true); + + /* World shadow shading (modified lighting) */ + ext.registerExtensionSlot({LightingShadowGLSL, "LightingShadowFunc"}, {MainPostGLSL, "MainPostFunc"}, + 3, BlockNames, 1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, + hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::Original, + false, false, false, true); + return ext; } diff --git a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp index f29674c18..08e4d905e 100644 --- a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp @@ -30,7 +30,7 @@ static const char* LightingHLSL = " Fog fog;\n" "};\n" "\n" -"static float4 LightingFunc(float4 mvPosIn, float4 mvNormIn)\n" +"static float4 LightingFunc(float4 mvPosIn, float4 mvNormIn, in VertToFrag vtf)\n" "{\n" " float4 ret = ambient;\n" " \n" @@ -51,6 +51,66 @@ static const char* LightingHLSL = " return saturate(ret);\n" "}\n"; +static const char* LightingShadowHLSL = +"struct Light\n" +"{\n" +" float4 pos;\n" +" float4 dir;\n" +" float4 color;\n" +" float4 linAtt;\n" +" float4 angAtt;\n" +"};\n" +"struct Fog\n" +"{\n" +" float4 color;\n" +" float rangeScale;\n" +" float start;\n" +"};\n" +"\n" +"cbuffer LightingUniform : register(b2)\n" +"{\n" +" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n" +" float4 ambient;\n" +" float4 colorReg0;\n" +" float4 colorReg1;\n" +" float4 colorReg2;\n" +" float4 mulColor;\n" +" Fog fog;\n" +"};\n" +"\n" +"static float4 LightingShadowFunc(float4 mvPosIn, float4 mvNormIn, in VertToFrag vtf)\n" +"{\n" +" float4 ret = ambient;\n" +" \n" +" float3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n" +" float dist = length(delta);\n" +" float angDot = saturate(dot(normalize(delta), lights[i].dir.xyz));\n" +" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n" +" lights[i].linAtt[1] * dist +\n" +" lights[i].linAtt[0]);\n" +" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n" +" lights[i].angAtt[1] * angDot +\n" +" lights[i].angAtt[0];\n" +" ret += lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn.xyz)) *\n" +" extTex0.Sample(clampSamp, vtf.extTcgs[0]).r;\n" +" \n" +" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n" +" {\n" +" float3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n" +" float dist = length(delta);\n" +" float angDot = saturate(dot(normalize(delta), lights[i].dir.xyz));\n" +" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n" +" lights[i].linAtt[1] * dist +\n" +" lights[i].linAtt[0]);\n" +" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n" +" lights[i].angAtt[1] * angDot +\n" +" lights[i].angAtt[0];\n" +" ret += lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn.xyz));\n" +" }\n" +" \n" +" return saturate(ret);\n" +"}\n"; + static const char* MainPostHLSL = "static float4 MainPostFunc(in VertToFrag vtf, float4 colorIn)\n" "{\n" @@ -173,6 +233,12 @@ CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat) hecl::Backend::ZTest::Equal, false, false, false, true); + /* World shadow shading (modified lighting) */ + ext.registerExtensionSlot({LightingShadowHLSL, "LightingShadowFunc"}, {MainPostHLSL, "MainPostFunc"}, + 0, nullptr, 1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, + hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::Original, + false, false, false, true); + return ext; } diff --git a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp index ce9731b42..74ff1a9f1 100644 --- a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp @@ -30,7 +30,7 @@ static const char* LightingMetal = " Fog fog;\n" "};\n" "\n" -"static float4 LightingFunc(constant LightingUniform& lu, float4 mvPosIn, float4 mvNormIn)\n" +"static float4 LightingFunc(constant LightingUniform& lu, float4 mvPosIn, float4 mvNormIn, thread VertToFrag& vtf)\n" "{\n" " float4 ret = lu.ambient;\n" " \n" @@ -51,6 +51,67 @@ static const char* LightingMetal = " return saturate(ret);\n" "}\n"; +static const char* LightingShadowMetal = +"struct Light\n" +"{\n" +" float4 pos;\n" +" float4 dir;\n" +" float4 color;\n" +" float4 linAtt;\n" +" float4 angAtt;\n" +"};\n" +"struct Fog\n" +"{\n" +" float4 color;\n" +" float rangeScale;\n" +" float start;\n" +"};\n" +"\n" +"struct LightingUniform\n" +"{\n" +" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n" +" float4 ambient;\n" +" float4 colorReg0;\n" +" float4 colorReg1;\n" +" float4 colorReg2;\n" +" float4 mulColor;\n" +" Fog fog;\n" +"};\n" +"\n" +"static float4 EXTLightingShadowFunc(constant LightingUniform& lu, float4 mvPosIn, float4 mvNormIn,\n" +" thread VertToFrag& vtf, texture2d extTex0)\n" +"{\n" +" float4 ret = lu.ambient;\n" +" \n" +" float3 delta = mvPosIn.xyz - lu.lights[i].pos.xyz;\n" +" float dist = length(delta);\n" +" float angDot = saturate(dot(normalize(delta), lu.lights[i].dir.xyz));\n" +" float att = 1.0 / (lu.lights[i].linAtt[2] * dist * dist +\n" +" lu.lights[i].linAtt[1] * dist +\n" +" lu.lights[i].linAtt[0]);\n" +" float angAtt = lu.lights[i].angAtt[2] * angDot * angDot +\n" +" lu.lights[i].angAtt[1] * angDot +\n" +" lu.lights[i].angAtt[0];\n" +" ret += lu.lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn.xyz)) *\n" +" extTex0.sample(clampSamp, vtf.extTcgs0);\n" +" \n" +" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n" +" {\n" +" float3 delta = mvPosIn.xyz - lu.lights[i].pos.xyz;\n" +" float dist = length(delta);\n" +" float angDot = saturate(dot(normalize(delta), lu.lights[i].dir.xyz));\n" +" float att = 1.0 / (lu.lights[i].linAtt[2] * dist * dist +\n" +" lu.lights[i].linAtt[1] * dist +\n" +" lu.lights[i].linAtt[0]);\n" +" float angAtt = lu.lights[i].angAtt[2] * angDot * angDot +\n" +" lu.lights[i].angAtt[1] * angDot +\n" +" lu.lights[i].angAtt[0];\n" +" ret += lu.lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn.xyz));\n" +" }\n" +" \n" +" return saturate(ret);\n" +"}\n"; + static const char* MainPostMetal = "float4 MainPostFunc(thread VertToFrag& vtf, constant LightingUniform& lu, float4 colorIn)\n" "{\n" @@ -179,6 +240,12 @@ CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat hecl::Backend::ZTest::Equal, false, false, false, true); + /* World shadow shading (modified lighting) */ + ext.registerExtensionSlot({LightingShadowMetal, "EXTLightingShadowFunc"}, {MainPostMetal, "MainPostFunc"}, + 1, BlockNames, 1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, + hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::Original, + false, false, false, true); + return ext; } diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp index e865ed9a9..f90dce204 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -27,8 +27,8 @@ void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& c } } m_warpTex = ctx.newStaticTexture(WARP_RAMP_RES+1, WARP_RAMP_RES+1, 1, - boo::TextureFormat::RGBA8, data[0], - (WARP_RAMP_RES+1) * (WARP_RAMP_RES+1) * 4); + boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, + data[0], (WARP_RAMP_RES+1) * (WARP_RAMP_RES+1) * 4); } CSpaceWarpFilter::CSpaceWarpFilter() diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp index 14123a04f..de68190a1 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp @@ -8,7 +8,7 @@ CThermalColdFilter::CThermalColdFilter() { m_token = CGraphics::g_BooFactory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { - m_shiftTex = ctx.newDynamicTexture(8, 4, boo::TextureFormat::RGBA8); + m_shiftTex = ctx.newDynamicTexture(8, 4, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat); struct Vert { diff --git a/Runtime/Graphics/Shaders/CWorldShadowShader.cpp b/Runtime/Graphics/Shaders/CWorldShadowShader.cpp new file mode 100644 index 000000000..329fbbf25 --- /dev/null +++ b/Runtime/Graphics/Shaders/CWorldShadowShader.cpp @@ -0,0 +1,59 @@ +#include "CWorldShadowShader.hpp" + +namespace urde +{ + +CWorldShadowShader::CWorldShadowShader(u32 w, u32 h) +: m_w(w), m_h(h) {} + +void CWorldShadowShader::_buildTex(boo::IGraphicsDataFactory::Context& ctx) +{ + m_tex = ctx.newRenderTexture(m_w, m_h, boo::TextureClampMode::ClampToWhite, 1, 0); +} + +void CWorldShadowShader::bindRenderTarget() +{ + CGraphics::g_BooMainCommandQueue->setRenderTarget(m_tex); +} + +void CWorldShadowShader::drawBase(float extent) +{ + zeus::CVector3f verts[] = {{-extent, 0.f, extent}, {extent, 0.f, extent}, + {-extent, 0.f, -extent}, {extent, 0.f, -extent}}; + m_vbo->load(verts, sizeof(zeus::CVector3f) * 4); + + m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_color = zeus::CColor::skWhite; + m_uniBuf->load(&m_uniform, sizeof(m_uniform)); + + CGraphics::SetShaderDataBinding(m_zDataBind); + CGraphics::DrawArray(0, 4); +} + +void CWorldShadowShader::lightenShadow() +{ + m_uniform.m_color = zeus::CColor(1.f, 0.25f); + m_uniBuf->load(&m_uniform, sizeof(m_uniform)); + + CGraphics::SetShaderDataBinding(m_dataBind); + CGraphics::DrawArray(0, 4); +} + +void CWorldShadowShader::blendPreviousShadow() +{ + if (!m_prevQuad) + m_prevQuad.emplace(EFilterType::Blend, m_tex); + m_prevQuad->draw({1.f, 0.85f}, 1.f); +} + +void CWorldShadowShader::resolveTexture() +{ + boo::SWindowRect rect = {0, 0, m_w, m_h}; + CGraphics::g_BooMainCommandQueue->resolveBindTexture(m_tex, rect, false, 0, true, false); +} + +void CWorldShadowShader::Shutdown() {} + +URDE_SPECIALIZE_SHADER(CWorldShadowShader) + +} diff --git a/Runtime/Graphics/Shaders/CWorldShadowShader.hpp b/Runtime/Graphics/Shaders/CWorldShadowShader.hpp new file mode 100644 index 000000000..b3b163746 --- /dev/null +++ b/Runtime/Graphics/Shaders/CWorldShadowShader.hpp @@ -0,0 +1,55 @@ +#ifndef URDE_CWORLDSHADOWSHADER_HPP +#define URDE_CWORLDSHADOWSHADER_HPP + +#include "TShader.hpp" +#include "CColoredQuadFilter.hpp" +#include "CTexturedQuadFilter.hpp" + +namespace urde +{ + +class CWorldShadowShader +{ + friend class CWorldShadowShaderGLDataBindingFactory; + friend class CWorldShadowShaderVulkanDataBindingFactory; + friend class CWorldShadowShaderD3DDataBindingFactory; + friend class CWorldShadowShaderMetalDataBindingFactory; + + boo::ITextureR* m_tex; + std::experimental::optional m_prevQuad; + u32 m_w, m_h; + + struct Uniform + { + zeus::CMatrix4f m_matrix; + zeus::CColor m_color; + }; + boo::GraphicsDataToken m_token; + boo::IGraphicsBufferD* m_vbo; + boo::IGraphicsBufferD* m_uniBuf; + boo::IShaderDataBinding* m_dataBind = nullptr; + boo::IShaderDataBinding* m_zDataBind = nullptr; + Uniform m_uniform; + + void _buildTex(boo::IGraphicsDataFactory::Context& ctx); + +public: + CWorldShadowShader(u32 w, u32 h); + void bindRenderTarget(); + void drawBase(float extent); + void lightenShadow(); + void blendPreviousShadow(); + void resolveTexture(); + + u32 GetWidth() const { return m_w; } + u32 GetHeight() const { return m_h; } + + boo::ITexture* GetTexture() const { return m_tex; } + + using _CLS = CWorldShadowShader; +#include "TShaderDecl.hpp" +}; + +} + +#endif // URDE_CWORLDSHADOWSHADER_HPP diff --git a/Runtime/Graphics/Shaders/CWorldShadowShaderGLSL.cpp b/Runtime/Graphics/Shaders/CWorldShadowShaderGLSL.cpp new file mode 100644 index 000000000..5fedad08f --- /dev/null +++ b/Runtime/Graphics/Shaders/CWorldShadowShaderGLSL.cpp @@ -0,0 +1,129 @@ +#include "CWorldShadowShader.hpp" + +namespace urde +{ + +static const char* VS = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"layout(location=0) in vec4 posIn;\n" +"\n" +"UBINDING0 uniform ColoredQuadUniform\n" +"{\n" +" mat4 xf;\n" +" vec4 color;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" vec4 color;\n" +"};\n" +"\n" +"SBINDING(0) out VertToFrag vtf;\n" +"void main()\n" +"{\n" +" vtf.color = color;\n" +" gl_Position = xf * vec4(posIn.xyz, 1.0);\n" +"}\n"; + +static const char* FS = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"struct VertToFrag\n" +"{\n" +" vec4 color;\n" +"};\n" +"\n" +"SBINDING(0) in VertToFrag vtf;\n" +"layout(location=0) out vec4 colorOut;\n" +"void main()\n" +"{\n" +" colorOut = vtf.color;\n" +"}\n"; + +URDE_DECL_SPECIALIZE_SHADER(CWorldShadowShader) + +static boo::IVertexFormat* s_VtxFmt = nullptr; +static boo::IShaderPipeline* s_Pipeline = nullptr; +static boo::IShaderPipeline* s_ZPipeline = nullptr; + +struct CWorldShadowShaderGLDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CWorldShadowShader& filter) + { + boo::GLDataFactory::Context& cctx = static_cast(ctx); + + const boo::VertexElementDescriptor VtxVmt[] = + { + {filter.m_vbo, nullptr, boo::VertexSemantic::Position4} + }; + boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf}; + boo::PipelineStage stages[] = {boo::PipelineStage::Vertex}; + boo::IVertexFormat* vtxFmt = ctx.newVertexFormat(1, VtxVmt); + filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, + vtxFmt, filter.m_vbo, nullptr, nullptr, + 1, bufs, stages, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter.m_zDataBind = cctx.newShaderDataBinding(s_ZPipeline, + vtxFmt, filter.m_vbo, nullptr, nullptr, + 1, bufs, stages, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter._buildTex(ctx); + return nullptr; + } +}; + +#if BOO_HAS_VULKAN +struct CWorldShadowShaderVulkanDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CWorldShadowShader& filter) + { + boo::VulkanDataFactory::Context& cctx = static_cast(ctx); + + boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf}; + filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, s_VtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter.m_zDataBind = cctx.newShaderDataBinding(s_ZPipeline, s_VtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter._buildTex(ctx); + return nullptr; + } +}; +#endif + +TShader::IDataBindingFactory* +CWorldShadowShader::Initialize(boo::GLDataFactory::Context& ctx) +{ + const char* uniNames[] = {"ColoredQuadUniform"}; + s_Pipeline = ctx.newShaderPipeline(VS, FS, 0, nullptr, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_ZPipeline = ctx.newShaderPipeline(VS, FS, 0, nullptr, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + return new CWorldShadowShaderGLDataBindingFactory; +} + +#if BOO_HAS_VULKAN +TShader::IDataBindingFactory* +CWorldShadowShader::Initialize(boo::VulkanDataFactory::Context& ctx) +{ + const boo::VertexElementDescriptor VtxVmt[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4} + }; + s_VtxFmt = ctx.newVertexFormat(1, VtxVmt); + s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_ZPipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + return new CWorldShadowShaderVulkanDataBindingFactory; +} +#endif + +} + diff --git a/Runtime/Graphics/Shaders/CWorldShadowShaderHLSL.cpp b/Runtime/Graphics/Shaders/CWorldShadowShaderHLSL.cpp new file mode 100644 index 000000000..2097e0195 --- /dev/null +++ b/Runtime/Graphics/Shaders/CWorldShadowShaderHLSL.cpp @@ -0,0 +1,89 @@ +#include "CWorldShadowShader.hpp" + +namespace urde +{ + +static const char* VS = +"struct VertData\n" +"{\n" +" float4 posIn : POSITION;\n" +"};\n" +"\n" +"cbuffer ColoredQuadUniform : register(b0)\n" +"{\n" +" float4x4 xf;\n" +" float4 color;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" float4 position : SV_Position;\n" +" float4 color : COLOR;\n" +"};\n" +"\n" +"VertToFrag main(in VertData v)\n" +"{\n" +" VertToFrag vtf;\n" +" vtf.color = color;\n" +" vtf.position = mul(xf, float4(v.posIn.xyz, 1.0));\n" +" return vtf;\n" +"}\n"; + +static const char* FS = +"struct VertToFrag\n" +"{\n" +" float4 position : SV_Position;\n" +" float4 color : COLOR;\n" +"};\n" +"\n" +"float4 main(in VertToFrag vtf) : SV_Target0\n" +"{\n" +" return vtf.color;\n" +"}\n"; + +URDE_DECL_SPECIALIZE_SHADER(CWorldShadowShader) + +static boo::IVertexFormat* s_VtxFmt = nullptr; +static boo::IShaderPipeline* s_Pipeline = nullptr; +static boo::IShaderPipeline* s_ZPipeline = nullptr; + +struct CWorldShadowShaderD3DDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CWorldShadowShader& filter) + { + boo::ID3DDataFactory::Context& cctx = static_cast(ctx); + + boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf}; + filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, + nullptr, nullptr, nullptr, s_VtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter.m_zDataBind = cctx.newShaderDataBinding(s_ZPipeline, + nullptr, nullptr, nullptr, s_VtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter._buildTex(ctx); + return nullptr; + } +}; + +TShader::IDataBindingFactory* +CWorldShadowShader::Initialize(boo::ID3DDataFactory::Context& ctx) +{ + const boo::VertexElementDescriptor VtxVmt[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4} + }; + s_VtxFmt = ctx.newVertexFormat(1, VtxVmt); + s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_ZPipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + return new CWorldShadowShaderD3DDataBindingFactory; +} + +} + diff --git a/Runtime/Graphics/Shaders/CWorldShadowShaderMetal.cpp b/Runtime/Graphics/Shaders/CWorldShadowShaderMetal.cpp new file mode 100644 index 000000000..787fc662d --- /dev/null +++ b/Runtime/Graphics/Shaders/CWorldShadowShaderMetal.cpp @@ -0,0 +1,91 @@ +#include "CWorldShadowShader.hpp" + +namespace urde +{ + +static const char* VS = +"#include \n" +"using namespace metal;\n" +"struct VertData\n" +"{\n" +" float4 posIn [[ attribute(0) ]];\n" +"};\n" +"\n" +"struct ColoredQuadUniform\n" +"{\n" +" float4x4 xf;\n" +" float4 color;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" float4 position [[ position ]];\n" +" float4 color;\n" +"};\n" +"\n" +"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant ColoredQuadUniform& cqu [[ buffer(2) ]])\n" +"{\n" +" VertToFrag vtf;\n" +" vtf.color = cqu.color;\n" +" vtf.position = cqu.xf * float4(v.posIn.xyz, 1.0);\n" +" return vtf;\n" +"}\n"; + +static const char* FS = +"#include \n" +"using namespace metal;\n" +"struct VertToFrag\n" +"{\n" +" float4 position [[ position ]];\n" +" float4 color;\n" +"};\n" +"\n" +"fragment float4 fmain(VertToFrag vtf [[ stage_in ]])\n" +"{\n" +" return vtf.color;\n" +"}\n"; + +URDE_DECL_SPECIALIZE_SHADER(CWorldShadowShader) + +static boo::IVertexFormat* s_VtxFmt = nullptr; +static boo::IShaderPipeline* s_Pipeline = nullptr; +static boo::IShaderPipeline* s_ZPipeline = nullptr; + +struct CWorldShadowShaderMetalDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CWorldShadowShader& filter) + { + boo::MetalDataFactory::Context& cctx = static_cast(ctx); + + boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf}; + filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, s_VtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter.m_zDataBind = cctx.newShaderDataBinding(s_ZPipeline, s_VtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr); + filter._buildTex(ctx); + return nullptr; + } +}; + +TShader::IDataBindingFactory* +CWorldShadowShader::Initialize(boo::MetalDataFactory::Context& ctx) +{ + const boo::VertexElementDescriptor VtxVmt[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4} + }; + s_VtxFmt = ctx.newVertexFormat(1, VtxVmt); + s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, CGraphics::g_ViewportSamples, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_ZPipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, CGraphics::g_ViewportSamples, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + return new CWorldShadowShaderMetalDataBindingFactory; +} + +} + diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 7dacf97fc..265b189ca 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -16,6 +16,7 @@ #include "Graphics/Shaders/CRandomStaticFilter.hpp" #include "Graphics/Shaders/CFluidPlaneShader.hpp" #include "Graphics/Shaders/CAABoxShader.hpp" +#include "Graphics/Shaders/CWorldShadowShader.hpp" #include "Character/CCharLayoutInfo.hpp" #include "Audio/CStreamAudioManager.hpp" #include "CGBASupport.hpp" @@ -36,6 +37,7 @@ URDE_DECL_SPECIALIZE_SHADER(CRadarPaintShader) URDE_DECL_SPECIALIZE_SHADER(CMapSurfaceShader) URDE_DECL_SPECIALIZE_SHADER(CPhazonSuitFilter) URDE_DECL_SPECIALIZE_SHADER(CAABoxShader) +URDE_DECL_SPECIALIZE_SHADER(CWorldShadowShader) URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CColoredQuadFilter) URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilter) URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilterAlpha) @@ -233,6 +235,7 @@ CMain::BooSetter::BooSetter(boo::IGraphicsDataFactory* factory, TShader::Initialize(); TShader::Initialize(); TShader::Initialize(); + TShader::Initialize(); TMultiBlendShader::Initialize(); TMultiBlendShader::Initialize(); TMultiBlendShader::Initialize(); @@ -368,6 +371,7 @@ void CMain::Shutdown() TShader::Shutdown(); TShader::Shutdown(); TShader::Shutdown(); + TShader::Shutdown(); TMultiBlendShader::Shutdown(); TMultiBlendShader::Shutdown(); TMultiBlendShader::Shutdown(); diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp index 2146a0e9f..86e8b4834 100644 --- a/Runtime/Weapon/CPlayerGun.cpp +++ b/Runtime/Weapon/CPlayerGun.cpp @@ -2470,19 +2470,14 @@ static const CModelFlags kHandHoloFlag = {1, 0, 3, zeus::CColor(0.75f, 0.5f, 0.f void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) const { CGraphics::CProjectionState projState = CGraphics::GetProjectionState(); - CModelFlags useFlags; + CModelFlags useFlags = flags; + if (x0_lights.HasShadowLight()) + useFlags.m_extendedShader = EExtendedShader::WorldShadow; + CModelFlags beamFlags = useFlags; if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) - { - useFlags = kThermalFlags[int(x310_currentBeam)]; - } - else - { - if (x835_26_phazonBeamMorphing) - useFlags = CModelFlags(1, 0, 3, zeus::CColor::lerp(zeus::CColor::skWhite, zeus::CColor::skBlack, - x39c_phazonMorphT)); - else - useFlags = flags; - } + beamFlags = kThermalFlags[int(x310_currentBeam)]; + else if (x835_26_phazonBeamMorphing) + beamFlags.x4_color = zeus::CColor::lerp(zeus::CColor::skWhite, zeus::CColor::skBlack, x39c_phazonMorphT); const CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr); CGraphics::SetDepthRange(0.03125f, 0.125f); @@ -2525,8 +2520,8 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal ? kHandThermalFlag : kHandHoloFlag); } - DrawArm(mgr, pos, flags); - x72c_currentBeam->Draw(drawSuitArm, mgr, offsetWorldXf, useFlags, &x0_lights); + DrawArm(mgr, pos, useFlags); + x72c_currentBeam->Draw(drawSuitArm, mgr, offsetWorldXf, beamFlags, &x0_lights); x82c_shadow->DisableModelProjectedShadow(); break; case CGunMorph::EGunState::InWipeDone: @@ -2545,7 +2540,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co x82c_shadow->EnableModelProjectedShadow(offsetWorldXf, x0_lights.GetShadowLightArrIndex(), 2.15f); CGraphics::SetModelMatrix(morphXf); DrawClipCube(x6c8_hologramClipCube); - x72c_currentBeam->Draw(drawSuitArm, mgr, offsetWorldXf, useFlags, &x0_lights); + x72c_currentBeam->Draw(drawSuitArm, mgr, offsetWorldXf, beamFlags, &x0_lights); x82c_shadow->DisableModelProjectedShadow(); } else @@ -2556,7 +2551,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co x72c_currentBeam->DrawHologram(mgr, offsetWorldXf, CModelFlags(0, 0, 3, zeus::CColor::skWhite)); if (x0_lights.HasShadowLight()) x82c_shadow->EnableModelProjectedShadow(offsetWorldXf, x0_lights.GetShadowLightArrIndex(), 2.15f); - DrawArm(mgr, pos, flags); + DrawArm(mgr, pos, useFlags); x82c_shadow->DisableModelProjectedShadow(); } break; diff --git a/Runtime/World/CMorphBall.cpp b/Runtime/World/CMorphBall.cpp index 8dacf0793..8ff517959 100644 --- a/Runtime/World/CMorphBall.cpp +++ b/Runtime/World/CMorphBall.cpp @@ -1382,7 +1382,7 @@ void CMorphBall::ComputeBoostBallMovement(const CFinalInput& input, CStateManage if (x1de8_boostChargeTime >= g_tweakBall->GetBoostBallMinChargeTime()) { - if (GetBallBoostState() == EBallBoostState::Zero) + if (GetBallBoostState() == EBallBoostState::BoostAvailable) { if (GetIsInHalfPipeMode() || x1df8_27_ballCloseToCollision) { @@ -1395,7 +1395,7 @@ void CMorphBall::ComputeBoostBallMovement(const CFinalInput& input, CStateManage CancelBoosting(); } } - else if (GetBallBoostState() == EBallBoostState::One) + else if (GetBallBoostState() == EBallBoostState::BoostDisabled) { x0_player.SetTransform(zeus::lookAt(x0_player.GetTranslation(), x0_player.GetTranslation() + GetBallToWorld().basis[1])); @@ -1726,7 +1726,10 @@ void CMorphBall::Render(const CStateManager& mgr, const CActorLights* lights) co if (x1c34_boostLightFactor != 1.f) { if (lights->HasShadowLight()) + { x1c14_worldShadow->EnableModelProjectedShadow(ballToWorld, lights->GetShadowLightArrIndex(), 1.f); + flags.m_extendedShader = EExtendedShader::WorldShadow; + } x58_ballModel->Render(mgr, ballToWorld, lights, flags); x1c14_worldShadow->DisableModelProjectedShadow(); } @@ -1798,7 +1801,10 @@ void CMorphBall::Render(const CStateManager& mgr, const CActorLights* lights) co if (tmp != 1.f) { if (lights->HasShadowLight()) + { x1c14_worldShadow->EnableModelProjectedShadow(ballToWorld, lights->GetShadowLightArrIndex(), 1.f); + sflags.m_extendedShader = EExtendedShader::WorldShadow; + } x60_spiderBallGlassModel->Render(mgr, ballToWorld, x1c18_actorLights.get(), sflags); x1c14_worldShadow->DisableModelProjectedShadow(); } diff --git a/Runtime/World/CMorphBall.hpp b/Runtime/World/CMorphBall.hpp index 4a080f79a..c143b1b29 100644 --- a/Runtime/World/CMorphBall.hpp +++ b/Runtime/World/CMorphBall.hpp @@ -28,8 +28,8 @@ class CMorphBall public: enum class EBallBoostState { - Zero, - One + BoostAvailable, + BoostDisabled }; enum class ESpiderBallState @@ -40,8 +40,8 @@ public: enum class EBombJumpState { - Zero, - One + BombJumpAvailable, + BombJumpDisabled }; private: struct CSpiderBallElectricityManager @@ -167,8 +167,8 @@ private: u16 x1e34_rollSfx = 0xffff; u16 x1e36_landSfx = 0xffff; u32 x1e38_wallSparkFrameCountdown = 0; - EBallBoostState x1e3c_boostState = EBallBoostState::Zero; - EBombJumpState x1e40_bombJumpState = EBombJumpState::Zero; + EBallBoostState x1e3c_boostState = EBallBoostState::BoostAvailable; + EBombJumpState x1e40_bombJumpState = EBombJumpState::BombJumpAvailable; float x1e44_damageEffect = 0.f; float x1e48_damageEffectDecaySpeed = 0.f; float x1e4c_damageTime = 0.f; @@ -278,6 +278,7 @@ public: EBallBoostState GetBallBoostState() const { return x1e3c_boostState; } void SetBallBoostState(EBallBoostState state) { x1e3c_boostState = state; } EBombJumpState GetBombJumpState() const { return x1e40_bombJumpState; } + void SetBombJumpState(EBombJumpState state) { x1e40_bombJumpState = state; } void TakeDamage(float dam); void DrawBallShadow(const CStateManager& mgr); void DeleteBallShadow(); diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index 0d68570c9..d3a957c64 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -5395,7 +5395,7 @@ void CPlayer::Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool rese void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr) { if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && - x768_morphball->GetBombJumpState() != CMorphBall::EBombJumpState::One) + x768_morphball->GetBombJumpState() != CMorphBall::EBombJumpState::BombJumpDisabled) { zeus::CVector3f posToBall = GetTranslation() + zeus::CVector3f(0.f, 0.f, g_tweakPlayer->GetPlayerBallHalfExtent()) - pos; diff --git a/Runtime/World/CWorldLight.hpp b/Runtime/World/CWorldLight.hpp index 0ac247ad2..d5c8194a8 100644 --- a/Runtime/World/CWorldLight.hpp +++ b/Runtime/World/CWorldLight.hpp @@ -33,9 +33,9 @@ private: public: CWorldLight(const CWorldLight&) = default; CWorldLight(CInputStream& in); - ELightType GetLightType() const; - const zeus::CVector3f& GetDirection() const; - const zeus::CVector3f& GetPosition() const; + EWorldLightType GetLightType() const { return x0_type; } + const zeus::CVector3f& GetDirection() const { return x1c_direction; } + const zeus::CVector3f& GetPosition() const { return x10_position; } bool DoesCastShadows() const { return x34_castShadows; } CLight GetAsCGraphicsLight() const; diff --git a/Runtime/World/CWorldShadow.cpp b/Runtime/World/CWorldShadow.cpp index dd81914eb..5784ac949 100644 --- a/Runtime/World/CWorldShadow.cpp +++ b/Runtime/World/CWorldShadow.cpp @@ -1,31 +1,128 @@ #include "CWorldShadow.hpp" +#include "CWorld.hpp" +#include "CStateManager.hpp" +#include "Graphics/CBooRenderer.hpp" namespace urde { -CWorldShadow::CWorldShadow(u32, u32, bool) -{ -} +CWorldShadow::CWorldShadow(u32 w, u32 h, bool rgba8) +: m_shader(w, h) {} void CWorldShadow::EnableModelProjectedShadow(const zeus::CTransform& pos, s32 lightIdx, float f1) { - + zeus::CTransform texTransform = zeus::lookAt(zeus::CVector3f::skZero, x74_lightPos - x68_objPos); + zeus::CTransform posXf = pos; + posXf.origin = zeus::CVector3f::skZero; + texTransform = posXf.inverse() * texTransform; + texTransform = (texTransform * zeus::CTransform::Scale(float(M_SQRT2) * x64_objHalfExtent * f1)).inverse(); + texTransform = zeus::CTransform::Translate(0.5f, 0.f, 0.5f) * texTransform; + CBooModel::EnableShadowMaps(m_shader.GetTexture(), texTransform); } void CWorldShadow::DisableModelProjectedShadow() { - + CBooModel::DisableShadowMaps(); } void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, s32 lightIdx, - const zeus::CAABox& aabb, bool b1, bool b2) + const zeus::CAABox& aabb, bool motionBlur, bool lighten) { + if (x80_aid != aid || x84_lightIdx != lightIdx) + { + x88_blurReset = true; + x80_aid = aid; + x84_lightIdx = lightIdx; + } + if (aid != kInvalidAreaId) + { + const CGameArea* area = mgr.GetWorld()->GetAreaAlways(aid); + if (area->IsPostConstructed()) + { + const CWorldLight& light = area->GetPostConstructed()->x60_lightsA[lightIdx]; + zeus::CVector3f centerPoint = aabb.center(); + if (const CPVSAreaSet* pvs = area->GetAreaVisSet()) + { + CPVSVisSet lightSet = pvs->Get1stLightSet(lightIdx); + g_Renderer->EnablePVS(lightSet, aid); + } + else + { + CPVSVisSet visSet; + visSet.Reset(EPVSVisSetState::OutOfBounds); + g_Renderer->EnablePVS(visSet, aid); + } + zeus::CVector3f lightToPoint = centerPoint - light.GetPosition(); + x64_objHalfExtent = (aabb.max - centerPoint).magnitude(); + float distance = lightToPoint.magnitude(); + float fov = zeus::radToDeg(std::atan2(x64_objHalfExtent, distance)) * 2.f; + if (fov >= 0.00001f) + { + lightToPoint.normalize(); + x4_view = zeus::lookAt(light.GetPosition(), centerPoint, zeus::CVector3f::skDown); + x68_objPos = centerPoint; + x74_lightPos = light.GetPosition(); + CGraphics::SetViewPointMatrix(x4_view); + zeus::CFrustum frustum; + frustum.updatePlanes(x4_view, zeus::SProjPersp( + zeus::degToRad(fov), 1.f, 0.1f, distance + x64_objHalfExtent)); + g_Renderer->SetClippingPlanes(frustum); + g_Renderer->SetPerspective(fov, m_shader.GetWidth(), m_shader.GetHeight(), 0.1f, 1000.f); + SViewport backupVp = g_Viewport; + zeus::CVector2f backupDepthRange = CGraphics::g_CachedDepthRange; + m_shader.bindRenderTarget(); + g_Renderer->SetViewport(0, 0, m_shader.GetWidth(), m_shader.GetHeight()); + CGraphics::SetDepthRange(0.f, 1.f); + + x34_model = zeus::lookAt(centerPoint - zeus::CVector3f(0.f, 0.f, 0.1f), light.GetPosition()); + CGraphics::SetModelMatrix(x34_model); + + m_shadowViewProj = CGraphics::GetPerspectiveProjectionMatrix(false) * + CGraphics::g_CameraMatrix.toMatrix4f(); + + float extent = float(M_SQRT2) * x64_objHalfExtent; + /* Depth test and write */ + /* Color white 100% alpha */ + m_shader.drawBase(extent); + + CGraphics::SetModelMatrix(zeus::CTransform::Identity()); + CBooModel::SetDrawingOccluders(true); + g_Renderer->PrepareDynamicLights({}); + g_Renderer->DrawUnsortedGeometry(aid, 0, 0); + CBooModel::SetDrawingOccluders(false); + + if (lighten) + { + CGraphics::SetModelMatrix(x34_model); + /* No depth test or write */ + /* Color white 25% alpha */ + m_shader.lightenShadow(); + } + + if (motionBlur && !x88_blurReset) + { + /* No depth test or write */ + /* Color white 85% alpha */ + /* Draw in shadow texture */ + m_shader.blendPreviousShadow(); + } + + x88_blurReset = false; + + m_shader.resolveTexture(); + CBooRenderer::BindMainDrawTarget(); + + g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height); + CGraphics::SetDepthRange(backupDepthRange[0], backupDepthRange[1]); + } + } + } } void CWorldShadow::ResetBlur() { - + x88_blurReset = true; } } diff --git a/Runtime/World/CWorldShadow.hpp b/Runtime/World/CWorldShadow.hpp index 4be8827a3..e1e72c6bd 100644 --- a/Runtime/World/CWorldShadow.hpp +++ b/Runtime/World/CWorldShadow.hpp @@ -3,6 +3,7 @@ #include "RetroTypes.hpp" #include "zeus/CAABox.hpp" +#include "Graphics/Shaders/CWorldShadowShader.hpp" namespace urde { @@ -10,12 +11,22 @@ class CStateManager; class CWorldShadow { + CWorldShadowShader m_shader; + zeus::CTransform x4_view; + zeus::CTransform x34_model; + float x64_objHalfExtent = 1.f; + zeus::CVector3f x68_objPos = {0.f, 1.f, 0.f}; + zeus::CVector3f x74_lightPos; + TAreaId x80_aid; + s32 x84_lightIdx = -1; + bool x88_blurReset = true; + zeus::CMatrix4f m_shadowViewProj; public: - CWorldShadow(u32, u32, bool); + CWorldShadow(u32 w, u32 h, bool rgba8); void EnableModelProjectedShadow(const zeus::CTransform& pos, s32 lightIdx, float f1); void DisableModelProjectedShadow(); void BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, s32 lightIdx, - const zeus::CAABox& aabb, bool b1, bool b2); + const zeus::CAABox& aabb, bool motionBlur, bool lighten); void ResetBlur(); }; diff --git a/hecl b/hecl index 0270b2c25..6f86b576e 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 0270b2c253785221367af1ca414fca52f3867105 +Subproject commit 6f86b576ed28e44740c65aaeb330b58ef6b06b13 diff --git a/specter b/specter index 6a89d8c22..02e557c7d 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 6a89d8c22b9dfc83b93baee1344096fca7008af9 +Subproject commit 02e557c7df6304e1f6143ef2f6ecae0fb152c6e1