Fix water rendering

This commit is contained in:
Jack Andersen 2018-06-02 20:11:39 -10:00
parent 357a7efa9a
commit a5f25bf3f4
16 changed files with 98 additions and 73 deletions

View File

@ -52,7 +52,7 @@ void Buckets::Sort()
float delta = std::max(1.f, sMinMaxDistance[1] - sMinMaxDistance[0]);
float pitch = 49.f / delta;
for (auto it = sPlaneObjectData->begin() ; it != sPlaneObjectData->end() ; ++it)
if (sPlaneObjectBucket->size() < 8)
if (sPlaneObjectBucket->size() != sPlaneObjectBucket->capacity())
sPlaneObjectBucket->push_back(s16(it - sPlaneObjectData->begin()));
u32 precision = 50;
@ -119,14 +119,14 @@ void Buckets::Sort()
bucket.push_back(&drawable);
}
int bucketIdx = sBuckets->size();
u16 bucketIdx = u16(sBuckets->size());
for (auto it = sBuckets->rbegin() ; it != sBuckets->rend() ; ++it)
{
--bucketIdx;
sBucketIndex.push_back(bucketIdx);
rstl::reserved_vector<CDrawable*, 128>& bucket = *it;
if (bucket.size())
{
sBucketIndex.push_back(bucketIdx);
std::sort(bucket.begin(), bucket.end(),
[](CDrawable* a, CDrawable* b) -> bool
{
@ -143,10 +143,12 @@ void Buckets::Sort()
}
}
void Buckets::InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool invertTest,
void Buckets::InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest,
const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data)
{
sPlaneObjectData->push_back(CDrawablePlaneObject(dtype, dist, something, aabb, invertTest, plane, zOnly, data));
if (sPlaneObjectData->size() == sPlaneObjectData->capacity())
return;
sPlaneObjectData->push_back(CDrawablePlaneObject(dtype, closeDist, farDist, aabb, invertTest, plane, zOnly, data));
}
void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype,
@ -1039,9 +1041,20 @@ void CBooRenderer::AddParticleGen(const CParticleGen& gen)
}
}
void CBooRenderer::AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)
void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type)
{
float closeDist = xb0_viewPlane.pointToPlaneDist(aabb.closestPointAlongVector(xb0_viewPlane.normal()));
float farDist = xb0_viewPlane.pointToPlaneDist(aabb.furthestPointAlongVector(xb0_viewPlane.normal()));
if (closeDist >= 0.f || farDist >= 0.f)
{
bool zOnly = plane.normal().isZero();
bool invert;
if (zOnly)
invert = CGraphics::g_ViewMatrix.origin.z >= plane.d;
else
invert = plane.pointToPlaneDist(CGraphics::g_ViewMatrix.origin) >= 0.f;
Buckets::InsertPlaneObject(closeDist, farDist, aabb, invert, plane, zOnly, EDrawableType(type + 2), obj);
}
}
void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb,

View File

@ -42,7 +42,7 @@ class Buckets
public:
static void Clear();
static void Sort();
static void InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool invertTest,
static void InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest,
const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data);
static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype,
const void* data, const zeus::CPlane& plane, u16 extraSort);

View File

