mirror of https://github.com/AxioDL/metaforce.git
Support for rendering dynamic cubemaps
This commit is contained in:
parent
486c925a45
commit
410d7896f7
|
@ -603,6 +603,25 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const {
|
|||
return frustum;
|
||||
}
|
||||
|
||||
zeus::CFrustum CStateManager::SetupViewForCubeFaceDraw(const zeus::CVector3f& pos, int face) const {
|
||||
zeus::CTransform mainCamXf = x870_cameraManager->GetCurrentCameraTransform(*this);
|
||||
zeus::CTransform camXf = zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], pos);
|
||||
g_Renderer->SetWorldViewpoint(camXf);
|
||||
CBooModel::SetNewPlayerPositionAndTime(x84c_player->GetTranslation());
|
||||
constexpr float width = CUBEMAP_RES;
|
||||
g_Renderer->SetViewport(0, 0, width, width);
|
||||
CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR);
|
||||
constexpr float fov = zeus::degToRad(90.f);
|
||||
g_Renderer->SetPerspective(zeus::radToDeg(fov), width, width, 0.2f, 750.f);
|
||||
zeus::CFrustum frustum;
|
||||
zeus::CProjection proj;
|
||||
proj.setPersp(zeus::SProjPersp{fov, 1.f, 0.2f, 750.f});
|
||||
frustum.updatePlanes(camXf, proj);
|
||||
g_Renderer->SetClippingPlanes(frustum);
|
||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||
return frustum;
|
||||
}
|
||||
|
||||
void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport,
|
||||
const zeus::CTransform& backupViewMatrix) const {
|
||||
g_Renderer->SetViewport(backupViewport.x0_left, backupViewport.x4_top, backupViewport.x8_width,
|
||||
|
@ -621,14 +640,17 @@ void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport,
|
|||
void CStateManager::DrawWorld() const {
|
||||
CTimeProvider timeProvider(xf14_curTimeMod900);
|
||||
SViewport backupViewport = g_Viewport;
|
||||
zeus::CFrustum frustum = SetupViewForDraw(g_Viewport);
|
||||
zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix;
|
||||
|
||||
/* Area camera is in (not necessarily player) */
|
||||
TAreaId visAreaId = GetVisAreaId();
|
||||
|
||||
x850_world->TouchSky();
|
||||
|
||||
DrawWorldCubeFaces();
|
||||
|
||||
zeus::CFrustum frustum = SetupViewForDraw(g_Viewport);
|
||||
zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix;
|
||||
|
||||
int areaCount = 0;
|
||||
const CGameArea* areaArr[10];
|
||||
for (const CGameArea& area : *x850_world) {
|
||||
|
@ -851,6 +873,107 @@ void CStateManager::DrawWorld() const {
|
|||
DrawAdditionalFilters();
|
||||
}
|
||||
|
||||
void CStateManager::DrawActorCubeFaces(CActor& actor, int& cubeInst) const {
|
||||
if (!actor.m_reflectionCube ||
|
||||
(!TCastToPtr<CPlayer>(actor) && (!actor.GetActive() || !actor.IsDrawEnabled() || actor.xe4_30_outOfFrustum)))
|
||||
return;
|
||||
|
||||
TAreaId visAreaId = actor.GetAreaIdAlways();
|
||||
SViewport backupVp = g_Viewport;
|
||||
|
||||
int areaCount = 0;
|
||||
const CGameArea* areaArr[10];
|
||||
for (const CGameArea& area : *x850_world) {
|
||||
if (areaCount == 10)
|
||||
break;
|
||||
CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded;
|
||||
if (area.IsPostConstructed())
|
||||
occState = area.GetOcclusionState();
|
||||
if (occState == CGameArea::EOcclusionState::Visible)
|
||||
areaArr[areaCount++] = &area;
|
||||
}
|
||||
|
||||
for (int f = 0; f < 6; ++f) {
|
||||
CGraphics::g_BooMainCommandQueue->setRenderTarget(actor.m_reflectionCube, f);
|
||||
SetupViewForCubeFaceDraw(actor.GetRenderBounds().center(), f);
|
||||
CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
|
||||
std::sort(std::begin(areaArr), std::begin(areaArr) + areaCount,
|
||||
[visAreaId](const CGameArea* a, const CGameArea* b) {
|
||||
if (a->x4_selfIdx == b->x4_selfIdx)
|
||||
return false;
|
||||
if (visAreaId == a->x4_selfIdx)
|
||||
return false;
|
||||
if (visAreaId == b->x4_selfIdx)
|
||||
return true;
|
||||
return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) >
|
||||
CGraphics::g_ViewPoint.dot(b->GetAABB().center());
|
||||
});
|
||||
|
||||
int pvsCount = 0;
|
||||
CPVSVisSet pvsArr[10];
|
||||
for (const CGameArea** area = areaArr; area != areaArr + areaCount; ++area) {
|
||||
const CGameArea* areaPtr = *area;
|
||||
CPVSVisSet& pvsSet = pvsArr[pvsCount++];
|
||||
pvsSet.Reset(EPVSVisSetState::OutOfBounds);
|
||||
GetVisSetForArea(areaPtr->x4_selfIdx, visAreaId, pvsSet);
|
||||
}
|
||||
|
||||
for (int i = areaCount - 1; i >= 0; --i) {
|
||||
const CGameArea& area = *areaArr[i];
|
||||
SetupFogForArea(area);
|
||||
g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx);
|
||||
g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel);
|
||||
g_Renderer->UpdateAreaUniforms(area.x4_selfIdx, false, true, cubeInst * 6 + f);
|
||||
g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, 0x2, 0x0);
|
||||
}
|
||||
|
||||
if (!SetupFogForDraw())
|
||||
g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::skBlack);
|
||||
|
||||
x850_world->DrawSky(zeus::CTransform::Translate(CGraphics::g_ViewPoint));
|
||||
|
||||
for (int i = 0; i < areaCount; ++i) {
|
||||
const CGameArea& area = *areaArr[i];
|
||||
CPVSVisSet& pvs = pvsArr[i];
|
||||
SetupFogForArea(area);
|
||||
g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel);
|
||||
g_Renderer->EnablePVS(pvs, area.x4_selfIdx);
|
||||
g_Renderer->DrawSortedGeometry(area.x4_selfIdx, 0x2, 0x0);
|
||||
}
|
||||
}
|
||||
|
||||
CGraphics::g_BooMainCommandQueue->generateMipmaps(actor.m_reflectionCube);
|
||||
|
||||
CBooRenderer::BindMainDrawTarget();
|
||||
g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
|
||||
|
||||
++cubeInst;
|
||||
}
|
||||
|
||||
void CStateManager::DrawWorldCubeFaces() const {
|
||||
int areaCount = 0;
|
||||
const CGameArea* areaArr[10];
|
||||
for (const CGameArea& area : *x850_world) {
|
||||
if (areaCount == 10)
|
||||
break;
|
||||
CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded;
|
||||
if (area.IsPostConstructed())
|
||||
occState = area.GetOcclusionState();
|
||||
if (occState == CGameArea::EOcclusionState::Visible)
|
||||
areaArr[areaCount++] = &area;
|
||||
}
|
||||
|
||||
for (int ai = 0; ai < areaCount; ++ai) {
|
||||
const CGameArea& area = *areaArr[ai];
|
||||
int cubeInst = 0;
|
||||
for (CEntity* ent : *area.GetAreaObjects()) {
|
||||
if (TCastToPtr<CActor> actor = ent)
|
||||
DrawActorCubeFaces(*actor, cubeInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CStateManager::SetupFogForArea(TAreaId area) const {
|
||||
if (area == kInvalidAreaId)
|
||||
area = x8cc_nextAreaId;
|
||||
|
|
|
@ -245,8 +245,11 @@ public:
|
|||
void DrawAdditionalFilters() const;
|
||||
zeus::CFrustum SetupDrawFrustum(const SViewport& vp) const;
|
||||
zeus::CFrustum SetupViewForDraw(const SViewport& vp) const;
|
||||
zeus::CFrustum SetupViewForCubeFaceDraw(const zeus::CVector3f& pos, int face) const;
|
||||
void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const;
|
||||
void DrawWorld() const;
|
||||
void DrawActorCubeFaces(CActor& actor, int& cubeInst) const;
|
||||
void DrawWorldCubeFaces() const;
|
||||
void SetupFogForArea(TAreaId area) const;
|
||||
void SetupFogForAreaNonCurrent(TAreaId area) const;
|
||||
void SetupFogForArea(const CGameArea& area) const;
|
||||
|
|
|
@ -705,7 +705,7 @@ void CBooRenderer::EnablePVS(const CPVSVisSet& set, u32 areaIdx) {
|
|||
|
||||
void CBooRenderer::DisablePVS() { xc8_pvs = rstl::nullopt; }
|
||||
|
||||
void CBooRenderer::UpdateAreaUniforms(int areaIdx, bool shadowRender, bool activateLights) {
|
||||
void CBooRenderer::UpdateAreaUniforms(int areaIdx, bool shadowRender, bool activateLights, int cubeFace) {
|
||||
SetupRendererStates();
|
||||
|
||||
CModelFlags flags;
|
||||
|
@ -716,7 +716,7 @@ void CBooRenderer::UpdateAreaUniforms(int areaIdx, bool shadowRender, bool activ
|
|||
bufIdx = 1;
|
||||
} else {
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
bufIdx = 0;
|
||||
bufIdx = cubeFace == -1 ? 0 : 2 + cubeFace;
|
||||
}
|
||||
|
||||
for (CAreaListItem& item : x1c_areaListItems) {
|
||||
|
@ -724,7 +724,7 @@ void CBooRenderer::UpdateAreaUniforms(int areaIdx, bool shadowRender, bool activ
|
|||
continue;
|
||||
|
||||
item.m_shaderSet->m_geomLayout->Update(flags, nullptr, nullptr, &item.m_shaderSet->m_matSet,
|
||||
item.m_shaderSet->m_geomLayout->m_sharedBuffer[bufIdx], nullptr);
|
||||
item.m_shaderSet->m_geomLayout->GetSharedBuffer(bufIdx), nullptr);
|
||||
|
||||
for (auto it = item.x10_models.begin(); it != item.x10_models.end(); ++it) {
|
||||
CBooModel* model = *it;
|
||||
|
|
|
@ -201,7 +201,7 @@ public:
|
|||
const SShader* shaderSet);
|
||||
void EnablePVS(const CPVSVisSet&, u32);
|
||||
void DisablePVS();
|
||||
void UpdateAreaUniforms(int areaIdx, bool shadowRender = false, bool activateLights = true);
|
||||
void UpdateAreaUniforms(int areaIdx, bool shadowRender = false, bool activateLights = true, int cubeFace = -1);
|
||||
void RemoveStaticGeometry(const std::vector<CMetroidModelInstance>*);
|
||||
void DrawAreaGeometry(int areaIdx, int mask, int targetMask);
|
||||
void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask, bool shadowRender = false);
|
||||
|
|
|
@ -31,6 +31,33 @@ bool CGraphics::g_IsGXModelMatrixIdentity = true;
|
|||
SViewport g_Viewport = {0, 0, 640, 480, 640 / 2.f, 480 / 2.f};
|
||||
u32 CGraphics::g_FrameCounter = 0;
|
||||
|
||||
const zeus::CMatrix3f CGraphics::skCubeBasisMats[] = {
|
||||
/* Right */
|
||||
{0.f, 1.f, 0.f,
|
||||
1.f, 0.f, 0.f,
|
||||
0.f, 0.f, -1.f},
|
||||
/* Left */
|
||||
{0.f, -1.f, 0.f,
|
||||
-1.f, 0.f, 0.f,
|
||||
0.f, 0.f, -1.f},
|
||||
/* Up */
|
||||
{1.f, 0.f, 0.f,
|
||||
0.f, 0.f, -1.f,
|
||||
0.f, 1.f, 0.f},
|
||||
/* Down */
|
||||
{1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f,
|
||||
0.f, -1.f, 0.f},
|
||||
/* Back */
|
||||
{1.f, 0.f, 0.f,
|
||||
0.f, -1.f, 0.f,
|
||||
0.f, 0.f, -1.f},
|
||||
/* Forward */
|
||||
{-1.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f,
|
||||
0.f, 0.f, -1.f},
|
||||
};
|
||||
|
||||
void CGraphics::DisableAllLights() {
|
||||
g_NumLightsActive = 0;
|
||||
g_LightActive = ERglLightBits::None;
|
||||
|
|
|
@ -176,6 +176,8 @@ enum class ETexelFormat {
|
|||
#define DEPTH_SCREEN_ACTORS (1.f / 64.f)
|
||||
#define DEPTH_HUD (1.f / 512.f)
|
||||
#define DEPTH_NEAR 0.f
|
||||
#define CUBEMAP_RES 256
|
||||
#define CUBEMAP_MIPS 6
|
||||
|
||||
class CGraphics {
|
||||
public:
|
||||
|
@ -268,6 +270,8 @@ public:
|
|||
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
|
||||
static boo::ObjToken<boo::ITextureR> g_SpareTexture;
|
||||
|
||||
static const zeus::CMatrix3f skCubeBasisMats[6];
|
||||
|
||||
static void InitializeBoo(boo::IGraphicsDataFactory* factory, boo::IGraphicsCommandQueue* cc,
|
||||
const boo::ObjToken<boo::ITextureR>& spareTex) {
|
||||
g_BooPlatform = factory->platform();
|
||||
|
|
|
@ -77,7 +77,7 @@ struct CBooSurface {
|
|||
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
|
||||
|
||||
struct GeometryUniformLayout {
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_sharedBuffer[2];
|
||||
mutable std::vector<boo::ObjToken<boo::IGraphicsBufferD>> m_sharedBuffer;
|
||||
size_t m_geomBufferSize = 0;
|
||||
size_t m_skinBankCount = 0;
|
||||
size_t m_weightVecCount = 0;
|
||||
|
@ -92,6 +92,9 @@ struct GeometryUniformLayout {
|
|||
void Update(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose,
|
||||
const MaterialSet* matSet, const boo::ObjToken<boo::IGraphicsBufferD>& buf,
|
||||
const CBooModel* parent) const;
|
||||
|
||||
void ReserveSharedBuffers(boo::IGraphicsDataFactory::Context& ctx, int size);
|
||||
boo::ObjToken<boo::IGraphicsBufferD> GetSharedBuffer(int idx) const;
|
||||
};
|
||||
|
||||
struct SShader {
|
||||
|
@ -167,6 +170,7 @@ private:
|
|||
|
||||
boo::ObjToken<boo::ITexture> m_lastDrawnShadowMap;
|
||||
boo::ObjToken<boo::ITexture> m_lastDrawnOneTexture;
|
||||
boo::ObjToken<boo::ITextureCubeR> m_lastDrawnReflectionCube;
|
||||
|
||||
ModelInstance* PushNewModelInstance(int sharedLayoutBuf = -1);
|
||||
void DrawAlphaSurfaces(const CModelFlags& flags) const;
|
||||
|
@ -240,10 +244,13 @@ public:
|
|||
static boo::ObjToken<boo::ITexture> g_disintegrateTexture;
|
||||
static void SetDisintegrateTexture(const boo::ObjToken<boo::ITexture>& map) { g_disintegrateTexture = map; }
|
||||
|
||||
static boo::ObjToken<boo::ITextureCubeR> g_reflectionCube;
|
||||
static void SetReflectionCube(const boo::ObjToken<boo::ITextureCubeR>& map) { g_reflectionCube = map; }
|
||||
|
||||
static void SetDummyTextures(bool b) { g_DummyTextures = b; }
|
||||
static void SetRenderModelBlack(bool b) { g_RenderModelBlack = b; }
|
||||
|
||||
static void AssertAllFreed();
|
||||
static void Shutdown();
|
||||
|
||||
const zeus::CAABox& GetAABB() const { return x20_aabb; }
|
||||
};
|
||||
|
|
|
@ -18,7 +18,12 @@ bool CBooModel::g_DrawingOccluders = false;
|
|||
|
||||
static CBooModel* g_FirstModel = nullptr;
|
||||
|
||||
void CBooModel::AssertAllFreed() { assert(g_FirstModel == nullptr && "Dangling CBooModels detected"); }
|
||||
void CBooModel::Shutdown() {
|
||||
g_shadowMap.reset();
|
||||
g_disintegrateTexture.reset();
|
||||
g_reflectionCube.reset();
|
||||
assert(g_FirstModel == nullptr && "Dangling CBooModels detected");
|
||||
}
|
||||
|
||||
void CBooModel::ClearModelUniformCounters() {
|
||||
for (CBooModel* model = g_FirstModel; model; model = model->m_next)
|
||||
|
@ -123,6 +128,7 @@ void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurfa
|
|||
boo::ObjToken<boo::ITexture> CBooModel::g_shadowMap;
|
||||
zeus::CTransform CBooModel::g_shadowTexXf;
|
||||
boo::ObjToken<boo::ITexture> CBooModel::g_disintegrateTexture;
|
||||
boo::ObjToken<boo::ITextureCubeR> CBooModel::g_reflectionCube;
|
||||
|
||||
void CBooModel::EnableShadowMaps(const boo::ObjToken<boo::ITexture>& map, const zeus::CTransform& texXf) {
|
||||
g_shadowMap = map;
|
||||
|
@ -248,7 +254,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
/* Build geometry uniform buffer if shared not available */
|
||||
boo::ObjToken<boo::IGraphicsBufferD> geomUniformBuf;
|
||||
if (sharedLayoutBuf >= 0) {
|
||||
geomUniformBuf = m_geomLayout->m_sharedBuffer[sharedLayoutBuf];
|
||||
geomUniformBuf = m_geomLayout->GetSharedBuffer(sharedLayoutBuf);
|
||||
} else {
|
||||
geomUniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomLayout->m_geomBufferSize, 1);
|
||||
newInst.m_geomUniformBuffer = geomUniformBuf;
|
||||
|
@ -356,7 +362,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
texs[8] = g_Renderer->m_ballShadowId.get();
|
||||
texs[9] = g_Renderer->x220_sphereRamp.get();
|
||||
texs[10] = g_Renderer->m_ballFade.get();
|
||||
} else if (idx == EExtendedShader::WorldShadow) {
|
||||
} else if (idx == EExtendedShader::WorldShadow || idx == EExtendedShader::LightingCubeReflectionWorldShadow) {
|
||||
if (g_shadowMap)
|
||||
texs[8] = g_shadowMap;
|
||||
else
|
||||
|
@ -366,6 +372,12 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
texs[8] = g_disintegrateTexture;
|
||||
else
|
||||
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||
} else if (idx == EExtendedShader::LightingCubeReflection ||
|
||||
idx == EExtendedShader::LightingCubeReflectionWorldShadow) {
|
||||
if (m_lastDrawnReflectionCube)
|
||||
texs[11] = m_lastDrawnReflectionCube.get();
|
||||
else
|
||||
texs[11] = g_Renderer->x220_sphereRamp.get();
|
||||
}
|
||||
extendeds.push_back(ctx.newShaderDataBinding(pipeline, newInst.GetBooVBO(*this, ctx), nullptr,
|
||||
m_staticIbo.get(), 4, bufs, stages, thisOffs, thisSizes, 12, texs,
|
||||
|
@ -778,7 +790,8 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet
|
|||
postMtxOut[1].y() = 0.5f;
|
||||
postMtxOut[3].x() = 0.5f;
|
||||
postMtxOut[3].y() = 0.5f;
|
||||
} else if (flags.m_extendedShader == EExtendedShader::WorldShadow) {
|
||||
} else if (flags.m_extendedShader == EExtendedShader::WorldShadow ||
|
||||
flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) {
|
||||
/* Special matrix for mapping world shadow */
|
||||
specialMtxOut.emplace();
|
||||
|
||||
|
@ -891,6 +904,31 @@ void GeometryUniformLayout::Update(const CModelFlags& flags, const CSkinRules* c
|
|||
buf->unmap();
|
||||
}
|
||||
|
||||
void GeometryUniformLayout::ReserveSharedBuffers(boo::IGraphicsDataFactory::Context& ctx, int size) {
|
||||
if (m_sharedBuffer.size() < size)
|
||||
m_sharedBuffer.resize(size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
auto& buf = m_sharedBuffer[i];
|
||||
if (!buf)
|
||||
buf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomBufferSize, 1);
|
||||
}
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IGraphicsBufferD> GeometryUniformLayout::GetSharedBuffer(int idx) const {
|
||||
if (idx >= m_sharedBuffer.size())
|
||||
m_sharedBuffer.resize(idx + 1);
|
||||
|
||||
auto& buf = m_sharedBuffer[idx];
|
||||
if (!buf) {
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
buf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomBufferSize, 1);
|
||||
return true;
|
||||
} BooTrace);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr,
|
||||
const CPoseAsTransforms* pose,
|
||||
int sharedLayoutBuf) const {
|
||||
|
@ -898,7 +936,9 @@ boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFl
|
|||
return {};
|
||||
|
||||
/* Invalidate instances if new shadow being drawn */
|
||||
if (flags.m_extendedShader == EExtendedShader::WorldShadow && m_lastDrawnShadowMap != g_shadowMap) {
|
||||
if ((flags.m_extendedShader == EExtendedShader::WorldShadow ||
|
||||
flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) &&
|
||||
m_lastDrawnShadowMap != g_shadowMap) {
|
||||
const_cast<CBooModel*>(this)->m_lastDrawnShadowMap = g_shadowMap;
|
||||
const_cast<CBooModel*>(this)->m_instances.clear();
|
||||
}
|
||||
|
@ -909,6 +949,14 @@ boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFl
|
|||
const_cast<CBooModel*>(this)->m_instances.clear();
|
||||
}
|
||||
|
||||
/* Invalidate instances if new reflection cube being drawn */
|
||||
if ((flags.m_extendedShader == EExtendedShader::LightingCubeReflection ||
|
||||
flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) &&
|
||||
m_lastDrawnReflectionCube != g_reflectionCube) {
|
||||
const_cast<CBooModel*>(this)->m_lastDrawnReflectionCube = g_reflectionCube;
|
||||
const_cast<CBooModel*>(this)->m_instances.clear();
|
||||
}
|
||||
|
||||
const ModelInstance* inst;
|
||||
if (sharedLayoutBuf >= 0) {
|
||||
if (m_instances.size() <= sharedLayoutBuf) {
|
||||
|
|
|
@ -145,7 +145,13 @@ static hecl::Backend::ExtensionSlot g_ExtensionSlots[] = {
|
|||
false, false, true, false, false, false, true},
|
||||
/* Normal lit shading with alpha */
|
||||
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface}};
|
||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface},
|
||||
/* Normal lit shading with cube reflection */
|
||||
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
||||
/* Normal lit shading with cube reflection and world shadow */
|
||||
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}};
|
||||
|
||||
static const char* ShaderMacros[] = {
|
||||
"URDE_LIGHTING",
|
||||
|
@ -172,6 +178,8 @@ static const char* ShaderMacros[] = {
|
|||
"URDE_LIGHTING",
|
||||
"URDE_THERMAL_COLD",
|
||||
"URDE_LIGHTING",
|
||||
"URDE_LIGHTING_CUBE_REFLECTION",
|
||||
"URDE_LIGHTING_CUBE_REFLECTION_SHADOW",
|
||||
};
|
||||
|
||||
void CModelShaders::Initialize() {
|
||||
|
|
|
@ -38,6 +38,8 @@ enum EExtendedShader : uint8_t {
|
|||
ForcedAdditiveNoZWriteDepthGreater,
|
||||
ThermalCold,
|
||||
LightingAlphaWrite,
|
||||
LightingCubeReflection,
|
||||
LightingCubeReflectionWorldShadow,
|
||||
MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -864,9 +864,9 @@ void CMain::Shutdown() {
|
|||
CFluidPlaneShader::Shutdown();
|
||||
CFluidPlaneManager::RippleMapTex.reset();
|
||||
CNESShader::Shutdown();
|
||||
CBooModel::Shutdown();
|
||||
CGraphics::ShutdownBoo();
|
||||
ShutdownDiscord();
|
||||
CBooModel::AssertAllFreed();
|
||||
}
|
||||
|
||||
boo::IWindow* CMain::GetMainWindow() const { return m_mainWindow; }
|
||||
|
|
|
@ -2085,7 +2085,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co
|
|||
CGraphics::CProjectionState projState = CGraphics::GetProjectionState();
|
||||
CModelFlags useFlags = flags;
|
||||
if (x0_lights.HasShadowLight())
|
||||
useFlags.m_extendedShader = EExtendedShader::WorldShadow;
|
||||
useFlags.m_extendedShader = EExtendedShader::LightingCubeReflectionWorldShadow;
|
||||
CModelFlags beamFlags = useFlags;
|
||||
if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal)
|
||||
beamFlags = kThermalFlags[int(x310_currentBeam)];
|
||||
|
|
|
@ -431,6 +431,13 @@ void CActor::_CreateShadow() {
|
|||
x94_simpleShadow.reset(new CSimpleShadow(1.f, 1.f, 20.f, 0.05f));
|
||||
}
|
||||
|
||||
void CActor::_CreateReflectionCube() {
|
||||
CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
m_reflectionCube = ctx.newCubeRenderTexture(CUBEMAP_RES, CUBEMAP_MIPS);
|
||||
return true;
|
||||
} BooTrace);
|
||||
}
|
||||
|
||||
void CActor::SetCallTouch(bool callTouch) { xe5_28_callTouch = callTouch; }
|
||||
|
||||
bool CActor::GetCallTouch() const { return xe5_28_callTouch; }
|
||||
|
|
|
@ -76,7 +76,11 @@ protected:
|
|||
};
|
||||
u32 dummy = 0;
|
||||
};
|
||||
|
||||
boo::ObjToken<boo::ITextureCubeR> m_reflectionCube;
|
||||
|
||||
void _CreateShadow();
|
||||
void _CreateReflectionCube();
|
||||
void UpdateSfxEmitters();
|
||||
void DrawTouchBounds() const;
|
||||
void RenderInternal(const CStateManager& mgr) const;
|
||||
|
|
|
@ -1033,12 +1033,10 @@ void CGameArea::FillInStaticGeometry(bool textures) {
|
|||
matSet.InitializeLayout(nullptr);
|
||||
++secIt;
|
||||
}
|
||||
|
||||
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
/* Shared geometry uniform buffer - one for normal render, one for shadow render */
|
||||
for (int i = 0; i < 2; ++i)
|
||||
matSet.m_geomLayout->m_sharedBuffer[i] =
|
||||
ctx.newDynamicBuffer(boo::BufferUse::Uniform, matSet.m_geomLayout->m_geomBufferSize, 1);
|
||||
/* Reserve extra buffers for 16 cubemaps and shadow rendering */
|
||||
matSet.m_geomLayout->ReserveSharedBuffers(ctx, 98);
|
||||
|
||||
/* Models */
|
||||
for (CMetroidModelInstance& inst : x12c_postConstructed->x4c_insts) {
|
||||
|
|
|
@ -1418,6 +1418,7 @@ void CMorphBall::Render(const CStateManager& mgr, const CActorLights* lights) co
|
|||
if (dying) {
|
||||
zeus::CColor modColor(0.f, zeus::clamp(0.f, 1.f - x0_player.x9f4_deathTime / 0.2f * 6.f, 1.f));
|
||||
CModelFlags flags(7, u8(x5c_ballModelShader), 1, modColor);
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x58_ballModel->Render(mgr, ballToWorld, nullptr, flags);
|
||||
}
|
||||
|
||||
|
@ -1426,13 +1427,15 @@ void CMorphBall::Render(const CStateManager& mgr, const CActorLights* lights) co
|
|||
if (x1e44_damageEffect > 0.f)
|
||||
flags = CModelFlags(1, 0, 3, zeus::CColor(1.f, 1.f - x1e44_damageEffect, 1.f - x1e44_damageEffect, 1.f));
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
|
||||
if (x1c1c_rainSplashGen && x1c1c_rainSplashGen->IsRaining())
|
||||
CSkinnedModel::SetPointGeneratorFunc(x1c1c_rainSplashGen.get(), PointGenerator);
|
||||
|
||||
if (x1c34_boostLightFactor != 1.f) {
|
||||
if (lights->HasShadowLight()) {
|
||||
x1c14_worldShadow->EnableModelProjectedShadow(ballToWorld, lights->GetShadowLightArrIndex(), 1.f);
|
||||
flags.m_extendedShader = EExtendedShader::WorldShadow;
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflectionWorldShadow;
|
||||
}
|
||||
x58_ballModel->Render(mgr, ballToWorld, lights, flags);
|
||||
x1c14_worldShadow->DisableModelProjectedShadow();
|
||||
|
@ -1493,10 +1496,11 @@ void CMorphBall::Render(const CStateManager& mgr, const CActorLights* lights) co
|
|||
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::SpiderBall) && x60_spiderBallGlassModel) {
|
||||
float tmp = std::max(x1c38_spiderLightFactor, x1c34_boostLightFactor);
|
||||
CModelFlags sflags(0, u8(x64_spiderBallGlassModelShader), 3, zeus::skWhite);
|
||||
sflags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
if (tmp != 1.f) {
|
||||
if (lights->HasShadowLight()) {
|
||||
x1c14_worldShadow->EnableModelProjectedShadow(ballToWorld, lights->GetShadowLightArrIndex(), 1.f);
|
||||
sflags.m_extendedShader = EExtendedShader::WorldShadow;
|
||||
sflags.m_extendedShader = EExtendedShader::LightingCubeReflectionWorldShadow;
|
||||
}
|
||||
x60_spiderBallGlassModel->Render(mgr, ballToWorld, x1c18_actorLights.get(), sflags);
|
||||
x1c14_worldShadow->DisableModelProjectedShadow();
|
||||
|
|
|
@ -118,6 +118,8 @@ CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox&
|
|||
x64_modelData->SetScale(playerScale);
|
||||
x7f0_ballTransitionBeamModel->SetScale(playerScale);
|
||||
LoadAnimationTokens();
|
||||
|
||||
_CreateReflectionCube();
|
||||
}
|
||||
|
||||
void CPlayer::InitializeBallTransition() {
|
||||
|
@ -1141,7 +1143,9 @@ void CPlayer::RenderGun(const CStateManager& mgr, const zeus::CVector3f& pos) co
|
|||
if ((mgr.GetCameraManager()->IsInFirstPersonCamera() && x2f4_cameraState == EPlayerCameraState::FirstPerson) ||
|
||||
(x2f8_morphBallState == EPlayerMorphBallState::Morphing &&
|
||||
x498_gunHolsterState == EGunHolsterState::Holstering)) {
|
||||
CBooModel::SetReflectionCube(m_reflectionCube);
|
||||
CModelFlags flags(5, 0, 3, zeus::CColor(1.f, x494_gunAlpha));
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x490_gun->Render(mgr, pos, flags);
|
||||
}
|
||||
}
|
||||
|
@ -1152,6 +1156,7 @@ void CPlayer::Render(const CStateManager& mgr) const {
|
|||
if (TCastToConstPtr<CCinematicCamera> cam = mgr.GetCameraManager()->GetCurrentCamera(mgr))
|
||||
doRender = (x2f8_morphBallState == EPlayerMorphBallState::Morphed && cam->GetFlags() & 0x40);
|
||||
if (x2f4_cameraState != EPlayerCameraState::FirstPerson && doRender) {
|
||||
CBooModel::SetReflectionCube(m_reflectionCube);
|
||||
bool doTransitionRender = false;
|
||||
bool doBallRender = false;
|
||||
switch (x2f8_morphBallState) {
|
||||
|
@ -1161,6 +1166,7 @@ void CPlayer::Render(const CStateManager& mgr) const {
|
|||
if (HasTransitionBeamModel()) {
|
||||
x7f0_ballTransitionBeamModel->Touch(mgr, 0);
|
||||
CModelFlags flags(0, 0, 3, zeus::skWhite);
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x7f0_ballTransitionBeamModel->Render(mgr, x7f4_gunWorldXf, x90_actorLights.get(), flags);
|
||||
}
|
||||
break;
|
||||
|
@ -1184,6 +1190,7 @@ void CPlayer::Render(const CStateManager& mgr) const {
|
|||
CPhysicsActor::Render(mgr);
|
||||
if (HasTransitionBeamModel()) {
|
||||
CModelFlags flags(5, 0, 3, zeus::CColor(1.f, x588_alpha));
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x7f0_ballTransitionBeamModel->Render(CModelData::EWhichModel::Normal, x7f4_gunWorldXf, x90_actorLights.get(),
|
||||
flags);
|
||||
}
|
||||
|
@ -1206,10 +1213,12 @@ void CPlayer::Render(const CStateManager& mgr) const {
|
|||
if (alpha != 0.f) {
|
||||
CModelData& data = *x730_transitionModels[i];
|
||||
CModelFlags flags(5, 0, 3, zeus::CColor(1.f, alpha));
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
data.Render(CModelData::GetRenderingModel(mgr), *x658_transitionModelXfs.GetEntry(ni), x90_actorLights.get(),
|
||||
flags);
|
||||
if (HasTransitionBeamModel()) {
|
||||
CModelFlags flags(5, 0, 3, zeus::CColor(1.f, alpha));
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x7f0_ballTransitionBeamModel->Render(CModelData::EWhichModel::Normal, *x594_transisionBeamXfs.GetEntry(ni),
|
||||
x90_actorLights.get(), flags);
|
||||
}
|
||||
|
@ -1229,6 +1238,7 @@ void CPlayer::Render(const CStateManager& mgr) const {
|
|||
if (morphFactor > ballAlphaStart) {
|
||||
CModelFlags flags(5, u8(x768_morphball->GetMorphballModelShader()), 3,
|
||||
zeus::CColor(1.f, ballAlphaMag * (morphFactor - ballAlphaStart)));
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x768_morphball->GetMorphballModelData().Render(mgr, x768_morphball->GetBallToWorld(), x90_actorLights.get(),
|
||||
flags);
|
||||
}
|
||||
|
@ -1252,6 +1262,7 @@ void CPlayer::Render(const CStateManager& mgr) const {
|
|||
ballAlpha *= 0.5f;
|
||||
if (ballAlpha > 0.f) {
|
||||
CModelFlags flags(7, 0, 3, zeus::CColor(1.f, ballAlpha));
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
x768_morphball->GetMorphballModelData().Render(
|
||||
mgr,
|
||||
x768_morphball->GetBallToWorld() * zeus::CTransform::RotateZ(theta) * zeus::CTransform::Scale(scale),
|
||||
|
|
|
@ -35,6 +35,8 @@ CScriptPlayerActor::CScriptPlayerActor(TUniqueId uid, std::string_view name, con
|
|||
SetActorLights(aParams.GetLightParameters().MakeActorLights());
|
||||
xe7_29_drawEnabled = true;
|
||||
x2e3_24_isPlayerActor = true;
|
||||
|
||||
_CreateReflectionCube();
|
||||
}
|
||||
|
||||
u32 CScriptPlayerActor::GetSuitCharIdx(const CStateManager& mgr, CPlayerState::EPlayerSuit suit) const {
|
||||
|
@ -360,6 +362,7 @@ void CScriptPlayerActor::PreRender(CStateManager& mgr, const zeus::CFrustum& fru
|
|||
}
|
||||
if (x2e8_suitRes.GetCharacterNodeId() == 3)
|
||||
g_Renderer->AllocatePhazonSuitMaskTexture();
|
||||
xb4_drawFlags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
CScriptActor::PreRender(mgr, frustum);
|
||||
}
|
||||
|
||||
|
@ -370,6 +373,8 @@ void CScriptPlayerActor::AddToRenderer(const zeus::CFrustum& frustum, const CSta
|
|||
}
|
||||
|
||||
void CScriptPlayerActor::Render(const CStateManager& mgr) const {
|
||||
CBooModel::SetReflectionCube(m_reflectionCube);
|
||||
|
||||
bool phazonSuit = x2e8_suitRes.GetCharacterNodeId() == 3;
|
||||
if (phazonSuit) {
|
||||
// Draw into alpha buffer
|
||||
|
@ -387,7 +392,7 @@ void CScriptPlayerActor::Render(const CStateManager& mgr) const {
|
|||
CModelFlags flags(5, 0, 3, zeus::skWhite);
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
x314_beamModelData->Render(mgr, modelXf, x90_actorLights.get(), flags);
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
flags.x4_color = zeus::CColor{1.f, xb4_drawFlags.x4_color.a()};
|
||||
x314_beamModelData->Render(mgr, modelXf, x90_actorLights.get(), flags);
|
||||
}
|
||||
|
|
|
@ -167,64 +167,107 @@ void CWorldTransManager::Update(float dt) {
|
|||
}
|
||||
}
|
||||
|
||||
void CWorldTransManager::DrawAllModels() {
|
||||
CActorLights lights(0, zeus::skZero3f, 4, 4, 0, 0, 0, 0.1f);
|
||||
lights.BuildFakeLightList(x4_modelData->x1a0_lights, zeus::CColor{0.1f, 0.1f, 0.1f, 1.0f});
|
||||
|
||||
void CWorldTransManager::DrawPlatformModels(CActorLights* lights) {
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
|
||||
if (!x4_modelData->x100_bgModelData[0].IsNull()) {
|
||||
zeus::CTransform xf0 = zeus::CTransform::Translate(0.f, 0.f, -(2.f * x1c_bgHeight - x18_bgOffset));
|
||||
x4_modelData->x100_bgModelData[0].Render(CModelData::EWhichModel::Normal, xf0, &lights, flags);
|
||||
x4_modelData->x100_bgModelData[0].Render(CModelData::EWhichModel::Normal, xf0, lights, flags);
|
||||
}
|
||||
if (!x4_modelData->x100_bgModelData[1].IsNull()) {
|
||||
zeus::CTransform xf1 = zeus::CTransform::Translate(0.f, 0.f, x18_bgOffset - x1c_bgHeight);
|
||||
x4_modelData->x100_bgModelData[1].Render(CModelData::EWhichModel::Normal, xf1, &lights, flags);
|
||||
x4_modelData->x100_bgModelData[1].Render(CModelData::EWhichModel::Normal, xf1, lights, flags);
|
||||
}
|
||||
if (!x4_modelData->x100_bgModelData[2].IsNull()) {
|
||||
zeus::CTransform xf2 = zeus::CTransform::Translate(0.f, 0.f, x18_bgOffset);
|
||||
x4_modelData->x100_bgModelData[2].Render(CModelData::EWhichModel::Normal, xf2, &lights, flags);
|
||||
x4_modelData->x100_bgModelData[2].Render(CModelData::EWhichModel::Normal, xf2, lights, flags);
|
||||
}
|
||||
|
||||
if (!x4_modelData->xb4_platformModelData.IsNull()) {
|
||||
x4_modelData->xb4_platformModelData.Render(CModelData::EWhichModel::Normal, zeus::CTransform(), &lights,
|
||||
x4_modelData->xb4_platformModelData.Render(CModelData::EWhichModel::Normal, zeus::CTransform(), lights,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldTransManager::DrawAllModels(CActorLights* lights) {
|
||||
DrawPlatformModels(lights);
|
||||
|
||||
if (!x4_modelData->x1c_samusModelData.IsNull()) {
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = EExtendedShader::LightingCubeReflection;
|
||||
|
||||
x4_modelData->x1c_samusModelData.AnimationData()->PreRender();
|
||||
x4_modelData->x1c_samusModelData.Render(CModelData::EWhichModel::Normal, zeus::CTransform(), &lights,
|
||||
x4_modelData->x1c_samusModelData.Render(CModelData::EWhichModel::Normal, zeus::CTransform(), lights,
|
||||
flags);
|
||||
|
||||
if (!x4_modelData->x68_beamModelData.IsNull()) {
|
||||
x4_modelData->x68_beamModelData.Render(CModelData::EWhichModel::Normal, x4_modelData->x170_gunXf, &lights, flags);
|
||||
x4_modelData->x68_beamModelData.Render(CModelData::EWhichModel::Normal, x4_modelData->x170_gunXf, lights, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldTransManager::DrawFirstPass() {
|
||||
void CWorldTransManager::DrawFirstPass(CActorLights* lights) {
|
||||
CBooModel::SetReflectionCube(m_reflectionCube[0]);
|
||||
zeus::CTransform translateXf = zeus::CTransform::Translate(
|
||||
x4_modelData->x1b4_shakeResult.x(), -3.5f * (1.f - zeus::clamp(0.f, x0_curTime / 10.f, 1.f)) - 3.5f,
|
||||
x4_modelData->x1b4_shakeResult.y() + 2.f);
|
||||
zeus::CTransform rotateXf =
|
||||
zeus::CTransform::RotateZ(zeus::degToRad(zeus::clamp(0.f, x0_curTime / 25.f, 100.f) * 360.f + 180.f - 90.f));
|
||||
CGraphics::SetViewPointMatrix(rotateXf * translateXf);
|
||||
DrawAllModels();
|
||||
DrawAllModels(lights);
|
||||
m_camblur.draw(x4_modelData->x1c8_blurResult);
|
||||
}
|
||||
|
||||
void CWorldTransManager::DrawSecondPass() {
|
||||
void CWorldTransManager::DrawSecondPass(CActorLights* lights) {
|
||||
CBooModel::SetReflectionCube(m_reflectionCube[1]);
|
||||
const zeus::CVector3f& samusScale = x4_modelData->x0_samusRes.GetScale();
|
||||
zeus::CTransform translateXf =
|
||||
zeus::CTransform::Translate(-0.1f * samusScale.x(), -0.5f * samusScale.y(), 1.5f * samusScale.z());
|
||||
zeus::CTransform rotateXf = zeus::CTransform::RotateZ(zeus::degToRad(
|
||||
48.f * zeus::clamp(0.f, (x0_curTime - x4_modelData->x1d0_dissolveStartTime + 2.f) / 5.f, 1.f) + 180.f - 24.f));
|
||||
CGraphics::SetViewPointMatrix(rotateXf * translateXf);
|
||||
DrawAllModels();
|
||||
DrawAllModels(lights);
|
||||
}
|
||||
|
||||
void CWorldTransManager::DrawEnabled() {
|
||||
CActorLights lights(0, zeus::skZero3f, 4, 4, 0, 0, 0, 0.1f);
|
||||
lights.BuildFakeLightList(x4_modelData->x1a0_lights, zeus::CColor{0.1f, 0.1f, 0.1f, 1.0f});
|
||||
|
||||
SViewport backupVp = g_Viewport;
|
||||
constexpr float width = CUBEMAP_RES;
|
||||
CGraphics::g_BooMainCommandQueue->setRenderTarget(m_reflectionCube[0], 0);
|
||||
g_Renderer->SetViewport(0, 0, width, width);
|
||||
g_Renderer->SetPerspective(90.f, width, width, 0.2f, 750.f);
|
||||
|
||||
if (x0_curTime < x4_modelData->x1d4_dissolveEndTime) {
|
||||
zeus::CTransform mainCamXf =
|
||||
zeus::CTransform::RotateZ(zeus::degToRad(zeus::clamp(0.f, x0_curTime / 25.f, 100.f) * 360.f + 180.f - 90.f));
|
||||
for (int face = 0; face < 6; ++face) {
|
||||
CGraphics::g_BooMainCommandQueue->setRenderTarget(m_reflectionCube[0], face);
|
||||
CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
zeus::CTransform camXf = zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], zeus::CVector3f(0.f, 0.f, 1.5f));
|
||||
g_Renderer->SetWorldViewpoint(camXf);
|
||||
DrawPlatformModels(&lights);
|
||||
}
|
||||
CGraphics::g_BooMainCommandQueue->generateMipmaps(m_reflectionCube[0]);
|
||||
}
|
||||
if (x0_curTime > x4_modelData->x1d0_dissolveStartTime) {
|
||||
zeus::CTransform mainCamXf = zeus::CTransform::RotateZ(zeus::degToRad(
|
||||
48.f * zeus::clamp(0.f, (x0_curTime - x4_modelData->x1d0_dissolveStartTime + 2.f) / 5.f, 1.f) + 180.f - 24.f));
|
||||
for (int face = 0; face < 6; ++face) {
|
||||
CGraphics::g_BooMainCommandQueue->setRenderTarget(m_reflectionCube[1], face);
|
||||
CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
zeus::CTransform camXf = zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], zeus::CVector3f(0.f, 0.f, 1.5f));
|
||||
g_Renderer->SetWorldViewpoint(camXf);
|
||||
DrawPlatformModels(&lights);
|
||||
}
|
||||
CGraphics::g_BooMainCommandQueue->generateMipmaps(m_reflectionCube[1]);
|
||||
}
|
||||
|
||||
CBooRenderer::BindMainDrawTarget();
|
||||
g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
|
||||
|
||||
float wsAspect = CWideScreenFilter::SetViewportToMatch(1.f);
|
||||
|
||||
g_Renderer->SetPerspective(CCameraManager::FirstPersonFOV(), wsAspect, CCameraManager::NearPlane(),
|
||||
|
@ -232,16 +275,16 @@ void CWorldTransManager::DrawEnabled() {
|
|||
g_Renderer->x318_26_requestRGBA6 = true;
|
||||
|
||||
if (x0_curTime <= x4_modelData->x1d0_dissolveStartTime)
|
||||
DrawFirstPass();
|
||||
DrawFirstPass(&lights);
|
||||
else if (x0_curTime >= x4_modelData->x1d4_dissolveEndTime)
|
||||
DrawSecondPass();
|
||||
DrawSecondPass(&lights);
|
||||
else {
|
||||
float t = zeus::clamp(0.f, (x0_curTime - x4_modelData->x1d0_dissolveStartTime) / 2.f, 1.f);
|
||||
DrawFirstPass();
|
||||
DrawFirstPass(&lights);
|
||||
SClipScreenRect rect(g_Viewport);
|
||||
CGraphics::ResolveSpareTexture(rect);
|
||||
CGraphics::g_BooMainCommandQueue->clearTarget(true, true);
|
||||
DrawSecondPass();
|
||||
DrawSecondPass(&lights);
|
||||
m_dissolve.drawCropped(zeus::CColor{1.f, 1.f, 1.f, 1.f - t}, 1.f);
|
||||
}
|
||||
|
||||
|
@ -335,6 +378,13 @@ void CWorldTransManager::EnableTransition(const CAnimRes& samusRes, CAssetId pla
|
|||
x30_type = ETransType::Enabled;
|
||||
x4_modelData.reset(new SModelDatas(samusRes));
|
||||
|
||||
if (!m_reflectionCube[0])
|
||||
CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
m_reflectionCube[0] = ctx.newCubeRenderTexture(CUBEMAP_RES, CUBEMAP_MIPS);
|
||||
m_reflectionCube[1] = ctx.newCubeRenderTexture(CUBEMAP_RES, CUBEMAP_MIPS);
|
||||
return true;
|
||||
} BooTrace);
|
||||
|
||||
x8_textData.reset();
|
||||
x20_random.SetSeed(99);
|
||||
|
||||
|
|
|
@ -77,10 +77,13 @@ private:
|
|||
CWideScreenFilter m_widescreen = {EFilterType::Blend};
|
||||
CCameraBlurFilter m_camblur;
|
||||
|
||||
boo::ObjToken<boo::ITextureCubeR> m_reflectionCube[2];
|
||||
|
||||
static int GetSuitCharIdx();
|
||||
void DrawFirstPass();
|
||||
void DrawSecondPass();
|
||||
void DrawAllModels();
|
||||
void DrawFirstPass(CActorLights* lights);
|
||||
void DrawSecondPass(CActorLights* lights);
|
||||
void DrawPlatformModels(CActorLights* lights);
|
||||
void DrawAllModels(CActorLights* lights);
|
||||
void UpdateLights(float dt);
|
||||
void UpdateEnabled(float);
|
||||
void UpdateDisabled(float);
|
||||
|
|
|
@ -14,7 +14,12 @@ TBINDING7 uniform sampler2D reflectionIndTex;
|
|||
TBINDING8 uniform sampler2D extTex0;
|
||||
TBINDING9 uniform sampler2D extTex1;
|
||||
TBINDING10 uniform sampler2D extTex2;
|
||||
|
||||
#if defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW)
|
||||
TBINDING11 uniform samplerCube reflectionTex;
|
||||
#else
|
||||
TBINDING11 uniform sampler2D reflectionTex;
|
||||
#endif
|
||||
|
||||
const vec3 kRGBToYPrime = vec3(0.257, 0.504, 0.098);
|
||||
|
||||
|
@ -84,7 +89,7 @@ vec3 SampleTexture_alpha() { return texture(alpha, vtf.alphaUv).rgb; }
|
|||
float SampleTextureAlpha_alpha() { return dot(texture(alpha, vtf.alphaUv).rgb, kRGBToYPrime); }
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||
struct Fog {
|
||||
vec4 color;
|
||||
float A;
|
||||
|
@ -94,7 +99,7 @@ struct Fog {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW)
|
||||
struct Light {
|
||||
vec4 pos;
|
||||
vec4 dir;
|
||||
|
@ -119,7 +124,7 @@ const vec4 colorReg1 = vec4(1.0);
|
|||
const vec4 colorReg2 = vec4(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING)
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_CUBE_REFLECTION)
|
||||
vec3 LightingFunc() {
|
||||
vec4 ret = ambient;
|
||||
|
||||
|
@ -176,7 +181,7 @@ UBINDING2 uniform MBShadowUniform {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING_SHADOW)
|
||||
#if defined(URDE_LIGHTING_SHADOW) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW)
|
||||
vec3 LightingFunc() {
|
||||
vec2 shadowUV = vtf.extUvs[0];
|
||||
shadowUV.y = 1.0 - shadowUV.y;
|
||||
|
@ -224,7 +229,7 @@ vec3 LightingFunc() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||
vec4 FogFunc(vec4 colorIn) {
|
||||
float fogZ;
|
||||
float fogF = clamp((fog.A / (fog.B - gl_FragCoord.z)) - fog.C, 0.0, 1.0);
|
||||
|
@ -257,7 +262,7 @@ vec4 FogFunc(vec4 colorIn) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW)
|
||||
vec4 PostFunc(vec4 colorIn) {
|
||||
return FogFunc(colorIn) * mulColor + addColor;
|
||||
}
|
||||
|
@ -303,7 +308,10 @@ vec4 PostFunc(vec4 colorIn) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(URDE_REFLECTION_SIMPLE)
|
||||
#if defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW)
|
||||
vec3 ReflectionFunc(float roughness) { return texture(reflectionTex, reflect(vtf.mvPos.xyz, vtf.mvNorm.xyz),
|
||||
roughness * 5.0).rgb; }
|
||||
#elif defined(URDE_REFLECTION_SIMPLE)
|
||||
vec3 ReflectionFunc() { return texture(reflectionTex, vtf.dynReflectionUvs[1]).rgb * vtf.dynReflectionAlpha; }
|
||||
#elif defined(URDE_REFLECTION_INDIRECT)
|
||||
vec3 ReflectionFunc() { return texture(reflectionTex, (texture(reflectionIndTex, vtf.dynReflectionUvs[0]).ab -
|
||||
|
@ -316,7 +324,12 @@ layout(location=0) out vec4 colorOut;
|
|||
void main() {
|
||||
vec3 lighting = LightingFunc();
|
||||
vec4 tmp;
|
||||
#if defined(URDE_DIFFUSE_ONLY)
|
||||
#if defined(URDE_LIGHTING_CUBE_REFLECTION) || defined(URDE_LIGHTING_CUBE_REFLECTION_SHADOW)
|
||||
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() +
|
||||
SampleTexture_emissive() + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||
(SampleTexture_reflection() * ReflectionFunc(clamp(0.5 - SampleTextureAlpha_specular(), 0.0, 1.0)) * 2.0);
|
||||
tmp.a = SampleTextureAlpha_alpha();
|
||||
#elif defined(URDE_DIFFUSE_ONLY)
|
||||
tmp.rgb = SampleTexture_diffuse();
|
||||
tmp.a = SampleTextureAlpha_alpha();
|
||||
#elif defined(RETRO_SHADER)
|
||||
|
|
|
@ -96,6 +96,7 @@ static std::string _BuildVS(const SModelShadersInfo& info) {
|
|||
if (info.m_tag.getWeightCount())
|
||||
vertOut << "layout(location="sv << 2 + info.m_tag.getColorCount() + info.m_tag.getUvCount() <<
|
||||
") in vec4 weightIn["sv << unsigned(info.m_tag.getWeightCount()) << "];"sv;
|
||||
vertOut << '\n';
|
||||
|
||||
vertOut << "#define URDE_TCG_EXPR "sv;
|
||||
using UVAnimType = BlendMaterial::UVAnimType;
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 4c65ccf85be21b9869dcdaea09692ca6677f3204
|
||||
Subproject commit 9bb5181bbd9657c6b48d9a214352a72b26d411a0
|
Loading…
Reference in New Issue