mirror of https://github.com/AxioDL/metaforce.git
Initial fog volume rendering implementation
This commit is contained in:
parent
0f6ae9d217
commit
2d093b6d80
|
@ -9,8 +9,12 @@
|
|||
#include "Particle/CElementGen.hpp"
|
||||
#include "CMetroidModelInstance.hpp"
|
||||
#include "Collision/CAreaOctTree.hpp"
|
||||
#include "zeus/CUnitVector.hpp"
|
||||
#include "Graphics/CSkinnedModel.hpp"
|
||||
|
||||
#define FOGVOL_RAMP_RES 256
|
||||
#define FOGVOL_FAR 750.0
|
||||
#define FOGVOL_NEAR 0.2
|
||||
#define SPHERE_RAMP_RES 32
|
||||
|
||||
namespace urde
|
||||
|
@ -268,42 +272,160 @@ void CBooRenderer::HandleUnsortedModel(CAreaListItem* item, CBooModel& model)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct FogVolumeControl
|
||||
{
|
||||
|
||||
u32 xfc_[12][2] =
|
||||
{
|
||||
{0, 1},
|
||||
{1, 3},
|
||||
{3, 2},
|
||||
{2, 0},
|
||||
{4, 5},
|
||||
{5, 7},
|
||||
{7, 6},
|
||||
{6, 4},
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{3, 7},
|
||||
{2, 6}
|
||||
};
|
||||
u32 x15c_[8] = {};
|
||||
//GXVtxDescList x17c_; {{POS, DIRECT}, {TEX0, DIRECT}}
|
||||
|
||||
} s_FogVolumeCtrl = {};
|
||||
|
||||
void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, int numPlanes,
|
||||
int iteration, const zeus::CVector3f& center, float delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model,
|
||||
const zeus::CTransform& modelMtx, const zeus::CTransform& viewMtx,
|
||||
const CSkinnedModel* sModel)
|
||||
{
|
||||
if (!model && !sModel)
|
||||
{
|
||||
zeus::CAABox xfAABB = aabb.getTransformedAABox(modelMtx);
|
||||
zeus::CUnitVector3f viewNormal(viewMtx.basis[1]);
|
||||
zeus::CPlane planes[7] =
|
||||
{
|
||||
{zeus::CVector3f::skRight, xfAABB.min.x},
|
||||
{zeus::CVector3f::skLeft, -xfAABB.max.x},
|
||||
{zeus::CVector3f::skForward, xfAABB.min.y},
|
||||
{zeus::CVector3f::skBack, -xfAABB.max.y},
|
||||
{zeus::CVector3f::skUp, xfAABB.min.z},
|
||||
{zeus::CVector3f::skDown, -xfAABB.max.z},
|
||||
{viewNormal, viewNormal.dot(viewMtx.origin) + 0.2f + 0.1f}
|
||||
};
|
||||
|
||||
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||
|
||||
float delta = std::max(std::max(
|
||||
xfAABB.max.x - xfAABB.min.x,
|
||||
xfAABB.max.y - xfAABB.min.y),
|
||||
xfAABB.max.z - xfAABB.min.z) * 2.f;
|
||||
|
||||
for (int i=0 ; i<7 ; ++i)
|
||||
DrawFogSlices(planes, 7, i, xfAABB.center(), delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
CModelFlags flags;
|
||||
flags.m_extendedShaderIdx = 5;
|
||||
if (sModel)
|
||||
{
|
||||
sModel->Draw(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
model->UpdateLastFrame();
|
||||
model->GetInstance().Draw(flags, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb,
|
||||
const CModel* model, const CSkinnedModel* sModel)
|
||||
{
|
||||
zeus::CTransform backupModel = CGraphics::g_GXModelMatrix;
|
||||
zeus::CTransform backupView = CGraphics::g_ViewMatrix;
|
||||
zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(false);
|
||||
zeus::CVector3f points[8];
|
||||
float wVals[8];
|
||||
zeus::CVector4f points[8];
|
||||
|
||||
for (int i=0 ; i<8 ; ++i)
|
||||
{
|
||||
zeus::CVector3f pt = backupModel * aabb.getPoint(i);
|
||||
zeus::CVector3f xfPt =
|
||||
backupView.transposeRotate(zeus::CVector3f(pt.x - backupModel.basis[1].z,
|
||||
pt.y - backupModel.basis[1].y,
|
||||
pt.z - backupModel.basis[1].x));
|
||||
zeus::CVector4f xfPt4 = proj * zeus::CVector4f(xfPt);
|
||||
points[i] = xfPt4.toVec3f();
|
||||
wVals[i] = xfPt4.w;
|
||||
zeus::CVector3f xfPt = backupView.transposeRotate(pt - backupView.origin);
|
||||
points[i] = proj * zeus::CVector4f(xfPt);
|
||||
}
|
||||
|
||||
// TODO: Finish
|
||||
zeus::CVector2i vpMax(0, 0);
|
||||
zeus::CVector2i vpMin(g_Viewport.x8_width, g_Viewport.xc_height);
|
||||
|
||||
bool b1 = true;
|
||||
for (int i=0 ; i<20 ; ++i)
|
||||
{
|
||||
zeus::CVector3f overW;
|
||||
if (i < 8)
|
||||
{
|
||||
overW = points[i] * (1.f / wVals[i]);
|
||||
overW = points[i].toVec3f() * (1.f / points[i].w);
|
||||
}
|
||||
else
|
||||
{
|
||||
const zeus::CVector4f& pt1 = points[s_FogVolumeCtrl.xfc_[i-8][0]];
|
||||
const zeus::CVector4f& pt2 = points[s_FogVolumeCtrl.xfc_[i-8][1]];
|
||||
|
||||
bool eq1 = (pt1.z / pt1.w) == 1.f;
|
||||
bool eq2 = (pt2.z / pt2.w) == 1.f;
|
||||
if (eq1 == eq2)
|
||||
continue;
|
||||
|
||||
float interp = -(pt1.w - 1.f) / (pt2.w - pt1.w);
|
||||
if (interp <= 0.f || interp >= 1.f)
|
||||
continue;
|
||||
|
||||
float wRecip = 1.f / (interp * (pt2.w - pt1.w) + pt1.w);
|
||||
zeus::CVector3f pt1_3 = pt1.toVec3f();
|
||||
zeus::CVector3f pt2_3 = pt2.toVec3f();
|
||||
overW = (pt1_3 + interp * (pt2_3 - pt1_3)) * wRecip;
|
||||
}
|
||||
|
||||
if (overW.z > 1.001f)
|
||||
continue;
|
||||
|
||||
int vpX = zeus::clamp(0, int(g_Viewport.x8_width * overW.x * 0.5f + (g_Viewport.x8_width / 2)), int(g_Viewport.x8_width));
|
||||
int vpY = zeus::clamp(0, int(g_Viewport.xc_height * overW.y * 0.5f + (g_Viewport.xc_height / 2)), int(g_Viewport.xc_height));
|
||||
vpMax.x = std::max(vpMax.x, vpX);
|
||||
vpMin.x = std::min(vpMin.x, vpX);
|
||||
vpMax.y = std::max(vpMax.y, vpY);
|
||||
vpMin.y = std::min(vpMin.y, vpY);
|
||||
b1 = false;
|
||||
}
|
||||
|
||||
zeus::CVector2i vpSize = {320, 228};
|
||||
if (!b1)
|
||||
{
|
||||
vpSize.x = std::min(320, vpMax.x - vpMin.x);
|
||||
vpSize.y = std::min(320, vpMax.y - vpMin.y);
|
||||
|
||||
}
|
||||
|
||||
if (vpSize.x <= 0 || vpSize.y <= 0)
|
||||
return;
|
||||
|
||||
//vpMin.y + g_Viewport.x4_top;
|
||||
|
||||
zeus::CAABox box((backupModel * aabb.min) - 1.f, (backupModel * aabb.max) + 1.f);
|
||||
if (box.pointInside(CGraphics::g_ViewPoint) && (model || sModel))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx)
|
||||
|
@ -314,7 +436,9 @@ void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context&
|
|||
for (int x=0 ; x<FOGVOL_RAMP_RES ; ++x)
|
||||
{
|
||||
int tmp = y << 16 | x << 8 | 0x7f;
|
||||
double a = zeus::clamp(0.0, (-150.0 / (tmp * 749.7998 - 750.0) - 0.2) * 3.0 / 749.7998, 1.0);
|
||||
double a = zeus::clamp(0.0, (-150.0 / (tmp / double(0xffffff) *
|
||||
(FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) * 3.0 /
|
||||
(FOGVOL_FAR - FOGVOL_NEAR), 1.0);
|
||||
data[y][x] = (a * a + a) / 2.f * 255;
|
||||
}
|
||||
}
|
||||
|
@ -737,6 +861,7 @@ void CBooRenderer::DrawThermalModel(const CModel& model, const zeus::CColor& mul
|
|||
flags.m_extendedShaderIdx = 2;
|
||||
flags.color = mulCol;
|
||||
flags.addColor = addCol;
|
||||
model.UpdateLastFrame();
|
||||
model.Draw(flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "CPVSVisSet.hpp"
|
||||
#include "zeus/CRectangle.hpp"
|
||||
#include "World/CGameArea.hpp"
|
||||
#include "zeus/CPlane.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -165,6 +166,10 @@ class CBooRenderer : public IRenderer
|
|||
void ActivateLightsForModel(CAreaListItem* item, CBooModel& model);
|
||||
void RenderBucketItems(CAreaListItem* item);
|
||||
void HandleUnsortedModel(CAreaListItem* item, CBooModel& model);
|
||||
static void DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int iteration,
|
||||
const zeus::CVector3f& center, float delta);
|
||||
static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
|
||||
const zeus::CTransform& viewMtx, const CSkinnedModel* sModel);
|
||||
void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb,
|
||||
const CModel* model, const CSkinnedModel* sModel);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ SClipScreenRect CGraphics::g_CroppedViewport;
|
|||
int CGraphics::g_ViewportSamples = 1;
|
||||
bool CGraphics::g_IsGXModelMatrixIdentity = true;
|
||||
SViewport g_Viewport = {0, 0, 640, 480, 640 / 2.f, 480 / 2.f};
|
||||
u32 CGraphics::g_FrameCounter = 0;
|
||||
|
||||
void CGraphics::DisableAllLights()
|
||||
{
|
||||
|
@ -117,6 +118,8 @@ void CGraphics::EndScene()
|
|||
|
||||
/* Flush text instance buffers just before GPU command list submission */
|
||||
CTextSupportShader::UpdateBuffers();
|
||||
|
||||
++g_FrameCounter;
|
||||
}
|
||||
|
||||
void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1)
|
||||
|
|
|
@ -284,6 +284,8 @@ public:
|
|||
{g_ExternalTimeProvider = provider;}
|
||||
static float GetSecondsMod900();
|
||||
static void TickRenderTimings();
|
||||
static u32 g_FrameCounter;
|
||||
static u32 GetFrameCounter() { return g_FrameCounter; }
|
||||
|
||||
static boo::IGraphicsDataFactory::Platform g_BooPlatform;
|
||||
static const boo::SystemChar* g_BooPlatformName;
|
||||
|
|
|
@ -194,6 +194,7 @@ class CModel
|
|||
std::unique_ptr<CBooModel> x28_modelInst;
|
||||
CModel* x30_next = nullptr;
|
||||
CModel* x34_prev = nullptr;
|
||||
int x38_lastFrame;
|
||||
|
||||
/* urde addition: boo! */
|
||||
boo::GraphicsDataToken m_gfxToken;
|
||||
|
@ -217,6 +218,7 @@ public:
|
|||
CBooModel& GetInstance() {return *x28_modelInst;}
|
||||
const CBooModel& GetInstance() const {return *x28_modelInst;}
|
||||
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts);
|
||||
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
||||
};
|
||||
|
||||
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
||||
|
|
|
@ -764,6 +764,7 @@ std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts)
|
|||
CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef)
|
||||
: m_selfToken(selfRef)
|
||||
{
|
||||
x38_lastFrame = CGraphics::GetFrameCounter() - 2;
|
||||
std::unique_ptr<u8[]> data = std::move(in);
|
||||
|
||||
u32 version = hecl::SBig(*reinterpret_cast<u32*>(data.get() + 0x4));
|
||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
|||
Subproject commit de06e0173e9440d75287c0b7431e101fc53e570e
|
||||
Subproject commit 7ea8e20e0310c4f45da0c0c8396b6f6c00a70b85
|
Loading…
Reference in New Issue