@ -10,14 +10,14 @@ class CDrawablePlaneObject : public CDrawable
{
friend class Buckets;
u16 x24_targetBucket;
float x28_something;
float x28_farDist;
zeus::CPlane x2c_plane;
bool x3c_24_invertTest : 1;
bool x3c_25_zOnly : 1;
public:
CDrawablePlaneObject(EDrawableType dtype, float dist, float something, const zeus::CAABox& aabb,
CDrawablePlaneObject(EDrawableType dtype, float closeDist, float farDist, const zeus::CAABox& aabb,
bool invertTest, const zeus::CPlane& plane, bool zOnly, const void* data)
: CDrawable(dtype, 0, dist, aabb, data), x24_targetBucket(0), x28_something(something),
: CDrawable(dtype, 0, closeDist, aabb, data), x24_targetBucket(0), x28_farDist(farDist),
x2c_plane(plane) {x3c_24_invertTest = invertTest; x3c_25_zOnly = zOnly;}
const zeus::CPlane& GetPlane() const { return x2c_plane; }
};

View File

@ -380,13 +380,12 @@ public:
void AddVert(const VTX& vert)
{
++m_added;
if (m_added > 3)
if (m_added > 3 && (m_added & 1) == 0)
{
const VTX& last = m_vec.back();
m_vec.reserve(m_vec.size() + 4);
m_vec.push_back(m_vec[m_start]);
m_vec.push_back(m_vec[m_start]);
m_vec.reserve(m_vec.size() + 3);
m_vec.push_back(last);
m_vec.push_back(m_vec[m_start]);
}
m_vec.push_back(vert);
}
@ -395,13 +394,12 @@ public:
void EmplaceVert(_Args&&... args)
{
++m_added;
if (m_added > 3)
if (m_added > 3 && (m_added & 1) == 0)
{
const VTX& last = m_vec.back();
m_vec.reserve(m_vec.size() + 4);
m_vec.push_back(m_vec[m_start]);
m_vec.push_back(m_vec[m_start]);
m_vec.reserve(m_vec.size() + 3);
m_vec.push_back(last);
m_vec.push_back(m_vec[m_start]);
}
m_vec.emplace_back(std::forward<_Args>(args)...);
}

View File

@ -33,15 +33,16 @@ BOO_GLSL_BINDING_HEAD
"SBINDING(0) out VertToFrag vtf;\n"
"void main()\n"
"{\n"
" vtf.mvPos = mv * vec4(posIn.xyz, 1.0);\n"
" vec4 pos = vec4(posIn.xyz, 1.0);\n"
" vtf.mvPos = mv * pos;\n"
" gl_Position = proj * vtf.mvPos;\n"
" vtf.mvNorm = mvNorm * normalIn;\n"
" vtf.mvBinorm = mvNorm * binormalIn;\n"
" vtf.mvTangent = mvNorm * tangentIn;\n"
" vtf.color = colorIn;\n"
" vtf.uvs[0] = (texMtxs[0] * posIn).xy;\n"
" vtf.uvs[1] = (texMtxs[1] * posIn).xy;\n"
" vtf.uvs[2] = (texMtxs[2] * posIn).xy;\n"
" vtf.uvs[0] = (texMtxs[0] * pos).xy;\n"
" vtf.uvs[1] = (texMtxs[1] * pos).xy;\n"
" vtf.uvs[2] = (texMtxs[2] * pos).xy;\n"
"%s" // Additional TCGs here
"}\n";
@ -214,22 +215,22 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
if (info.m_hasBumpMap)
{
bumpMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[0] * posIn).xy;\n", nextTCG++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[0] * pos).xy;\n", nextTCG++);
}
if (info.m_hasEnvBumpMap)
{
envBumpMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[3] * posIn).xy;\n", nextTCG++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[3] * vec4(normalize(normalIn.xyz), 1.0)).xy;\n", nextTCG++);
}
if (info.m_hasEnvMap)
{
envMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * posIn).xy;\n", nextTCG++, nextMtx++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
}
if (info.m_hasLightmap)
{
lightmapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * posIn).xy;\n", nextTCG++, nextMtx++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
}
switch (info.m_type)

View File

@ -37,15 +37,16 @@ static const char* VS =
"VertToFrag main(in VertData v)\n"
"{\n"
" VertToFrag vtf;\n"
" vtf.mvPos = mul(mv, float4(v.posIn.xyz, 1.0));\n"
" float4 pos = float4(v.posIn.xyz, 1.0);\n"
" vtf.mvPos = mul(mv, pos);\n"
" vtf.pos = mul(proj, vtf.mvPos);\n"
" vtf.mvNorm = mul(mvNorm, v.normalIn);\n"
" vtf.mvBinorm = mul(mvNorm, v.binormalIn);\n"
" vtf.mvTangent = mul(mvNorm, v.tangentIn);\n"
" vtf.color = v.colorIn;\n"
" vtf.uvs[0] = mul(texMtxs[0], v.posIn).xy;\n"
" vtf.uvs[1] = mul(texMtxs[1], v.posIn).xy;\n"
" vtf.uvs[2] = mul(texMtxs[2], v.posIn).xy;\n"
" vtf.uvs[0] = mul(texMtxs[0], pos).xy;\n"
" vtf.uvs[1] = mul(texMtxs[1], pos).xy;\n"
" vtf.uvs[2] = mul(texMtxs[2], pos).xy;\n"
"%s" // Additional TCGs here
" return vtf;\n"
"}\n";
@ -209,22 +210,22 @@ CFluidPlaneShader::BuildShader(boo::D3DDataFactory::Context& ctx, const SFluidPl
if (info.m_hasBumpMap)
{
bumpMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[0], v.posIn).xy;\n", nextTCG++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[0], pos).xy;\n", nextTCG++);
}
if (info.m_hasEnvBumpMap)
{
envBumpMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[3], v.posIn).xy;\n", nextTCG++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[3], float4(normalize(v.normalIn.xyz), 1.0)).xy;\n", nextTCG++);
}
if (info.m_hasEnvMap)
{
envMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[%d], v.posIn).xy;\n", nextTCG++, nextMtx++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[%d], pos).xy;\n", nextTCG++, nextMtx++);
}
if (info.m_hasLightmap)
{
lightmapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[%d], v.posIn).xy;\n", nextTCG++, nextMtx++);
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[%d], pos).xy;\n", nextTCG++, nextMtx++);
}
switch (info.m_type)

View File

@ -46,15 +46,16 @@ static const char* VS =
" constant FluidPlaneUniform& fu [[ buffer(2) ]])\n"
"{\n"
" VertToFrag vtf;\n"
" vtf.mvPos = fu.mv * float4(v.posIn.xyz, 1.0);\n"
" float4 pos = float4(v.posIn.xyz, 1.0);\n"
" vtf.mvPos = fu.mv * pos;\n"
" vtf.pos = fu.proj * vtf.mvPos;\n"
" vtf.mvNorm = fu.mvNorm * v.normalIn;\n"
" vtf.mvBinorm = fu.mvNorm * v.binormalIn;\n"
" vtf.mvTangent = fu.mvNorm * v.tangentIn;\n"
" vtf.color = v.colorIn;\n"
" vtf.uv0 = (fu.texMtxs[0] * v.posIn).xy;\n"
" vtf.uv1 = (fu.texMtxs[1] * v.posIn).xy;\n"
" vtf.uv2 = (fu.texMtxs[2] * v.posIn).xy;\n"
" vtf.uv0 = (fu.texMtxs[0] * pos).xy;\n"
" vtf.uv1 = (fu.texMtxs[1] * pos).xy;\n"
" vtf.uv2 = (fu.texMtxs[2] * pos).xy;\n"
"%s" // Additional TCGs here
" return vtf;\n"
"}\n";
@ -237,22 +238,22 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
if (info.m_hasBumpMap)
{
bumpMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[0] * v.posIn).xy;\n", nextTCG++);
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[0] * pos).xy;\n", nextTCG++);
}
if (info.m_hasEnvBumpMap)
{
envBumpMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[3] * v.posIn).xy;\n", nextTCG++);
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[3] * float4(normalize(v.normalIn.xyz), 1.0)).xy;\n", nextTCG++);
}
if (info.m_hasEnvMap)
{
envMapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[%d] * v.posIn).xy;\n", nextTCG++, nextMtx++);
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
}
if (info.m_hasLightmap)
{
lightmapUv = nextTCG;
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[%d] * v.posIn).xy;\n", nextTCG++, nextMtx++);
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
}
switch (info.m_type)

View File

@ -14,7 +14,7 @@ namespace urde
const CTargetReticleRenderState CTargetReticleRenderState::skZeroRenderState(kInvalidUniqueId, 1.f,
zeus::CVector3f::skZero, 0.f, 1.f, true);
static float offshoot_func(float f1, float f2, float f3) { return (f1 * 0.5f) + zeus::fastSinF((f3 - 0.5f) * f2); }
static float offshoot_func(float f1, float f2, float f3) { return (f1 * 0.5f) + std::sin((f3 - 0.5f) * f2); }
static float calculate_premultiplied_overshoot_offset(float f1) { return 2.f * (M_PIF - std::asin(1.f / f1)); }

View File

@ -63,9 +63,9 @@ bool CVEAngleSphere::GetValue(int frame, zeus::CVector3f& pPos, zeus::CVector3f&
d = zeus::degToRad(d + ((0.5f * (f * rand->Float())) - f));
e = zeus::degToRad(e + ((0.5f * (g * rand->Float())) - g));
float cosD = zeus::fastCosF(d);
pPos.x = a.x + (b * (-zeus::fastSinF(e) * cosD));
pPos.y = a.y + (b * zeus::fastSinF(d));
float cosD = std::cos(d);
pPos.x = a.x + (b * (-std::sin(e) * cosD));
pPos.y = a.y + (b * std::sin(d));
pPos.z = a.z + (b * (cosD * cosD));
zeus::CVector3f normVec = (pPos - a).normalized();

View File

@ -198,7 +198,8 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
pttScale = g_tweakGame->GetFluidEnvBumpScale() * x4c_uvMotion.GetFluidLayers()[0].GetUVScale();
// Load GX_TEXMTX3 with identity
nextTexMtx++;
zeus::CMatrix4f& texMtx = out.texMtxs[nextTexMtx++];
texMtx[0][0] = texMtx[1][1] = pttScale;
// Load GX_PTTEXMTX0 with scale of pttScale
// Next: GX_TG_MTX2x4 GX_TG_NRM, GX_TEXMTX3, true, GX_PTTEXMTX0
@ -1080,6 +1081,7 @@ void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
int xTileStart = info.x28_tileX + info.x2e_tileY * info.x2a_gridDimX;
yMax = yMin;
for (int curYTile=yTiles ; curYTile>0 ; --curYTile,
yMax += info.x14_tileSize, xTileStart += info.x2a_gridDimX)
{

View File

@ -29,8 +29,8 @@ CFluidUVMotion::CFluidUVMotion(float timeToWrap, float orientation)
void CFluidUVMotion::CalculateFluidTextureOffset(float t, float offsets[3][2]) const
{
float totalYOffset = (t * x4c_ooTimeToWrap) * zeus::fastCosF(x50_orientation);
float totalXOffset = (t * x4c_ooTimeToWrap) * zeus::fastSinF(x50_orientation);
float totalYOffset = t * x4c_ooTimeToWrap * std::cos(x50_orientation);
float totalXOffset = t * x4c_ooTimeToWrap * std::sin(x50_orientation);
for (u32 i = 0 ; i<x0_fluidLayers.size() ; ++i)
{
@ -42,17 +42,23 @@ void CFluidUVMotion::CalculateFluidTextureOffset(float t, float offsets[3][2]) c
float localX;
switch(layer.x0_motion)
{
case EFluidUVMotion::One:
case EFluidUVMotion::Linear:
{
float angle = (M_PIF * 2) * cycleT;
localY = layer.xc_magnitude * zeus::fastSinF(angle);
localX = layer.xc_magnitude * zeus::fastCosF(angle);
localX = speedT;
localY = 0.f;
}
break;
case EFluidUVMotion::Two:
case EFluidUVMotion::Circular:
{
float angle = (M_PIF * 2) * cycleT;
localY = layer.xc_magnitude * std::sin(angle);
localX = layer.xc_magnitude * std::cos(angle);
}
break;
case EFluidUVMotion::Oscillate:
{
localY = 0.f;
localX = layer.xc_magnitude * zeus::fastCosF((M_PIF * 2) * cycleT);
localX = layer.xc_magnitude * std::cos((M_PIF * 2) * cycleT);
}
break;
default:
@ -60,10 +66,10 @@ void CFluidUVMotion::CalculateFluidTextureOffset(float t, float offsets[3][2]) c
break;
}
float x = localX * zeus::fastSinF(layer.x8_orientation) +
localY * zeus::fastCosF(layer.x8_orientation) + totalXOffset;
float y = localY * zeus::fastSinF(layer.x8_orientation) +
localX * zeus::fastCosF(layer.x8_orientation) + totalYOffset;
float x = localX * std::sin(layer.x8_orientation) +
localY * std::cos(layer.x8_orientation) + totalXOffset;
float y = localY * std::sin(layer.x8_orientation) +
localX * std::cos(layer.x8_orientation) + totalYOffset;
offsets[i][0] = x - std::floor(x);
offsets[i][1] = y - std::floor(y);

View File

@ -11,14 +11,14 @@ class CFluidUVMotion
public:
enum class EFluidUVMotion
{
Zero,
One,
Two,
Linear,
Circular,
Oscillate,
};
struct SFluidLayerMotion
{
EFluidUVMotion x0_motion = EFluidUVMotion::Zero;
EFluidUVMotion x0_motion = EFluidUVMotion::Linear;
float x4_ooTimeToWrap = 0.16666667f;
float x8_orientation = 0.f;
float xc_magnitude = 1.f;

View File

@ -8,6 +8,7 @@
#include "CStateManager.hpp"
#include "IMain.hpp"
#include "CPlayer.hpp"
#include "hecl/CVarManager.hpp"
namespace urde
{
@ -456,11 +457,9 @@ void CScriptSpecialFunction::ThinkPlayerInArea(float, CStateManager &)
bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& stateMgr) const
{
#ifndef NDEBUG
return true;
#else
if (hecl::com_developer->toBoolean())
return true;
return g_GameState->SystemOptions().GetCinematicState(stateMgr.GetWorld()->IGetWorldAssetId(), GetEditorId());
#endif
}
void CScriptSpecialFunction::DeleteEmitter(const CSfxHandle& handle)

View File

@ -271,6 +271,11 @@ void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr)
}
}
void CScriptWater::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptWater::Think(float dt, CStateManager& mgr)
{
if (!x30_24_active)
@ -450,9 +455,7 @@ void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, const CState
{
if (!xe4_30_outOfFrustum)
{
zeus::CPlane plane;
plane.vec = x34_transform.origin.normalized();
plane.d = x34_transform.origin.z + x130_bounds.max.z;
zeus::CPlane plane(zeus::CVector3f::skUp, x34_transform.origin.z + x130_bounds.max.z);
zeus::CAABox renderBounds = GetSortingBounds(mgr);
mgr.AddDrawableActorPlane(*this, plane, renderBounds);
}
@ -568,7 +571,7 @@ float CScriptWater::GetSplashEffectScale(float dt) const
return kSplashScales[5];
u32 idx = GetSplashIndex(dt);
float s = dt - zeus::floorF(dt * 3.f);
float s = dt - std::floor(dt * 3.f);
return ((1.f - s) * (s * kSplashScales[idx * 2])) + kSplashScales[idx];
}

View File

@ -95,6 +95,7 @@ public:
const zeus::CColor& fogColor, CAssetId lightmapId, float unitsPerLightmapTexel, float alphaInTime,
float alphaOutTime, u32, u32, bool, s32, s32, std::unique_ptr<u32[]>&& u32Arr);
void Accept(IVisitor& visitor);
void Think(float, CStateManager&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void PreRender(CStateManager &, const zeus::CFrustum &);

@ -1 +1 @@
Subproject commit 5881cd0368e43a4a5c3f2e9164593852c364422e
Subproject commit cc9d7c8b46cdb2a5f0389cd4f513146ef4624f66