mirror of https://github.com/AxioDL/metaforce.git
Implement CFluidPlaneGPU for GPU-computed water ripples
This commit is contained in:
parent
e63102e180
commit
ac424ff9eb
|
@ -62,7 +62,7 @@ struct Water : IScriptObject
|
|||
Value<float> turbulenceAmplitudeMax;
|
||||
Value<float> turbulenceAmplitudeMin;
|
||||
Value<atVec4f> splashColor;
|
||||
Value<atVec4f> unkColor;
|
||||
Value<atVec4f> insideFogColor;
|
||||
UniqueID32 splashParticle1;
|
||||
UniqueID32 splashParticle2;
|
||||
UniqueID32 splashParticle3;
|
||||
|
|
|
@ -590,12 +590,12 @@ void CCameraManager::UpdateFog(float dt, CStateManager& mgr)
|
|||
{
|
||||
zeus::CVector2f zRange(GetCurrentCamera(mgr)->GetNearClipDistance(),
|
||||
CalculateFogDensity(mgr, water.GetPtr()));
|
||||
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, water->GetFogColor(), zRange);
|
||||
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, water->GetInsideFogColor(), zRange);
|
||||
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal)
|
||||
mgr.GetCameraFilterPass(4).DisableFilter(0.f);
|
||||
else
|
||||
mgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply, EFilterShape::Fullscreen,
|
||||
0.f, water->GetFogColor(), {});
|
||||
0.f, water->GetInsideFogColor(), {});
|
||||
}
|
||||
xa0_26_inWater = true;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "CFluidPlaneShader.hpp"
|
||||
#include "World/CRipple.hpp"
|
||||
#include "World/CRippleManager.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -11,9 +13,9 @@ u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info)
|
|||
|
||||
switch (info.m_type)
|
||||
{
|
||||
case CFluidPlane::EFluidType::NormalWater:
|
||||
case CFluidPlane::EFluidType::PhazonFluid:
|
||||
case CFluidPlane::EFluidType::Four:
|
||||
case EFluidType::NormalWater:
|
||||
case EFluidType::PhazonFluid:
|
||||
case EFluidType::Four:
|
||||
if (info.m_hasLightmap)
|
||||
{
|
||||
ret |= 1 << 2;
|
||||
|
@ -29,7 +31,7 @@ u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info)
|
|||
|
||||
break;
|
||||
|
||||
case CFluidPlane::EFluidType::PoisonWater:
|
||||
case EFluidType::PoisonWater:
|
||||
ret |= 1;
|
||||
|
||||
if (info.m_hasLightmap)
|
||||
|
@ -44,7 +46,7 @@ u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info)
|
|||
|
||||
break;
|
||||
|
||||
case CFluidPlane::EFluidType::Lava:
|
||||
case EFluidType::Lava:
|
||||
ret |= 2;
|
||||
|
||||
if (info.m_hasBumpMap)
|
||||
|
@ -52,7 +54,7 @@ u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info)
|
|||
|
||||
break;
|
||||
|
||||
case CFluidPlane::EFluidType::ThickLava:
|
||||
case EFluidType::ThickLava:
|
||||
ret |= 3;
|
||||
|
||||
if (info.m_hasBumpMap)
|
||||
|
@ -89,15 +91,15 @@ u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneDoorShaderInfo& info
|
|||
}
|
||||
|
||||
template<class T>
|
||||
boo::ObjToken<boo::IShaderPipeline> CFluidPlaneShader::Cache::GetOrBuildShader(const T& info)
|
||||
CFluidPlaneShader::ShaderPair CFluidPlaneShader::Cache::GetOrBuildShader(const T& info)
|
||||
{
|
||||
u16 key = MakeCacheKey(info);
|
||||
auto& slot = CacheSlot(info, key);
|
||||
if (slot)
|
||||
if (slot.m_regular)
|
||||
return slot;
|
||||
|
||||
if (CGraphics::g_BooFactory == nullptr)
|
||||
return nullptr;
|
||||
return {};
|
||||
|
||||
CGraphics::CommitResources(
|
||||
[&](boo::IGraphicsDataFactory::Context& ctx)
|
||||
|
@ -132,9 +134,9 @@ boo::ObjToken<boo::IShaderPipeline> CFluidPlaneShader::Cache::GetOrBuildShader(c
|
|||
return slot;
|
||||
}
|
||||
|
||||
template boo::ObjToken<boo::IShaderPipeline>
|
||||
template CFluidPlaneShader::ShaderPair
|
||||
CFluidPlaneShader::Cache::GetOrBuildShader<SFluidPlaneShaderInfo>(const SFluidPlaneShaderInfo& info);
|
||||
template boo::ObjToken<boo::IShaderPipeline>
|
||||
template CFluidPlaneShader::ShaderPair
|
||||
CFluidPlaneShader::Cache::GetOrBuildShader<SFluidPlaneDoorShaderInfo>(const SFluidPlaneDoorShaderInfo& info);
|
||||
|
||||
void CFluidPlaneShader::Cache::Clear()
|
||||
|
@ -145,34 +147,36 @@ void CFluidPlaneShader::Cache::Clear()
|
|||
p.reset();
|
||||
}
|
||||
|
||||
void CFluidPlaneShader::PrepareBinding(const boo::ObjToken<boo::IShaderPipeline>& pipeline, u32 maxVertCount, bool door)
|
||||
void CFluidPlaneShader::PrepareBinding(const ShaderPair& pipeline, u32 maxVertCount)
|
||||
{
|
||||
CGraphics::CommitResources(
|
||||
[&](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount);
|
||||
if (pipeline.m_tessellation)
|
||||
m_pvbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(PatchVertex), maxVertCount);
|
||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
||||
|
||||
switch (ctx.platform())
|
||||
{
|
||||
#if BOO_HAS_GL
|
||||
case boo::IGraphicsDataFactory::Platform::OpenGL:
|
||||
m_dataBind = BuildBinding(static_cast<boo::GLDataFactory::Context&>(ctx), pipeline, door);
|
||||
m_dataBind = BuildBinding(static_cast<boo::GLDataFactory::Context&>(ctx), pipeline);
|
||||
break;
|
||||
#endif
|
||||
#if _WIN32
|
||||
case boo::IGraphicsDataFactory::Platform::D3D11:
|
||||
m_dataBind = BuildBinding(static_cast<boo::D3DDataFactory::Context&>(ctx), pipeline, door);
|
||||
m_dataBind = BuildBinding(static_cast<boo::D3DDataFactory::Context&>(ctx), pipeline);
|
||||
break;
|
||||
#endif
|
||||
#if BOO_HAS_METAL
|
||||
case boo::IGraphicsDataFactory::Platform::Metal:
|
||||
m_dataBind = BuildBinding(static_cast<boo::MetalDataFactory::Context&>(ctx), pipeline, door);
|
||||
m_dataBind = BuildBinding(static_cast<boo::MetalDataFactory::Context&>(ctx), pipeline);
|
||||
break;
|
||||
#endif
|
||||
#if BOO_HAS_VULKAN
|
||||
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
||||
m_dataBind = BuildBinding(static_cast<boo::VulkanDataFactory::Context&>(ctx), pipeline, door);
|
||||
m_dataBind = BuildBinding(static_cast<boo::VulkanDataFactory::Context&>(ctx), pipeline);
|
||||
break;
|
||||
#endif
|
||||
default: break;
|
||||
|
@ -210,14 +214,15 @@ void CFluidPlaneShader::Shutdown()
|
|||
}
|
||||
}
|
||||
|
||||
CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& colorTex,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& bumpMap,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& envMap,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
|
||||
CFluidPlaneShader::CFluidPlaneShader(EFluidType type,
|
||||
const TLockedToken<CTexture>& patternTex1,
|
||||
const TLockedToken<CTexture>& patternTex2,
|
||||
const TLockedToken<CTexture>& colorTex,
|
||||
const TLockedToken<CTexture>& bumpMap,
|
||||
const TLockedToken<CTexture>& envMap,
|
||||
const TLockedToken<CTexture>& envBumpMap,
|
||||
const TLockedToken<CTexture>& lightmap,
|
||||
const boo::ObjToken<boo::ITextureS>& rippleMap,
|
||||
bool doubleLightmapBlend, bool additive, u32 maxVertCount)
|
||||
: m_patternTex1(patternTex1),
|
||||
m_patternTex2(patternTex2),
|
||||
|
@ -225,7 +230,8 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
|||
m_bumpMap(bumpMap),
|
||||
m_envMap(envMap),
|
||||
m_envBumpMap(envBumpMap),
|
||||
m_lightmap(lightmap)
|
||||
m_lightmap(lightmap),
|
||||
m_rippleMap(rippleMap)
|
||||
{
|
||||
SFluidPlaneShaderInfo shaderInfo(type,
|
||||
m_patternTex1.operator bool(),
|
||||
|
@ -235,14 +241,15 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
|||
m_envMap.operator bool(),
|
||||
m_envBumpMap.operator bool(),
|
||||
m_lightmap.operator bool(),
|
||||
m_rippleMap.operator bool(),
|
||||
doubleLightmapBlend, additive);
|
||||
boo::ObjToken<boo::IShaderPipeline> pipeline = _cache.GetOrBuildShader(shaderInfo);
|
||||
PrepareBinding(pipeline, maxVertCount, false);
|
||||
ShaderPair pipeline = _cache.GetOrBuildShader(shaderInfo);
|
||||
PrepareBinding(pipeline, maxVertCount);
|
||||
}
|
||||
|
||||
CFluidPlaneShader::CFluidPlaneShader(const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& colorTex,
|
||||
CFluidPlaneShader::CFluidPlaneShader(const TLockedToken<CTexture>& patternTex1,
|
||||
const TLockedToken<CTexture>& patternTex2,
|
||||
const TLockedToken<CTexture>& colorTex,
|
||||
u32 maxVertCount)
|
||||
: m_patternTex1(patternTex1),
|
||||
m_patternTex2(patternTex2),
|
||||
|
@ -251,8 +258,8 @@ CFluidPlaneShader::CFluidPlaneShader(const std::experimental::optional<TLockedTo
|
|||
SFluidPlaneDoorShaderInfo shaderInfo(m_patternTex1.operator bool(),
|
||||
m_patternTex2.operator bool(),
|
||||
m_colorTex.operator bool());
|
||||
boo::ObjToken<boo::IShaderPipeline> pipeline = _cache.GetOrBuildShader(shaderInfo);
|
||||
PrepareBinding(pipeline, maxVertCount, true);
|
||||
ShaderPair pipeline = _cache.GetOrBuildShader(shaderInfo);
|
||||
PrepareBinding(pipeline, maxVertCount);
|
||||
}
|
||||
|
||||
void CFluidPlaneShader::prepareDraw(const RenderSetupInfo& info)
|
||||
|
@ -269,12 +276,56 @@ void CFluidPlaneShader::prepareDraw(const RenderSetupInfo& info)
|
|||
uni.m_lighting.mulColor = info.kColors[3];
|
||||
uni.m_lighting.fog.m_rangeScale = info.indScale;
|
||||
m_uniBuf->unmap();
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
}
|
||||
|
||||
void CFluidPlaneShader::loadVerts(const std::vector<Vertex>& verts)
|
||||
void CFluidPlaneShader::prepareDraw(const RenderSetupInfo& info,
|
||||
const zeus::CVector3f& waterCenter,
|
||||
const CRippleManager& rippleManager,
|
||||
const zeus::CColor& colorMul,
|
||||
float rippleNormResolution)
|
||||
{
|
||||
Uniform& uni = *reinterpret_cast<Uniform*>(m_uniBuf->map(sizeof(Uniform)));
|
||||
uni.m_mv = CGraphics::g_GXModelView.toMatrix4f();
|
||||
uni.m_mvNorm = info.normMtx;
|
||||
uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true);
|
||||
for (int i=0 ; i<6 ; ++i)
|
||||
uni.m_texMtxs[i] = info.texMtxs[i];
|
||||
int i = 0;
|
||||
for (const CRipple& ripple : rippleManager.GetRipples())
|
||||
{
|
||||
assert(i < 20 && "Too many ripples");
|
||||
Ripple& rOut = uni.m_ripple[i++];
|
||||
if (ripple.GetTime() >= ripple.GetTimeFalloff())
|
||||
{
|
||||
rOut.center.zeroOut();
|
||||
rOut.params.zeroOut();
|
||||
continue;
|
||||
}
|
||||
zeus::CVector3f localPos = ripple.GetCenter() - waterCenter;
|
||||
rOut.center.x = localPos.x;
|
||||
rOut.center.y = localPos.y;
|
||||
rOut.center.z = ripple.GetTime() * ripple.GetOOTimeFalloff();
|
||||
rOut.center.w = ripple.GetOODistanceFalloff();
|
||||
rOut.params.x = ripple.GetAmplitude();
|
||||
rOut.params.y = ripple.GetPhase();
|
||||
rOut.params.z = (1.f - ripple.GetTime() * ripple.GetOOTimeFalloff() *
|
||||
ripple.GetOOTimeFalloff()) * ripple.GetFrequency();
|
||||
}
|
||||
uni.m_colorMul = colorMul;
|
||||
uni.m_pad[0].x = rippleNormResolution;
|
||||
uni.m_lighting.ActivateLights(info.lights);
|
||||
for (i=0 ; i<3 ; ++i)
|
||||
uni.m_lighting.colorRegs[i] = info.kColors[i];
|
||||
uni.m_lighting.mulColor = info.kColors[3];
|
||||
uni.m_lighting.fog.m_rangeScale = info.indScale;
|
||||
m_uniBuf->unmap();
|
||||
}
|
||||
|
||||
void CFluidPlaneShader::loadVerts(const std::vector<Vertex>& verts, const std::vector<PatchVertex>& pVerts)
|
||||
{
|
||||
m_vbo->load(verts.data(), verts.size() * sizeof(Vertex));
|
||||
if (m_pvbo)
|
||||
m_pvbo->load(pVerts.data(), pVerts.size() * sizeof(PatchVertex));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,19 +3,22 @@
|
|||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
#include "Runtime/World/CFluidPlane.hpp"
|
||||
#include "CModelShaders.hpp"
|
||||
#include "boo/graphicsdev/GL.hpp"
|
||||
#include "boo/graphicsdev/D3D.hpp"
|
||||
#include "boo/graphicsdev/Metal.hpp"
|
||||
#include "boo/graphicsdev/Vulkan.hpp"
|
||||
#include "World/CFluidPlaneManager.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
#include "CToken.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
struct SFluidPlaneShaderInfo
|
||||
{
|
||||
CFluidPlane::EFluidType m_type;
|
||||
EFluidType m_type;
|
||||
bool m_hasPatternTex1;
|
||||
bool m_hasPatternTex2;
|
||||
bool m_hasColorTex;
|
||||
|
@ -23,15 +26,16 @@ struct SFluidPlaneShaderInfo
|
|||
bool m_hasEnvMap;
|
||||
bool m_hasEnvBumpMap;
|
||||
bool m_hasLightmap;
|
||||
bool m_tessellation;
|
||||
bool m_doubleLightmapBlend;
|
||||
bool m_additive;
|
||||
|
||||
SFluidPlaneShaderInfo(CFluidPlane::EFluidType type, bool hasPatternTex1, bool hasPatternTex2, bool hasColorTex,
|
||||
SFluidPlaneShaderInfo(EFluidType type, bool hasPatternTex1, bool hasPatternTex2, bool hasColorTex,
|
||||
bool hasBumpMap, bool hasEnvMap, bool hasEnvBumpMap, bool hasLightmap,
|
||||
bool doubleLightmapBlend, bool additive)
|
||||
bool tessellation, bool doubleLightmapBlend, bool additive)
|
||||
: m_type(type), m_hasPatternTex1(hasPatternTex1), m_hasPatternTex2(hasPatternTex2), m_hasColorTex(hasColorTex),
|
||||
m_hasBumpMap(hasBumpMap), m_hasEnvMap(hasEnvMap), m_hasEnvBumpMap(hasEnvBumpMap), m_hasLightmap(hasLightmap),
|
||||
m_doubleLightmapBlend(doubleLightmapBlend), m_additive(additive)
|
||||
m_tessellation(tessellation), m_doubleLightmapBlend(doubleLightmapBlend), m_additive(additive)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -70,6 +74,13 @@ public:
|
|||
: m_pos(position), m_norm(normal), m_binorm(binormal), m_tangent(tangent), m_color(color) {}
|
||||
};
|
||||
|
||||
struct PatchVertex
|
||||
{
|
||||
zeus::CVector4f m_pos;
|
||||
float m_outerLevels[4] = {};
|
||||
float m_innerLevels[4] = {};
|
||||
};
|
||||
|
||||
struct RenderSetupInfo
|
||||
{
|
||||
zeus::CMatrix4f texMtxs[6];
|
||||
|
@ -80,96 +91,145 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
struct ShaderPair
|
||||
{
|
||||
boo::ObjToken<boo::IShaderPipeline> m_regular;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_tessellation;
|
||||
void reset()
|
||||
{
|
||||
m_regular.reset();
|
||||
m_tessellation.reset();
|
||||
}
|
||||
};
|
||||
|
||||
struct BindingPair
|
||||
{
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_regular;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_tessellation;
|
||||
};
|
||||
|
||||
class Cache
|
||||
{
|
||||
boo::ObjToken<boo::IShaderPipeline> m_cache[1024] = {};
|
||||
boo::ObjToken<boo::IShaderPipeline> m_doorCache[8] = {};
|
||||
boo::ObjToken<boo::IShaderPipeline>&
|
||||
ShaderPair m_cache[1024] = {};
|
||||
ShaderPair m_doorCache[8] = {};
|
||||
ShaderPair&
|
||||
CacheSlot(const SFluidPlaneShaderInfo& info, int i) { return m_cache[i]; }
|
||||
boo::ObjToken<boo::IShaderPipeline>&
|
||||
ShaderPair&
|
||||
CacheSlot(const SFluidPlaneDoorShaderInfo& info, int i) { return m_doorCache[i]; }
|
||||
static u16 MakeCacheKey(const SFluidPlaneShaderInfo& info);
|
||||
static u16 MakeCacheKey(const SFluidPlaneDoorShaderInfo& info);
|
||||
public:
|
||||
template<class T>
|
||||
boo::ObjToken<boo::IShaderPipeline> GetOrBuildShader(const T& info);
|
||||
ShaderPair GetOrBuildShader(const T& info);
|
||||
void Clear();
|
||||
};
|
||||
static Cache _cache;
|
||||
|
||||
struct Ripple
|
||||
{
|
||||
zeus::CVector4f center; // time, distFalloff
|
||||
zeus::CVector4f params; // amplitude, lookupPhase, lookupTime
|
||||
};
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CMatrix4f m_mvNorm;
|
||||
zeus::CMatrix4f m_proj;
|
||||
zeus::CMatrix4f m_texMtxs[9]; // Pad out to 768 bytes
|
||||
zeus::CMatrix4f m_texMtxs[6];
|
||||
Ripple m_ripple[20];
|
||||
zeus::CVector4f m_colorMul;
|
||||
zeus::CVector4f m_pad[3]; // rippleNormResolution, Pad out to 1280 bytes
|
||||
CModelShaders::LightingUniform m_lighting;
|
||||
zeus::CVector3f m_pad; // Pad out to 768 bytes
|
||||
zeus::CVector3f m_pad2; // Pad out to 768 bytes
|
||||
};
|
||||
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_patternTex1;
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_patternTex2;
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_colorTex;
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_bumpMap;
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_envMap;
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_envBumpMap;
|
||||
std::experimental::optional<TLockedToken<CTexture>> m_lightmap;
|
||||
TLockedToken<CTexture> m_patternTex1;
|
||||
TLockedToken<CTexture> m_patternTex2;
|
||||
TLockedToken<CTexture> m_colorTex;
|
||||
TLockedToken<CTexture> m_bumpMap;
|
||||
TLockedToken<CTexture> m_envMap;
|
||||
TLockedToken<CTexture> m_envBumpMap;
|
||||
TLockedToken<CTexture> m_lightmap;
|
||||
boo::ObjToken<boo::ITextureS> m_rippleMap;
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_vbo;
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_pvbo;
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_uniBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_dataBind;
|
||||
BindingPair m_dataBind;
|
||||
int m_lastBind = -1;
|
||||
|
||||
#if BOO_HAS_GL
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::GLDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::GLDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
boo::ObjToken<boo::IShaderDataBinding> BuildBinding(boo::GLDataFactory::Context& ctx,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& pipeline, bool door);
|
||||
static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
BindingPair BuildBinding(boo::GLDataFactory::Context& ctx, const ShaderPair& pipeline);
|
||||
#endif
|
||||
#if _WIN32
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::D3DDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::D3DDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
boo::ObjToken<boo::IShaderDataBinding> BuildBinding(boo::D3DDataFactory::Context& ctx,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& pipeline, bool door);
|
||||
static ShaderPair BuildShader(boo::D3DDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static ShaderPair BuildShader(boo::D3DDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
BindingPair BuildBinding(boo::D3DDataFactory::Context& ctx, const ShaderPair& pipeline);
|
||||
#endif
|
||||
#if BOO_HAS_METAL
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::MetalDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::MetalDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
boo::ObjToken<boo::IShaderDataBinding> BuildBinding(boo::MetalDataFactory::Context& ctx,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& pipeline, bool door);
|
||||
static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
BindingPair BuildBinding(boo::MetalDataFactory::Context& ctx, const ShaderPair& pipeline);
|
||||
#endif
|
||||
#if BOO_HAS_VULKAN
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::VulkanDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static boo::ObjToken<boo::IShaderPipeline> BuildShader(boo::VulkanDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
boo::ObjToken<boo::IShaderDataBinding> BuildBinding(boo::VulkanDataFactory::Context& ctx,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& pipeline, bool door);
|
||||
static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info);
|
||||
static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx,
|
||||
const SFluidPlaneDoorShaderInfo& info);
|
||||
BindingPair BuildBinding(boo::VulkanDataFactory::Context& ctx, const ShaderPair& pipeline);
|
||||
#endif
|
||||
|
||||
template <class F> static void _Shutdown();
|
||||
|
||||
void PrepareBinding(const boo::ObjToken<boo::IShaderPipeline>& pipeline, u32 maxVertCount, bool door);
|
||||
void PrepareBinding(const ShaderPair& pipeline, u32 maxVertCount);
|
||||
public:
|
||||
CFluidPlaneShader(CFluidPlane::EFluidType type,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& colorTex,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& bumpMap,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& envMap,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
|
||||
CFluidPlaneShader(EFluidType type,
|
||||
const TLockedToken<CTexture>& patternTex1,
|
||||
const TLockedToken<CTexture>& patternTex2,
|
||||
const TLockedToken<CTexture>& colorTex,
|
||||
const TLockedToken<CTexture>& bumpMap,
|
||||
const TLockedToken<CTexture>& envMap,
|
||||
const TLockedToken<CTexture>& envBumpMap,
|
||||
const TLockedToken<CTexture>& lightmap,
|
||||
const boo::ObjToken<boo::ITextureS>& rippleMap,
|
||||
bool doubleLightmapBlend, bool additive, u32 maxVertCount);
|
||||
CFluidPlaneShader(const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||
const std::experimental::optional<TLockedToken<CTexture>>& colorTex,
|
||||
CFluidPlaneShader(const TLockedToken<CTexture>& patternTex1,
|
||||
const TLockedToken<CTexture>& patternTex2,
|
||||
const TLockedToken<CTexture>& colorTex,
|
||||
u32 maxVertCount);
|
||||
void prepareDraw(const RenderSetupInfo& info);
|
||||
void loadVerts(const std::vector<Vertex>& verts);
|
||||
void prepareDraw(const RenderSetupInfo& info,
|
||||
const zeus::CVector3f& waterCenter,
|
||||
const CRippleManager& rippleManager,
|
||||
const zeus::CColor& colorMul,
|
||||
float rippleNormResolution);
|
||||
void bindRegular()
|
||||
{
|
||||
if (m_lastBind != 0)
|
||||
{
|
||||
CGraphics::SetShaderDataBinding(m_dataBind.m_regular);
|
||||
m_lastBind = 0;
|
||||
}
|
||||
}
|
||||
bool bindTessellation()
|
||||
{
|
||||
if (m_lastBind != 1)
|
||||
{
|
||||
CGraphics::SetShaderDataBinding(m_dataBind.m_tessellation);
|
||||
m_lastBind = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void doneDrawing() { m_lastBind = -1; }
|
||||
void loadVerts(const std::vector<Vertex>& verts, const std::vector<PatchVertex>& pVerts);
|
||||
|
||||
static void Shutdown();
|
||||
};
|
||||
|
|
|
@ -39,13 +39,145 @@ BOO_GLSL_BINDING_HEAD
|
|||
" vtf.mvNorm = mvNorm * normalIn;\n"
|
||||
" vtf.mvBinorm = mvNorm * binormalIn;\n"
|
||||
" vtf.mvTangent = mvNorm * tangentIn;\n"
|
||||
" vtf.color = colorIn;\n"
|
||||
" vtf.color = vec4(colorIn.xyz, 1.0);\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";
|
||||
|
||||
static const char* TessVS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"\n"
|
||||
"layout(location=0) in vec4 posIn;\n"
|
||||
"layout(location=1) in vec4 outerLevelsIn;\n"
|
||||
"layout(location=2) in vec2 innerLevelsIn;\n"
|
||||
"\n"
|
||||
"struct VertToControl\n"
|
||||
"{\n"
|
||||
" vec4 minMaxPos;\n"
|
||||
" vec4 outerLevels;\n"
|
||||
" vec2 innerLevels;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) out VertToControl vtc;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vtc.minMaxPos = posIn;\n"
|
||||
" vtc.outerLevels = outerLevelsIn;\n"
|
||||
" vtc.innerLevels = innerLevelsIn;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* TessCS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"#extension GL_ARB_tessellation_shader: enable\n"
|
||||
"layout(vertices = 1) out;\n"
|
||||
"\n"
|
||||
"struct VertToControl\n"
|
||||
"{\n"
|
||||
" vec4 minMaxPos;\n"
|
||||
" vec4 outerLevels;\n"
|
||||
" vec2 innerLevels;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToControl vtc[];\n"
|
||||
"SBINDING(0) patch out vec4 minMaxPos;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" minMaxPos = vtc[gl_InvocationID].minMaxPos;\n"
|
||||
" for (int i=0 ; i<4 ; ++i)\n"
|
||||
" gl_TessLevelOuter[i] = vtc[gl_InvocationID].outerLevels[i];\n"
|
||||
" for (int i=0 ; i<2 ; ++i)\n"
|
||||
" gl_TessLevelInner[i] = vtc[gl_InvocationID].innerLevels[i];\n"
|
||||
"}";
|
||||
|
||||
static const char* TessES =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"#extension GL_ARB_tessellation_shader: enable\n"
|
||||
"layout(quads, equal_spacing) in;\n"
|
||||
"\n"
|
||||
"struct Ripple\n"
|
||||
"{\n"
|
||||
" vec4 center; // time, distFalloff\n"
|
||||
" vec4 params; // amplitude, lookupPhase, lookupTime\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"UBINDING0 uniform FluidPlaneUniform\n"
|
||||
"{\n"
|
||||
" mat4 mv;\n"
|
||||
" mat4 mvNorm;\n"
|
||||
" mat4 proj;\n"
|
||||
" mat4 texMtxs[6];\n"
|
||||
" Ripple ripples[20];\n"
|
||||
" vec4 colorMul;\n"
|
||||
" float rippleNormResolution;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 mvPos;\n"
|
||||
" vec4 mvNorm;\n"
|
||||
" vec4 mvBinorm;\n"
|
||||
" vec4 mvTangent;\n"
|
||||
" vec4 color;\n"
|
||||
" vec2 uvs[7];\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) patch in vec4 minMaxPos;\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"\n"
|
||||
"TBINDING%d uniform sampler2D RippleMap;\n"
|
||||
"\n"
|
||||
"const float PI_X2 = 6.283185307179586;\n"
|
||||
"\n"
|
||||
"void ApplyRipple(in Ripple ripple, in vec2 pos, inout float height)\n"
|
||||
"{\n"
|
||||
" float dist = length(ripple.center.xy - pos);\n"
|
||||
" float rippleV = texture(RippleMap, vec2(dist * ripple.center.w, ripple.center.z)).r;\n"
|
||||
" height += rippleV * ripple.params.x * sin((dist * ripple.params.y + ripple.params.z) * PI_X2);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 posIn = vec2(mix(minMaxPos.x, minMaxPos.z, gl_TessCoord.x),\n"
|
||||
" mix(minMaxPos.y, minMaxPos.w, gl_TessCoord.y));\n"
|
||||
" float height = 0.0;\n"
|
||||
" float upHeight = 0.0;\n"
|
||||
" float downHeight = 0.0;\n"
|
||||
" float rightHeight = 0.0;\n"
|
||||
" float leftHeight = 0.0;\n"
|
||||
" for (int i=0 ; i<20 ; ++i)\n"
|
||||
" {\n"
|
||||
" ApplyRipple(ripples[i], posIn, height);\n"
|
||||
" ApplyRipple(ripples[i], posIn + vec2(0.0, rippleNormResolution), upHeight);\n"
|
||||
" ApplyRipple(ripples[i], posIn - vec2(0.0, rippleNormResolution), downHeight);\n"
|
||||
" ApplyRipple(ripples[i], posIn + vec2(rippleNormResolution, 0.0), rightHeight);\n"
|
||||
" ApplyRipple(ripples[i], posIn - vec2(rippleNormResolution, 0.0), leftHeight);\n"
|
||||
" }\n"
|
||||
" vec4 normalIn = vec4(normalize(vec3((leftHeight - rightHeight),\n"
|
||||
" (downHeight - upHeight),\n"
|
||||
" rippleNormResolution)), 1.0);\n"
|
||||
" vec4 binormalIn = vec4(normalIn.x, normalIn.z, -normalIn.y, 1.0);\n"
|
||||
" vec4 tangentIn = vec4(normalIn.z, normalIn.y, -normalIn.x, 1.0);\n"
|
||||
" vec4 pos = vec4(posIn, height, 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 = max(height, 0.0) * colorMul;\n"
|
||||
" vtf.color.a = 1.0;\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\n" // Additional TCGs here
|
||||
"}\n";
|
||||
|
||||
static const char* FS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
|
@ -60,7 +192,7 @@ BOO_GLSL_BINDING_HEAD
|
|||
"};\n"
|
||||
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" vec4 color;\n"
|
||||
" float indScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -77,13 +209,13 @@ BOO_GLSL_BINDING_HEAD
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vec4 LightingFunc(vec4 mvPosIn, vec4 mvNormIn)\n"
|
||||
"vec4 LightingFunc(vec3 mvPosIn, vec3 mvNormIn)\n"
|
||||
"{\n"
|
||||
" vec4 ret = ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" vec3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" vec3 delta = mvPosIn - 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"
|
||||
|
@ -92,10 +224,10 @@ BOO_GLSL_BINDING_HEAD
|
|||
" 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"
|
||||
" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn), 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"
|
||||
" return ret;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
|
@ -113,7 +245,7 @@ BOO_GLSL_BINDING_HEAD
|
|||
"%s" // Textures here
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec4 lighting = LightingFunc(vtf.mvPos, normalize(vtf.mvNorm));\n"
|
||||
" vec4 lighting = LightingFunc(vtf.mvPos.xyz, normalize(vtf.mvNorm.xyz));\n"
|
||||
"%s" // Combiner expression here
|
||||
"}\n";
|
||||
|
||||
|
@ -131,7 +263,7 @@ BOO_GLSL_BINDING_HEAD
|
|||
"};\n"
|
||||
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" vec4 color;\n"
|
||||
" float indScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -166,14 +298,12 @@ BOO_GLSL_BINDING_HEAD
|
|||
"%s" // Combiner expression here
|
||||
"}\n";
|
||||
|
||||
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[7],
|
||||
const SFluidPlaneShaderInfo& info)
|
||||
static void _BuildFragShader(std::string& finalFS, int& nextTex, const char* texNames[8],
|
||||
const SFluidPlaneShaderInfo& info)
|
||||
{
|
||||
std::string additionalTCGs;
|
||||
std::string textures;
|
||||
std::string combiner;
|
||||
int nextTCG = 3;
|
||||
int nextMtx = 4;
|
||||
int bumpMapUv, envBumpMapUv, envMapUv, lightmapUv;
|
||||
|
||||
if (info.m_hasPatternTex1)
|
||||
|
@ -214,30 +344,26 @@ 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] * pos).xy;\n", nextTCG++);
|
||||
bumpMapUv = nextTCG++;
|
||||
}
|
||||
if (info.m_hasEnvBumpMap)
|
||||
{
|
||||
envBumpMapUv = nextTCG;
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[3] * vec4(normalize(normalIn.xyz), 1.0)).xy;\n", nextTCG++);
|
||||
envBumpMapUv = nextTCG++;
|
||||
}
|
||||
if (info.m_hasEnvMap)
|
||||
{
|
||||
envMapUv = nextTCG;
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
|
||||
envMapUv = nextTCG++;
|
||||
}
|
||||
if (info.m_hasLightmap)
|
||||
{
|
||||
lightmapUv = nextTCG;
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
|
||||
}
|
||||
|
||||
switch (info.m_type)
|
||||
{
|
||||
case CFluidPlane::EFluidType::NormalWater:
|
||||
case CFluidPlane::EFluidType::PhazonFluid:
|
||||
case CFluidPlane::EFluidType::Four:
|
||||
case EFluidType::NormalWater:
|
||||
case EFluidType::PhazonFluid:
|
||||
case EFluidType::Four:
|
||||
if (info.m_hasLightmap)
|
||||
{
|
||||
combiner += hecl::Format(" vec4 lightMapTexel = texture(lightMap, vtf.uvs[%d]);\n", lightmapUv);
|
||||
|
@ -293,7 +419,7 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
{
|
||||
// Make previous stage indirect, mtx0
|
||||
combiner += hecl::Format(" vec2 indUvs = (texture(envBumpMap, vtf.uvs[%d]).ra - vec2(0.5, 0.5)) *\n"
|
||||
" vec2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||
" vec2(fog.indScale, -fog.indScale);\n", envBumpMapUv);
|
||||
combiner += " colorOut += texture(colorTex, indUvs + vtf.uvs[2]) * lighting;\n";
|
||||
}
|
||||
else if (info.m_hasEnvMap)
|
||||
|
@ -307,8 +433,8 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
if (info.m_hasColorTex)
|
||||
combiner += " colorOut += texture(colorTex, vtf.uvs[2]) * lighting;\n";
|
||||
combiner += hecl::Format(" vec2 indUvs = (texture(envBumpMap, vtf.uvs[%d]).ra - vec2(0.5, 0.5)) *\n"
|
||||
" vec2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||
combiner += hecl::Format(" colorOut = mix(colorOut, texture(envMap, indUvs + vtf.uvs[%d]), kColor1);\n",
|
||||
" vec2(fog.indScale, -fog.indScale);\n", envBumpMapUv);
|
||||
combiner += hecl::Format(" colorOut = mix(colorOut, texture(envMap, indUvs + vtf.uvs[%d]), kColor1);\n",
|
||||
envMapUv);
|
||||
}
|
||||
else if (info.m_hasColorTex)
|
||||
|
@ -318,7 +444,7 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
|
||||
break;
|
||||
|
||||
case CFluidPlane::EFluidType::PoisonWater:
|
||||
case EFluidType::PoisonWater:
|
||||
if (info.m_hasLightmap)
|
||||
{
|
||||
combiner += hecl::Format(" vec4 lightMapTexel = texture(lightMap, vtf.uvs[%d]);\n", lightmapUv);
|
||||
|
@ -375,7 +501,7 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
{
|
||||
// Make previous stage indirect, mtx0
|
||||
combiner += hecl::Format(" vec2 indUvs = (texture(envBumpMap, vtf.uvs[%d]).ra - vec2(0.5, 0.5)) *\n"
|
||||
" vec2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||
" vec2(fog.indScale, -fog.indScale);\n", envBumpMapUv);
|
||||
combiner += " colorOut += texture(colorTex, indUvs + vtf.uvs[2]) * lighting;\n";
|
||||
}
|
||||
else
|
||||
|
@ -386,7 +512,7 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
|
||||
break;
|
||||
|
||||
case CFluidPlane::EFluidType::Lava:
|
||||
case EFluidType::Lava:
|
||||
// 0: Tex0TCG, Tex0, GX_COLOR0A0
|
||||
// ZERO, TEX, KONST, RAS
|
||||
// Output reg prev
|
||||
|
@ -444,7 +570,7 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
|
||||
break;
|
||||
|
||||
case CFluidPlane::EFluidType::ThickLava:
|
||||
case EFluidType::ThickLava:
|
||||
// 0: Tex0TCG, Tex0, GX_COLOR0A0
|
||||
// ZERO, TEX, KONST, RAS
|
||||
// Output reg prev
|
||||
|
@ -489,17 +615,66 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
|
||||
combiner += " colorOut.a = kColor0.a;\n";
|
||||
|
||||
char *finalVSs, *finalFSs;
|
||||
asprintf(&finalVSs, VS, additionalTCGs.c_str());
|
||||
char *finalFSs;
|
||||
asprintf(&finalFSs, FS, textures.c_str(), combiner.c_str());
|
||||
|
||||
finalVS = finalVSs;
|
||||
finalFS = finalFSs;
|
||||
|
||||
free(finalVSs);
|
||||
free(finalFSs);
|
||||
}
|
||||
|
||||
static std::string _BuildAdditionalTCGs(const SFluidPlaneShaderInfo& info)
|
||||
{
|
||||
std::string additionalTCGs;
|
||||
int nextTCG = 3;
|
||||
int nextMtx = 4;
|
||||
|
||||
if (info.m_hasBumpMap)
|
||||
{
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[0] * pos).xy;\n", nextTCG++);
|
||||
}
|
||||
if (info.m_hasEnvBumpMap)
|
||||
{
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[3] * vec4(normalIn.xyz, 1.0)).xy;\n", nextTCG++);
|
||||
}
|
||||
if (info.m_hasEnvMap)
|
||||
{
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * pos).xy;\n", nextTCG++, nextMtx++);
|
||||
}
|
||||
if (info.m_hasLightmap)
|
||||
{
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = (texMtxs[%d] * pos).xy;\n", nextTCG, nextMtx);
|
||||
}
|
||||
|
||||
return additionalTCGs;
|
||||
}
|
||||
|
||||
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[8],
|
||||
const SFluidPlaneShaderInfo& info)
|
||||
{
|
||||
std::string additionalTCGs = _BuildAdditionalTCGs(info);
|
||||
|
||||
char *finalVSs;
|
||||
asprintf(&finalVSs, VS, additionalTCGs.c_str());
|
||||
finalVS = finalVSs;
|
||||
free(finalVSs);
|
||||
|
||||
_BuildFragShader(finalFS, nextTex, texNames, info);
|
||||
}
|
||||
|
||||
static void _BuildTessellationShader(std::string& finalTessES, int& nextTex, const char* texNames[8],
|
||||
const SFluidPlaneShaderInfo& info)
|
||||
{
|
||||
std::string additionalTCGs = _BuildAdditionalTCGs(info);
|
||||
|
||||
texNames[nextTex] = "RippleMap";
|
||||
|
||||
char *finalESs;
|
||||
asprintf(&finalESs, TessES, nextTex, additionalTCGs.c_str());
|
||||
finalTessES = finalESs;
|
||||
free(finalESs);
|
||||
|
||||
++nextTex;
|
||||
}
|
||||
|
||||
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[3],
|
||||
const SFluidPlaneDoorShaderInfo& info)
|
||||
{
|
||||
|
@ -552,22 +727,36 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
|||
free(finalFSs);
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline>
|
||||
CFluidPlaneShader::ShaderPair
|
||||
CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
||||
{
|
||||
int nextTex = 0;
|
||||
const char* texNames[7] = {};
|
||||
const char* texNames[8] = {};
|
||||
std::string finalVS, finalFS;
|
||||
_BuildShader(finalVS, finalFS, nextTex, texNames, info);
|
||||
const char* uniNames[] = {"FluidPlaneUniform", "FluidPlaneUniform", "LightingUniform"};
|
||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), size_t(nextTex), texNames, 3, uniNames,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
auto regular = ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(),
|
||||
size_t(nextTex), texNames, 3, uniNames,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
boo::ObjToken<boo::IShaderPipeline> tessellation;
|
||||
if (info.m_tessellation)
|
||||
{
|
||||
std::string finalTessES;
|
||||
_BuildTessellationShader(finalTessES, nextTex, texNames, info);
|
||||
tessellation = ctx.newTessellationShaderPipeline(
|
||||
TessVS, finalFS.c_str(), TessCS, finalTessES.c_str(),
|
||||
size_t(nextTex), texNames, 3, uniNames,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||
1, boo::ZTest::LEqual, false, true, false, boo::CullMode::None);
|
||||
}
|
||||
return {regular, tessellation};
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline>
|
||||
CFluidPlaneShader::ShaderPair
|
||||
CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info)
|
||||
{
|
||||
int nextTex = 0;
|
||||
|
@ -575,10 +764,10 @@ CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPla
|
|||
std::string finalVS, finalFS;
|
||||
_BuildShader(finalVS, finalFS, nextTex, texNames, info);
|
||||
const char* uniNames[] = {"FluidPlaneUniform", "FluidPlaneUniform", "LightingUniform"};
|
||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), size_t(nextTex), texNames, 3, uniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
return {ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), size_t(nextTex), texNames, 3, uniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None), {}};
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -586,9 +775,11 @@ void CFluidPlaneShader::_Shutdown<boo::GLDataFactory>() {}
|
|||
|
||||
#if BOO_HAS_VULKAN
|
||||
static boo::ObjToken<boo::IVertexFormat> s_vtxFmt;
|
||||
static boo::ObjToken<boo::IVertexFormat> s_vtxFmtTess;
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline>
|
||||
CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
||||
CFluidPlaneShader::ShaderPair
|
||||
CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx,
|
||||
const SFluidPlaneShaderInfo& info)
|
||||
{
|
||||
if (!s_vtxFmt)
|
||||
{
|
||||
|
@ -604,17 +795,40 @@ CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx, const SFlui
|
|||
}
|
||||
|
||||
int nextTex = 0;
|
||||
const char* texNames[7] = {};
|
||||
const char* texNames[8] = {};
|
||||
std::string finalVS, finalFS;
|
||||
_BuildShader(finalVS, finalFS, nextTex, texNames, info);
|
||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), s_vtxFmt,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
auto regular = ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), s_vtxFmt,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
boo::ObjToken<boo::IShaderPipeline> tessellation;
|
||||
if (info.m_tessellation)
|
||||
{
|
||||
if (!s_vtxFmtTess)
|
||||
{
|
||||
boo::VertexElementDescriptor elements[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 1}
|
||||
};
|
||||
s_vtxFmtTess = ctx.newVertexFormat(3, elements);
|
||||
}
|
||||
|
||||
std::string finalTessES;
|
||||
_BuildTessellationShader(finalTessES, nextTex, texNames, info);
|
||||
tessellation = ctx.newTessellationShaderPipeline(
|
||||
TessVS, finalFS.c_str(), TessCS, finalTessES.c_str(), s_vtxFmtTess,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::SrcAlpha,
|
||||
info.m_additive ? boo::BlendFactor::One : boo::BlendFactor::InvSrcAlpha,
|
||||
1, boo::ZTest::LEqual, false, true, false, boo::CullMode::None);
|
||||
}
|
||||
return {regular, tessellation};
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline>
|
||||
CFluidPlaneShader::ShaderPair
|
||||
CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info)
|
||||
{
|
||||
if (!s_vtxFmt)
|
||||
|
@ -634,23 +848,24 @@ CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx, const SFlui
|
|||
const char* texNames[3] = {};
|
||||
std::string finalVS, finalFS;
|
||||
_BuildShader(finalVS, finalFS, nextTex, texNames, info);
|
||||
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), s_vtxFmt,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
auto regular = ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), s_vtxFmt,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||
boo::CullMode::None);
|
||||
return {regular, {}};
|
||||
}
|
||||
|
||||
template <>
|
||||
void CFluidPlaneShader::_Shutdown<boo::VulkanDataFactory>()
|
||||
{
|
||||
s_vtxFmt.reset();
|
||||
s_vtxFmtTess.reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
boo::ObjToken<boo::IShaderDataBinding>
|
||||
CFluidPlaneShader::BuildBinding(boo::GLDataFactory::Context& ctx,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& pipeline, bool door)
|
||||
CFluidPlaneShader::BindingPair
|
||||
CFluidPlaneShader::BuildBinding(boo::GLDataFactory::Context& ctx, const ShaderPair& pipeline)
|
||||
{
|
||||
boo::VertexElementDescriptor elements[] =
|
||||
{
|
||||
|
@ -664,56 +879,79 @@ CFluidPlaneShader::BuildBinding(boo::GLDataFactory::Context& ctx,
|
|||
boo::ObjToken<boo::IGraphicsBuffer> ubufs[] = { m_uniBuf.get(), m_uniBuf.get(), m_uniBuf.get() };
|
||||
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
||||
boo::PipelineStage::Fragment };
|
||||
size_t ubufOffs[] = {0, 0, 768};
|
||||
size_t ubufSizes[] = {768, 768, sizeof(CModelShaders::LightingUniform)};
|
||||
size_t ubufOffs[] = {0, 0, 1280};
|
||||
size_t ubufSizes[] = {1280, 1280, sizeof(CModelShaders::LightingUniform)};
|
||||
size_t texCount = 0;
|
||||
boo::ObjToken<boo::ITexture> texs[7];
|
||||
if (m_patternTex1)
|
||||
texs[texCount++] = (*m_patternTex1)->GetBooTexture();
|
||||
texs[texCount++] = m_patternTex1->GetBooTexture();
|
||||
if (m_patternTex2)
|
||||
texs[texCount++] = (*m_patternTex2)->GetBooTexture();
|
||||
texs[texCount++] = m_patternTex2->GetBooTexture();
|
||||
if (m_colorTex)
|
||||
texs[texCount++] = (*m_colorTex)->GetBooTexture();
|
||||
texs[texCount++] = m_colorTex->GetBooTexture();
|
||||
if (m_bumpMap)
|
||||
texs[texCount++] = (*m_bumpMap)->GetBooTexture();
|
||||
texs[texCount++] = m_bumpMap->GetBooTexture();
|
||||
if (m_envMap)
|
||||
texs[texCount++] = (*m_envMap)->GetBooTexture();
|
||||
texs[texCount++] = m_envMap->GetBooTexture();
|
||||
if (m_envBumpMap)
|
||||
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
||||
texs[texCount++] = m_envBumpMap->GetBooTexture();
|
||||
if (m_lightmap)
|
||||
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
||||
return ctx.newShaderDataBinding(pipeline, vtxFmt, m_vbo.get(), nullptr, nullptr, 3,
|
||||
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||
texs[texCount++] = m_lightmap->GetBooTexture();
|
||||
auto regular = ctx.newShaderDataBinding(pipeline.m_regular, vtxFmt, m_vbo.get(), nullptr, nullptr, 3,
|
||||
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||
boo::ObjToken<boo::IShaderDataBinding> tessellation;
|
||||
if (pipeline.m_tessellation)
|
||||
{
|
||||
boo::VertexElementDescriptor tessElements[] =
|
||||
{
|
||||
{m_pvbo.get(), nullptr, boo::VertexSemantic::Position4},
|
||||
{m_pvbo.get(), nullptr, boo::VertexSemantic::UV4, 0},
|
||||
{m_pvbo.get(), nullptr, boo::VertexSemantic::UV4, 1}
|
||||
};
|
||||
boo::ObjToken<boo::IVertexFormat> vtxFmtTess = ctx.newVertexFormat(3, tessElements);
|
||||
|
||||
texs[texCount++] = m_rippleMap.get();
|
||||
tessellation = ctx.newShaderDataBinding(pipeline.m_tessellation, vtxFmtTess, m_pvbo.get(), nullptr, nullptr, 3,
|
||||
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||
}
|
||||
return {regular, tessellation};
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
boo::ObjToken<boo::IShaderDataBinding>
|
||||
CFluidPlaneShader::BuildBinding(boo::VulkanDataFactory::Context& ctx,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& pipeline, bool door)
|
||||
CFluidPlaneShader::BindingPair
|
||||
CFluidPlaneShader::BuildBinding(boo::VulkanDataFactory::Context& ctx, const ShaderPair& pipeline)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> ubufs[] = { m_uniBuf.get(), m_uniBuf.get(), m_uniBuf.get() };
|
||||
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
||||
boo::PipelineStage::Fragment };
|
||||
size_t ubufOffs[] = {0, 0, 768};
|
||||
size_t ubufSizes[] = {768, 768, sizeof(CModelShaders::LightingUniform)};
|
||||
size_t ubufOffs[] = {0, 0, 1280};
|
||||
size_t ubufSizes[] = {1280, 1280, sizeof(CModelShaders::LightingUniform)};
|
||||
size_t texCount = 0;
|
||||
boo::ObjToken<boo::ITexture> texs[7] = {};
|
||||
if (m_patternTex1)
|
||||
texs[texCount++] = (*m_patternTex1)->GetBooTexture();
|
||||
texs[texCount++] = m_patternTex1->GetBooTexture();
|
||||
if (m_patternTex2)
|
||||
texs[texCount++] = (*m_patternTex2)->GetBooTexture();
|
||||
texs[texCount++] = m_patternTex2->GetBooTexture();
|
||||
if (m_colorTex)
|
||||
texs[texCount++] = (*m_colorTex)->GetBooTexture();
|
||||
texs[texCount++] = m_colorTex->GetBooTexture();
|
||||
if (m_bumpMap)
|
||||
texs[texCount++] = (*m_bumpMap)->GetBooTexture();
|
||||
texs[texCount++] = m_bumpMap->GetBooTexture();
|
||||
if (m_envMap)
|
||||
texs[texCount++] = (*m_envMap)->GetBooTexture();
|
||||
texs[texCount++] = m_envMap->GetBooTexture();
|
||||
if (m_envBumpMap)
|
||||
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
||||
texs[texCount++] = m_envBumpMap->GetBooTexture();
|
||||
if (m_lightmap)
|
||||
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
||||
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo.get(), nullptr, nullptr, 3,
|
||||
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||
texs[texCount++] = m_lightmap->GetBooTexture();
|
||||
auto regular = ctx.newShaderDataBinding(pipeline.m_regular, s_vtxFmt, m_vbo.get(), nullptr, nullptr,
|
||||
3, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||
boo::ObjToken<boo::IShaderDataBinding> tessellation;
|
||||
if (pipeline.m_tessellation)
|
||||
{
|
||||
texs[texCount++] = m_rippleMap.get();
|
||||
tessellation = ctx.newShaderDataBinding(pipeline.m_tessellation, s_vtxFmtTess, m_pvbo.get(), nullptr, nullptr,
|
||||
3, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||
}
|
||||
return {regular, tessellation};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ static const char* FS =
|
|||
"};\n"
|
||||
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float indScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -79,13 +79,13 @@ static const char* FS =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static float4 LightingFunc(float4 mvPosIn, float4 mvNormIn)\n"
|
||||
"static float4 LightingFunc(float3 mvPosIn, float3 mvNormIn)\n"
|
||||
"{\n"
|
||||
" float4 ret = ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" float3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - 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"
|
||||
|
@ -94,10 +94,10 @@ static const char* FS =
|
|||
" 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"
|
||||
" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn), 0.0, 1.0);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return clamp(ret, float4(0.0,0.0,0.0,0.0), float4(1.0,1.0,1.0,1.0));\n"
|
||||
" return ret;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
|
@ -115,7 +115,7 @@ static const char* FS =
|
|||
"%s" // Textures here
|
||||
"float4 main(in VertToFrag vtf) : SV_Target0\n"
|
||||
"{\n"
|
||||
" float4 lighting = LightingFunc(vtf.mvPos, normalize(vtf.mvNorm));\n"
|
||||
" float4 lighting = LightingFunc(vtf.mvPos.xyz, normalize(vtf.mvNorm.xyz));\n"
|
||||
" float4 colorOut;\n"
|
||||
"%s" // Combiner expression here
|
||||
" return colorOut;\n"
|
||||
|
@ -132,7 +132,7 @@ static const char* FSDoor =
|
|||
"};\n"
|
||||
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float indScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -215,7 +215,7 @@ CFluidPlaneShader::BuildShader(boo::D3DDataFactory::Context& ctx, const SFluidPl
|
|||
if (info.m_hasEnvBumpMap)
|
||||
{
|
||||
envBumpMapUv = nextTCG;
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[3], float4(normalize(v.normalIn.xyz), 1.0)).xy;\n", nextTCG++);
|
||||
additionalTCGs += hecl::Format(" vtf.uvs[%d] = mul(texMtxs[3], float4(v.normalIn.xyz, 1.0)).xy;\n", nextTCG++);
|
||||
}
|
||||
if (info.m_hasEnvMap)
|
||||
{
|
||||
|
@ -288,7 +288,7 @@ CFluidPlaneShader::BuildShader(boo::D3DDataFactory::Context& ctx, const SFluidPl
|
|||
{
|
||||
// Make previous stage indirect, mtx0
|
||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
||||
" float2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||
" float2(fog.indScale, -fog.indScale);\n", envBumpMapUv);
|
||||
combiner += " colorOut += colorTex.Sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
||||
}
|
||||
else if (info.m_hasEnvMap)
|
||||
|
@ -302,7 +302,7 @@ CFluidPlaneShader::BuildShader(boo::D3DDataFactory::Context& ctx, const SFluidPl
|
|||
if (info.m_hasColorTex)
|
||||
combiner += " colorOut += colorTex.Sample(samp, vtf.uvs[2]) * lighting;\n";
|
||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
||||
" float2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||
" float2(fog.indScale, -fog.indScale);\n", envBumpMapUv);
|
||||
combiner += hecl::Format(" colorOut = mix(colorOut, envMap.Sample(samp, indUvs + vtf.uvs[%d]), kColor1);\n",
|
||||
envMapUv);
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ CFluidPlaneShader::BuildShader(boo::D3DDataFactory::Context& ctx, const SFluidPl
|
|||
{
|
||||
// Make previous stage indirect, mtx0
|
||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
||||
" float2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||
" float2(fog.indScale, -fog.indScale);\n", envBumpMapUv);
|
||||
combiner += " colorOut += colorTex.Sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
||||
}
|
||||
else
|
||||
|
|
|
@ -74,7 +74,7 @@ static const char* FS =
|
|||
"};\n"
|
||||
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float indScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -91,13 +91,13 @@ static const char* FS =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static float4 LightingFunc(float4 mvPosIn, float4 mvNormIn)\n"
|
||||
"static float4 LightingFunc(float3 mvPosIn, float3 mvNormIn)\n"
|
||||
"{\n"
|
||||
" float4 ret = ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" float3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - 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"
|
||||
|
@ -106,10 +106,10 @@ static const char* FS =
|
|||
" 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"
|
||||
" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn), 0.0, 1.0);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return clamp(ret, float4(0.0,0.0,0.0,0.0), float4(1.0,1.0,1.0,1.0));\n"
|
||||
" return ret;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
|
@ -133,7 +133,7 @@ static const char* FS =
|
|||
" sampler samp [[ sampler(0) ]],\n"
|
||||
" constant LightingUniform& lu [[ buffer(4) ]]%s)\n" // Textures here
|
||||
"{\n"
|
||||
" float4 lighting = LightingFunc(vtf.mvPos, normalize(vtf.mvNorm));\n"
|
||||
" float4 lighting = LightingFunc(vtf.mvPos.xyz, normalize(vtf.mvNorm.xyz));\n"
|
||||
" float4 colorOut;\n"
|
||||
"%s" // Combiner expression here
|
||||
" return colorOut;\n"
|
||||
|
@ -153,7 +153,7 @@ static const char* FSDoor =
|
|||
"};\n"
|
||||
"struct Fog\n" // Reappropriated for indirect texture scaling
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float indScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -243,7 +243,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
|||
if (info.m_hasEnvBumpMap)
|
||||
{
|
||||
envBumpMapUv = nextTCG;
|
||||
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[3] * float4(normalize(v.normalIn.xyz), 1.0)).xy;\n", nextTCG++);
|
||||
additionalTCGs += hecl::Format(" vtf.uv%d = (fu.texMtxs[3] * float4(v.normalIn.xyz, 1.0)).xy;\n", nextTCG++);
|
||||
}
|
||||
if (info.m_hasEnvMap)
|
||||
{
|
||||
|
@ -316,7 +316,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
|||
{
|
||||
// Make previous stage indirect, mtx0
|
||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uv%d).ra - float2(0.5, 0.5)) *\n"
|
||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
||||
" float2(lu.fog.indScale, -lu.fog.indScale);\n", envBumpMapUv);
|
||||
combiner += " colorOut += colorTex.sample(samp, indUvs + vtf.uv2) * lighting;\n";
|
||||
}
|
||||
else if (info.m_hasEnvMap)
|
||||
|
@ -330,7 +330,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
|||
if (info.m_hasColorTex)
|
||||
combiner += " colorOut += colorTex.sample(samp, vtf.uv2) * lighting;\n";
|
||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uv%d).ra - float2(0.5, 0.5)) *\n"
|
||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
||||
" float2(lu.fog.indScale, -lu.fog.indScale);\n", envBumpMapUv);
|
||||
combiner += hecl::Format(" colorOut = mix(colorOut, envMap.sample(samp, indUvs + vtf.uv%d), lu.kColor1);\n",
|
||||
envMapUv);
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
|||
{
|
||||
// Make previous stage indirect, mtx0
|
||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.sample(samp, vtf.uv%d).ra - float2(0.5, 0.5)) *\n"
|
||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
||||
" float2(lu.fog.indScale, -lu.fog.indScale);\n", envBumpMapUv);
|
||||
combiner += " colorOut += colorTex.sample(samp, indUvs + vtf.uv2) * lighting;\n";
|
||||
}
|
||||
else
|
||||
|
|
|
@ -15,7 +15,7 @@ static const char* LightingGLSL =
|
|||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" vec4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -32,13 +32,13 @@ static const char* LightingGLSL =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vec4 LightingFunc(vec4 mvPosIn, vec4 mvNormIn)\n"
|
||||
"vec4 LightingFunc(vec3 mvPosIn, vec3 mvNormIn)\n"
|
||||
"{\n"
|
||||
" vec4 ret = ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" vec3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" vec3 delta = mvPosIn - 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"
|
||||
|
@ -47,7 +47,7 @@ static const char* LightingGLSL =
|
|||
" 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"
|
||||
" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn), 0.0, 1.0);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return ret;\n"
|
||||
|
@ -64,7 +64,7 @@ static const char* LightingShadowGLSL =
|
|||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" vec4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -81,14 +81,14 @@ static const char* LightingShadowGLSL =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vec4 LightingShadowFunc(vec4 mvPosIn, vec4 mvNormIn)\n"
|
||||
"vec4 LightingShadowFunc(vec3 mvPosIn, vec3 mvNormIn)\n"
|
||||
"{\n"
|
||||
" vec2 shadowUV = vtf.extTcgs[0];\n"
|
||||
" shadowUV.y = 1.0 - shadowUV.y;\n"
|
||||
" \n"
|
||||
" vec4 ret = ambient;\n"
|
||||
" \n"
|
||||
" vec3 delta = mvPosIn.xyz - lights[0].pos.xyz;\n"
|
||||
" vec3 delta = mvPosIn - lights[0].pos.xyz;\n"
|
||||
" float dist = length(delta);\n"
|
||||
" float angDot = clamp(dot(normalize(delta), lights[0].dir.xyz), 0.0, 1.0);\n"
|
||||
" float att = 1.0 / (lights[0].linAtt[2] * dist * dist +\n"
|
||||
|
@ -97,12 +97,12 @@ static const char* LightingShadowGLSL =
|
|||
" float angAtt = lights[0].angAtt[2] * angDot * angDot +\n"
|
||||
" lights[0].angAtt[1] * angDot +\n"
|
||||
" lights[0].angAtt[0];\n"
|
||||
" ret += lights[0].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn.xyz), 0.0, 1.0) *\n"
|
||||
" ret += lights[0].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn), 0.0, 1.0) *\n"
|
||||
" texture(extTex7, shadowUV).r;\n"
|
||||
" \n"
|
||||
" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" vec3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" vec3 delta = mvPosIn - 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"
|
||||
|
@ -111,7 +111,7 @@ static const char* LightingShadowGLSL =
|
|||
" 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"
|
||||
" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * clamp(dot(normalize(-delta), mvNormIn), 0.0, 1.0);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return ret;\n"
|
||||
|
|
|
@ -14,7 +14,7 @@ static const char* LightingHLSL =
|
|||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -31,13 +31,13 @@ static const char* LightingHLSL =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static float4 LightingFunc(float4 mvPosIn, float4 mvNormIn, in VertToFrag vtf)\n"
|
||||
"static float4 LightingFunc(float3 mvPosIn, float3 mvNormIn, in VertToFrag vtf)\n"
|
||||
"{\n"
|
||||
" float4 ret = ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" float3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - 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"
|
||||
|
@ -46,7 +46,7 @@ static const char* LightingHLSL =
|
|||
" 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"
|
||||
" ret += lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return ret;\n"
|
||||
|
@ -63,7 +63,7 @@ static const char* LightingShadowHLSL =
|
|||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -80,11 +80,11 @@ static const char* LightingShadowHLSL =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static float4 LightingShadowFunc(float4 mvPosIn, float4 mvNormIn, in VertToFrag vtf)\n"
|
||||
"static float4 LightingShadowFunc(float3 mvPosIn, float3 mvNormIn, in VertToFrag vtf)\n"
|
||||
"{\n"
|
||||
" float4 ret = ambient;\n"
|
||||
" \n"
|
||||
" float3 delta = mvPosIn.xyz - lights[0].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - lights[0].pos.xyz;\n"
|
||||
" float dist = length(delta);\n"
|
||||
" float angDot = saturate(dot(normalize(delta), lights[0].dir.xyz));\n"
|
||||
" float att = 1.0 / (lights[0].linAtt[2] * dist * dist +\n"
|
||||
|
@ -93,12 +93,12 @@ static const char* LightingShadowHLSL =
|
|||
" float angAtt = lights[0].angAtt[2] * angDot * angDot +\n"
|
||||
" lights[0].angAtt[1] * angDot +\n"
|
||||
" lights[0].angAtt[0];\n"
|
||||
" ret += lights[0].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn.xyz)) *\n"
|
||||
" ret += lights[0].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn)) *\n"
|
||||
" extTex7.Sample(clampSamp, vtf.extTcgs[0]).r;\n"
|
||||
" \n"
|
||||
" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" float3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - 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"
|
||||
|
@ -107,7 +107,7 @@ static const char* LightingShadowHLSL =
|
|||
" 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"
|
||||
" ret += lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return ret;\n"
|
||||
|
|
|
@ -14,7 +14,7 @@ static const char* LightingMetal =
|
|||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -31,13 +31,13 @@ static const char* LightingMetal =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static float4 LightingFunc(constant LightingUniform& lu, float4 mvPosIn, float4 mvNormIn, thread VertToFrag& vtf)\n"
|
||||
"static float4 LightingFunc(constant LightingUniform& lu, float3 mvPosIn, float3 mvNormIn, thread VertToFrag& vtf)\n"
|
||||
"{\n"
|
||||
" float4 ret = lu.ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" float3 delta = mvPosIn.xyz - lu.lights[i].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - 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"
|
||||
|
@ -46,7 +46,7 @@ static const char* LightingMetal =
|
|||
" 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"
|
||||
" ret += lu.lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return ret;\n"
|
||||
|
@ -63,7 +63,7 @@ static const char* LightingShadowMetal =
|
|||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" uint mode;\n"
|
||||
" int mode;\n"
|
||||
" float4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
|
@ -80,12 +80,12 @@ static const char* LightingShadowMetal =
|
|||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static float4 EXTLightingShadowFunc(constant LightingUniform& lu, float4 mvPosIn, float4 mvNormIn,\n"
|
||||
"static float4 EXTLightingShadowFunc(constant LightingUniform& lu, float3 mvPosIn, float3 mvNormIn,\n"
|
||||
" thread VertToFrag& vtf, sampler samp, sampler clampSamp, texture2d<float> extTex7)\n"
|
||||
"{\n"
|
||||
" float4 ret = lu.ambient;\n"
|
||||
" \n"
|
||||
" float3 delta = mvPosIn.xyz - lu.lights[0].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - lu.lights[0].pos.xyz;\n"
|
||||
" float dist = length(delta);\n"
|
||||
" float angDot = saturate(dot(normalize(delta), lu.lights[0].dir.xyz));\n"
|
||||
" float att = 1.0 / (lu.lights[0].linAtt[2] * dist * dist +\n"
|
||||
|
@ -94,12 +94,12 @@ static const char* LightingShadowMetal =
|
|||
" float angAtt = lu.lights[0].angAtt[2] * angDot * angDot +\n"
|
||||
" lu.lights[0].angAtt[1] * angDot +\n"
|
||||
" lu.lights[0].angAtt[0];\n"
|
||||
" ret += lu.lights[0].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn.xyz)) *\n"
|
||||
" ret += lu.lights[0].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn)) *\n"
|
||||
" extTex7.sample(clampSamp, vtf.extTcgs0).r;\n"
|
||||
" \n"
|
||||
" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" float3 delta = mvPosIn.xyz - lu.lights[i].pos.xyz;\n"
|
||||
" float3 delta = mvPosIn - 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"
|
||||
|
@ -108,7 +108,7 @@ static const char* LightingShadowMetal =
|
|||
" 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"
|
||||
" ret += lu.lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return ret;\n"
|
||||
|
|
|
@ -783,6 +783,7 @@ void CMain::Shutdown()
|
|||
TMultiBlendShader<CScanLinesFilter>::Shutdown();
|
||||
TMultiBlendShader<CRandomStaticFilter>::Shutdown();
|
||||
CFluidPlaneShader::Shutdown();
|
||||
CFluidPlaneManager::RippleMapTex.reset();
|
||||
CNESShader::Shutdown();
|
||||
CGraphics::ShutdownBoo();
|
||||
ShutdownDiscord();
|
||||
|
|
|
@ -256,7 +256,7 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
|
|||
{
|
||||
if (TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(sender))
|
||||
{
|
||||
if (water->GetFluidPlane().GetFluidType() == CFluidPlane::EFluidType::PhazonFluid)
|
||||
if (water->GetFluidPlane().GetFluidType() == EFluidType::PhazonFluid)
|
||||
{
|
||||
x835_24_canFirePhazon = true;
|
||||
x835_25_inPhazonBeam = true;
|
||||
|
|
|
@ -14,11 +14,11 @@ CFluidPlane::CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId te
|
|||
x44_fluidType(fluidType), x48_rippleIntensity(rippleIntensity), x4c_uvMotion(motion)
|
||||
{
|
||||
if (g_ResFactory->GetResourceTypeById(texPattern1) == FOURCC('TXTR'))
|
||||
x10_texPattern1.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern1}));
|
||||
x10_texPattern1 = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern1});
|
||||
if (g_ResFactory->GetResourceTypeById(texPattern2) == FOURCC('TXTR'))
|
||||
x20_texPattern2.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern2}));
|
||||
x20_texPattern2 = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern2});
|
||||
if (g_ResFactory->GetResourceTypeById(texColor) == FOURCC('TXTR'))
|
||||
x30_texColor.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texColor}));
|
||||
x30_texColor = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texColor});
|
||||
}
|
||||
|
||||
float CFluidPlane::ProjectRippleVelocity(float baseI, float velDot) const
|
||||
|
@ -84,4 +84,495 @@ void CFluidPlane::AddRipple(const CRipple& ripple, const CScriptWater& water, CS
|
|||
return;
|
||||
mgr.GetFluidPlaneManager()->RippleManager().AddRipple(ripple);
|
||||
}
|
||||
|
||||
void CFluidPlane::RenderStripWithRipples(float curY,
|
||||
const CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], int startYDiv,
|
||||
const CFluidPlaneRender::SPatchInfo& info,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
||||
std::vector<CFluidPlaneShader::PatchVertex>& pvOut) const
|
||||
{
|
||||
m_shader->bindRegular();
|
||||
|
||||
int yTile = (startYDiv + CFluidPlaneRender::numSubdivisionsInTile - 1) /
|
||||
CFluidPlaneRender::numSubdivisionsInTile;
|
||||
int endXTile = (info.x0_xSubdivs + CFluidPlaneRender::numSubdivisionsInTile - 4) /
|
||||
CFluidPlaneRender::numSubdivisionsInTile;
|
||||
|
||||
int midDiv = CFluidPlaneRender::numSubdivisionsInTile / 2;
|
||||
float tileMid = info.x18_rippleResolution * midDiv;
|
||||
float yMin = curY;
|
||||
float yMid = curY + tileMid;
|
||||
|
||||
float curX = info.x4_localMin.x;
|
||||
int gridCell = info.x28_tileX + info.x2a_gridDimX * (info.x2e_tileY + yTile - 1);
|
||||
int xTile = 1;
|
||||
int tileSpan;
|
||||
for (int i = 1 ; i < info.x0_xSubdivs - 2 ;
|
||||
i += CFluidPlaneRender::numSubdivisionsInTile * tileSpan, gridCell += tileSpan,
|
||||
xTile += tileSpan, curX += info.x14_tileSize * tileSpan)
|
||||
{
|
||||
tileSpan = 1;
|
||||
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell])
|
||||
continue;
|
||||
|
||||
if ((flags[yTile][xTile] & 0x1f) == 0x1f)
|
||||
{
|
||||
for (; xTile+tileSpan<=endXTile ; ++tileSpan)
|
||||
{
|
||||
if ((flags[yTile][xTile+tileSpan] & 0x1f) != 0x1f)
|
||||
break;
|
||||
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell+tileSpan])
|
||||
break;
|
||||
}
|
||||
|
||||
int stripDivCount = tileSpan * CFluidPlaneRender::numSubdivisionsInTile + 1;
|
||||
int remSubdivs = CFluidPlaneRender::numSubdivisionsInTile;
|
||||
std::function<void(float x, float y, const CFluidPlaneRender::SHFieldSample& samp)> func;
|
||||
|
||||
switch (info.x37_normalMode)
|
||||
{
|
||||
case CFluidPlaneRender::NormalMode::None:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(x, y, samp.height));
|
||||
};
|
||||
break;
|
||||
case CFluidPlaneRender::NormalMode::NoNormals:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeColor(info));
|
||||
};
|
||||
break;
|
||||
case CFluidPlaneRender::NormalMode::Normals:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
|
||||
samp.MakeColor(info));
|
||||
};
|
||||
break;
|
||||
case CFluidPlaneRender::NormalMode::NBT:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
|
||||
samp.MakeBinormal(), samp.MakeTangent(), samp.MakeColor(info));
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
float curTileY = yMin;
|
||||
int curYDiv = startYDiv;
|
||||
for (; remSubdivs>0 ; --remSubdivs, ++curYDiv, curTileY+=info.x18_rippleResolution)
|
||||
{
|
||||
size_t start = vOut.size();
|
||||
float curTileX = curX;
|
||||
for (int v=0 ; v<stripDivCount ; ++v)
|
||||
{
|
||||
func(curTileX, curTileY, heights[curYDiv][i+v]);
|
||||
func(curTileX, curTileY + info.x18_rippleResolution, heights[curYDiv+1][i+v]);
|
||||
curTileX += info.x18_rippleResolution;
|
||||
}
|
||||
CGraphics::DrawArray(start, vOut.size() - start);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool r19 = (flags[yTile+1][xTile] & 0x2) != 0; // North
|
||||
bool r16 = (flags[yTile][xTile-1] & 0x8) != 0; // West
|
||||
bool r18 = (flags[yTile][xTile+1] & 0x4) != 0; // East
|
||||
bool r17 = (flags[yTile-1][xTile] & 0x1) != 0; // South
|
||||
|
||||
int r6 = (r19 ? CFluidPlaneRender::numSubdivisionsInTile : 1) + 2;
|
||||
r6 += r18 ? CFluidPlaneRender::numSubdivisionsInTile : 1;
|
||||
r6 += r17 ? CFluidPlaneRender::numSubdivisionsInTile : 1;
|
||||
r6 += r16 ? CFluidPlaneRender::numSubdivisionsInTile : 1;
|
||||
|
||||
if (r6 == 6 && (info.x37_normalMode == CFluidPlaneRender::NormalMode::Normals ||
|
||||
info.x37_normalMode == CFluidPlaneRender::NormalMode::NBT))
|
||||
{
|
||||
for (; xTile+tileSpan<=endXTile ; ++tileSpan)
|
||||
{
|
||||
if ((flags[yTile][xTile+tileSpan] & 0x1f) == 0x1f)
|
||||
break;
|
||||
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell+tileSpan])
|
||||
break;
|
||||
if ((flags[yTile+1][xTile+tileSpan] & 0x2) != 0x0)
|
||||
break;
|
||||
if ((flags[yTile][xTile+tileSpan+1] & 0x4) != 0x0)
|
||||
break;
|
||||
if ((flags[yTile-1][xTile+tileSpan] & 0x1) != 0x0)
|
||||
break;
|
||||
}
|
||||
|
||||
int stripDivCount = tileSpan + 1;
|
||||
size_t start = vOut.size();
|
||||
switch (info.x37_normalMode)
|
||||
{
|
||||
case CFluidPlaneRender::NormalMode::Normals:
|
||||
{
|
||||
int curYDiv0 = startYDiv;
|
||||
int curYDiv1 = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
|
||||
float curTileX = curX;
|
||||
for (int v=0 ; v<stripDivCount ; ++v)
|
||||
{
|
||||
int curXDiv = v * CFluidPlaneRender::numSubdivisionsInTile + i;
|
||||
const CFluidPlaneRender::SHFieldSample& samp0 = heights[curYDiv0][curXDiv];
|
||||
const CFluidPlaneRender::SHFieldSample& samp1 = heights[curYDiv1][curXDiv];
|
||||
vOut.emplace_back(zeus::CVector3f(curTileX, yMin, samp0.height),
|
||||
samp0.MakeNormal(), samp0.MakeColor(info));
|
||||
vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height),
|
||||
samp1.MakeNormal(), samp1.MakeColor(info));
|
||||
curTileX += info.x14_tileSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CFluidPlaneRender::NormalMode::NBT:
|
||||
{
|
||||
int curYDiv0 = startYDiv;
|
||||
int curYDiv1 = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
|
||||
float curTileX = curX;
|
||||
for (int v=0 ; v<stripDivCount ; ++v)
|
||||
{
|
||||
int curXDiv = v * CFluidPlaneRender::numSubdivisionsInTile + i;
|
||||
const CFluidPlaneRender::SHFieldSample& samp0 = heights[curYDiv0][curXDiv];
|
||||
const CFluidPlaneRender::SHFieldSample& samp1 = heights[curYDiv1][curXDiv];
|
||||
vOut.emplace_back(zeus::CVector3f(curTileX, yMin, samp0.height),
|
||||
samp0.MakeNormal(), samp0.MakeBinormal(), samp0.MakeTangent(),
|
||||
samp0.MakeColor(info));
|
||||
vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height),
|
||||
samp1.MakeNormal(), samp1.MakeBinormal(), samp1.MakeTangent(),
|
||||
samp1.MakeColor(info));
|
||||
curTileX += info.x14_tileSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CGraphics::DrawArray(start, vOut.size() - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
TriFanToStrip<CFluidPlaneShader::Vertex> toStrip(vOut);
|
||||
std::function<void(float x, float y, const CFluidPlaneRender::SHFieldSample& samp)> func;
|
||||
|
||||
switch (info.x37_normalMode)
|
||||
{
|
||||
case CFluidPlaneRender::NormalMode::None:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height));
|
||||
};
|
||||
break;
|
||||
case CFluidPlaneRender::NormalMode::NoNormals:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeColor(info));
|
||||
};
|
||||
break;
|
||||
case CFluidPlaneRender::NormalMode::Normals:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
|
||||
samp.MakeColor(info));
|
||||
};
|
||||
break;
|
||||
case CFluidPlaneRender::NormalMode::NBT:
|
||||
func = [&](float x, float y, const CFluidPlaneRender::SHFieldSample& samp)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
|
||||
samp.MakeBinormal(), samp.MakeTangent(), samp.MakeColor(info));
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
func(tileMid + curX, yMid, heights[startYDiv+midDiv][i+midDiv]);
|
||||
|
||||
int curXDiv = i;
|
||||
int curYDiv = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
|
||||
float curTileX = curX;
|
||||
float curTileY = yMin + info.x14_tileSize;
|
||||
for (int v=0 ; v<(r19 ? CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv][curXDiv+v];
|
||||
func(curTileX, curTileY, samp);
|
||||
curTileX += info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
curXDiv = i + CFluidPlaneRender::numSubdivisionsInTile;
|
||||
curYDiv = startYDiv + CFluidPlaneRender::numSubdivisionsInTile;
|
||||
curTileX = curX + info.x14_tileSize;
|
||||
curTileY = yMin + info.x14_tileSize;
|
||||
for (int v=0 ; v<(r18 ? CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv-v][curXDiv];
|
||||
func(curTileX, curTileY, samp);
|
||||
curTileY -= info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
curXDiv = i + CFluidPlaneRender::numSubdivisionsInTile;
|
||||
curYDiv = startYDiv;
|
||||
curTileX = curX + info.x14_tileSize;
|
||||
curTileY = yMin;
|
||||
for (int v=0 ; v<(r17 ? CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv][curXDiv-v];
|
||||
func(curTileX, curTileY, samp);
|
||||
curTileX -= info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
curXDiv = i;
|
||||
curYDiv = startYDiv;
|
||||
curTileX = curX;
|
||||
curTileY = yMin;
|
||||
if (r16)
|
||||
{
|
||||
for (int v=0 ; v<CFluidPlaneRender::numSubdivisionsInTile+1 ; ++v)
|
||||
{
|
||||
const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv+v][curXDiv];
|
||||
func(curTileX, curTileY, samp);
|
||||
curTileY += info.x18_rippleResolution;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
const CFluidPlaneRender::SHFieldSample& samp = heights[curYDiv][curXDiv];
|
||||
func(curTileX, curTileY, samp);
|
||||
}
|
||||
curTileY += info.x14_tileSize;
|
||||
{
|
||||
const CFluidPlaneRender::SHFieldSample& samp =
|
||||
heights[curYDiv+CFluidPlaneRender::numSubdivisionsInTile][curXDiv];
|
||||
func(curTileX, curTileY, samp);
|
||||
}
|
||||
}
|
||||
|
||||
toStrip.Draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFluidPlane::RenderPatch(const CFluidPlaneRender::SPatchInfo& info,
|
||||
const CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
||||
std::vector<CFluidPlaneShader::PatchVertex>& pvOut) const
|
||||
{
|
||||
if (noRipples)
|
||||
{
|
||||
m_shader->bindRegular();
|
||||
|
||||
float xMin = info.x4_localMin.x;
|
||||
float yMin = info.x4_localMin.y;
|
||||
float xMax = info.x18_rippleResolution * (info.x0_xSubdivs - 2) + xMin;
|
||||
float yMax = info.x18_rippleResolution * (info.x1_ySubdivs - 2) + yMin;
|
||||
|
||||
switch (info.x37_normalMode)
|
||||
{
|
||||
case CFluidPlaneRender::NormalMode::None:
|
||||
{
|
||||
size_t start = vOut.size();
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f));
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f));
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f));
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f));
|
||||
CGraphics::DrawArray(start, 4);
|
||||
break;
|
||||
}
|
||||
case CFluidPlaneRender::NormalMode::NoNormals:
|
||||
{
|
||||
size_t start = vOut.size();
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack);
|
||||
CGraphics::DrawArray(start, 4);
|
||||
break;
|
||||
}
|
||||
case CFluidPlaneRender::NormalMode::Normals:
|
||||
{
|
||||
int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
|
||||
int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneRender::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)
|
||||
{
|
||||
xMax = xMin;
|
||||
int nextXTile;
|
||||
for (int curXTile=0 ; curXTile<xTiles ; curXTile=nextXTile)
|
||||
{
|
||||
if (!info.x30_gridFlags || info.x30_gridFlags[xTileStart+curXTile])
|
||||
{
|
||||
if (curYTile == yTiles || curYTile == 1 || curXTile == 0 || xTiles - 1 == curXTile)
|
||||
{
|
||||
TriFanToStrip<CFluidPlaneShader::Vertex> toStrip(vOut);
|
||||
|
||||
toStrip.EmplaceVert(zeus::CVector3f(xMax + 0.5f * info.x14_tileSize,
|
||||
yMax + 0.5f * info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
|
||||
float tmp = xMax;
|
||||
for (int v=0 ; v<((curYTile == 1) ?
|
||||
CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp += info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
tmp = yMax + info.x14_tileSize;
|
||||
for (int v=0 ; v<((xTiles - 1 == curXTile) ?
|
||||
CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp -= info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
tmp = xMax + info.x14_tileSize;
|
||||
for (int v=0 ; v<((curYTile == yTiles) ?
|
||||
CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp -= info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
tmp = yMax;
|
||||
for (int v=0 ; v<((curXTile == 0) ?
|
||||
CFluidPlaneRender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
toStrip.EmplaceVert(zeus::CVector3f(xMax, tmp, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp += info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
toStrip.EmplaceVert(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
|
||||
toStrip.Draw();
|
||||
|
||||
nextXTile = curXTile + 1;
|
||||
xMax += info.x14_tileSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
while (nextXTile < xTiles - 1 &&
|
||||
(!info.x30_gridFlags || info.x30_gridFlags[xTileStart+nextXTile]))
|
||||
++nextXTile;
|
||||
|
||||
size_t start = vOut.size();
|
||||
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
xMax += info.x14_tileSize;
|
||||
}
|
||||
CGraphics::DrawArray(start, vOut.size() - start);
|
||||
|
||||
++nextXTile;
|
||||
if (nextXTile == xTiles)
|
||||
{
|
||||
--nextXTile;
|
||||
xMax -= info.x14_tileSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
xMax += info.x14_tileSize;
|
||||
while (nextXTile < xTiles && !info.x30_gridFlags[xTileStart+nextXTile])
|
||||
{
|
||||
xMax += info.x14_tileSize;
|
||||
++nextXTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CFluidPlaneRender::NormalMode::NBT:
|
||||
{
|
||||
if (flagIs1 || !info.x30_gridFlags)
|
||||
{
|
||||
size_t start = vOut.size();
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
CGraphics::DrawArray(start, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
|
||||
int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneRender::numSubdivisionsInTile + 1;
|
||||
int xTileStart = info.x28_tileX + info.x2e_tileY * info.x2a_gridDimX;
|
||||
for (; yTiles>0 ; --yTiles, yMin += info.x14_tileSize, xTileStart += info.x2a_gridDimX)
|
||||
{
|
||||
xMax = xMin;
|
||||
int nextXTile;
|
||||
for (int curXTile=0 ; curXTile<xTiles ; curXTile=nextXTile)
|
||||
{
|
||||
if (info.x30_gridFlags[xTileStart+curXTile])
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
int tile = xTileStart + nextXTile;
|
||||
while (nextXTile < xTiles && info.x30_gridFlags[tile])
|
||||
{
|
||||
++nextXTile;
|
||||
++tile;
|
||||
}
|
||||
|
||||
size_t start = vOut.size();
|
||||
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight,
|
||||
zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CVector3f::skForward,
|
||||
zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
xMax += info.x14_tileSize;
|
||||
}
|
||||
CGraphics::DrawArray(start, vOut.size() - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
xMax += info.x14_tileSize;
|
||||
int tile = xTileStart + nextXTile;
|
||||
while (nextXTile < xTiles && !info.x30_gridFlags[tile])
|
||||
{
|
||||
xMax += info.x14_tileSize;
|
||||
++nextXTile;
|
||||
++tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float curY = info.x4_localMin.y;
|
||||
for (int startYDiv=1 ; startYDiv<info.x1_ySubdivs-2 ;
|
||||
startYDiv += CFluidPlaneRender::numSubdivisionsInTile, curY += info.x14_tileSize)
|
||||
RenderStripWithRipples(curY, heights, flags, startYDiv, info, vOut, pvOut);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "CFluidUVMotion.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
#include "zeus/CFrustum.hpp"
|
||||
#include "Graphics/Shaders/CFluidPlaneShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -15,33 +16,145 @@ class CRippleManager;
|
|||
class CScriptWater;
|
||||
class CStateManager;
|
||||
class CRipple;
|
||||
class CFluidPlane
|
||||
|
||||
class CFluidPlaneRender
|
||||
{
|
||||
public:
|
||||
enum class EFluidType
|
||||
enum class NormalMode
|
||||
{
|
||||
NormalWater,
|
||||
PoisonWater,
|
||||
Lava,
|
||||
PhazonFluid,
|
||||
Four,
|
||||
ThickLava
|
||||
None,
|
||||
NoNormals,
|
||||
Normals,
|
||||
NBT
|
||||
};
|
||||
|
||||
static int numTilesInHField;
|
||||
static int numSubdivisionsInTile;
|
||||
static int numSubdivisionsInHField;
|
||||
|
||||
struct SPatchInfo
|
||||
{
|
||||
u8 x0_xSubdivs, x1_ySubdivs;
|
||||
zeus::CVector2f x4_localMin, xc_globalMin;
|
||||
float x14_tileSize;
|
||||
float x18_rippleResolution;
|
||||
float x1c_tileHypRadius;
|
||||
float x20_ooTileSize;
|
||||
float x24_ooRippleResolution;
|
||||
u16 x28_tileX;
|
||||
u16 x2a_gridDimX;
|
||||
u16 x2c_gridDimY;
|
||||
u16 x2e_tileY;
|
||||
const bool* x30_gridFlags;
|
||||
u8 x34_redShift;
|
||||
u8 x35_greenShift;
|
||||
u8 x36_blueShift;
|
||||
NormalMode x37_normalMode;
|
||||
float x38_wavecapIntensityScale;
|
||||
public:
|
||||
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
||||
float rippleResolution, float tileSize, float wavecapIntensityScale, int numSubdivisionsInHField,
|
||||
NormalMode normalMode, int redShift, int greenShift, int blueShift, u32 tileX, u32 gridDimX,
|
||||
u32 gridDimY, u32 tileY, const bool* gridFlags)
|
||||
{
|
||||
x0_xSubdivs = std::min(s16((localMax.x - localMin.x) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||
numSubdivisionsInHField + 2);
|
||||
x1_ySubdivs = std::min(s16((localMax.y - localMin.y) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||
numSubdivisionsInHField + 2);
|
||||
float tileHypRadius = tileSize * tileSize * 2 * 0.25f;
|
||||
x4_localMin.x = localMin.x;
|
||||
x4_localMin.y = localMin.y;
|
||||
xc_globalMin = x4_localMin + zeus::CVector2f(pos.x, pos.y);
|
||||
x14_tileSize = tileSize;
|
||||
x18_rippleResolution = rippleResolution;
|
||||
if (tileHypRadius != 0.f)
|
||||
tileHypRadius = std::sqrt(tileHypRadius);
|
||||
x1c_tileHypRadius = tileHypRadius;
|
||||
x20_ooTileSize = 1.f / x14_tileSize;
|
||||
x24_ooRippleResolution = 1.f / x18_rippleResolution;
|
||||
x28_tileX = u16(tileX);
|
||||
x2a_gridDimX = u16(gridDimX);
|
||||
x2c_gridDimY = u16(gridDimY);
|
||||
x2e_tileY = u16(tileY);
|
||||
x30_gridFlags = gridFlags;
|
||||
x34_redShift = u8(redShift);
|
||||
x35_greenShift = u8(greenShift);
|
||||
x36_blueShift = u8(blueShift);
|
||||
x37_normalMode = normalMode;
|
||||
x38_wavecapIntensityScale = wavecapIntensityScale;
|
||||
}
|
||||
};
|
||||
|
||||
struct SRippleInfo
|
||||
{
|
||||
const CRipple& x0_ripple;
|
||||
int x4_fromX;
|
||||
int x8_toX;
|
||||
int xc_fromY;
|
||||
int x10_toY;
|
||||
int x14_gfromX;
|
||||
int x18_gtoX;
|
||||
int x1c_gfromY;
|
||||
int x20_gtoY;
|
||||
public:
|
||||
SRippleInfo(const CRipple& ripple, int fromX, int toX, int fromY, int toY)
|
||||
: x0_ripple(ripple), x14_gfromX(fromX), x18_gtoX(toX), x1c_gfromY(fromY), x20_gtoY(toY) {}
|
||||
};
|
||||
|
||||
struct SHFieldSample
|
||||
{
|
||||
float height;
|
||||
s8 nx;
|
||||
s8 ny;
|
||||
s8 nz;
|
||||
u8 wavecapIntensity;
|
||||
|
||||
zeus::CVector3f MakeNormal() const { return zeus::CVector3f{nx / 63.f, ny / 63.f, nz / 63.f}.normalized(); }
|
||||
zeus::CVector3f MakeBinormal() const { return zeus::CVector3f{nx / 63.f, nz / 63.f, -ny / 63.f}.normalized(); }
|
||||
zeus::CVector3f MakeTangent() const { return zeus::CVector3f{nz / 63.f, ny / 63.f, -nx / 63.f}.normalized(); }
|
||||
zeus::CColor MakeColor(const CFluidPlaneRender::SPatchInfo& info) const
|
||||
{
|
||||
return {(wavecapIntensity >> info.x34_redShift) / 255.f,
|
||||
(wavecapIntensity >> info.x35_greenShift) / 255.f,
|
||||
(wavecapIntensity >> info.x36_blueShift) / 255.f};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class CFluidPlane
|
||||
{
|
||||
protected:
|
||||
CAssetId x4_texPattern1Id;
|
||||
CAssetId x8_texPattern2Id;
|
||||
CAssetId xc_texColorId;
|
||||
std::experimental::optional<TLockedToken<CTexture>> x10_texPattern1;
|
||||
std::experimental::optional<TLockedToken<CTexture>> x20_texPattern2;
|
||||
std::experimental::optional<TLockedToken<CTexture>> x30_texColor;
|
||||
TLockedToken<CTexture> x10_texPattern1;
|
||||
TLockedToken<CTexture> x20_texPattern2;
|
||||
TLockedToken<CTexture> x30_texColor;
|
||||
float x40_alpha;
|
||||
EFluidType x44_fluidType;
|
||||
float x48_rippleIntensity;
|
||||
CFluidUVMotion x4c_uvMotion;
|
||||
|
||||
mutable std::vector<CFluidPlaneShader::Vertex> m_verts;
|
||||
mutable std::vector<CFluidPlaneShader::PatchVertex> m_pVerts;
|
||||
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
||||
|
||||
float ProjectRippleVelocity(float baseI, float velDot) const;
|
||||
float CalculateRippleIntensity(float baseI) const;
|
||||
|
||||
virtual void RenderStripWithRipples(float curY, const CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], int startYDiv,
|
||||
const CFluidPlaneRender::SPatchInfo& info,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
||||
std::vector<CFluidPlaneShader::PatchVertex>& pvOut) const;
|
||||
void RenderPatch(const CFluidPlaneRender::SPatchInfo& info,
|
||||
const CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
||||
std::vector<CFluidPlaneShader::PatchVertex>& pvOut) const;
|
||||
|
||||
public:
|
||||
virtual ~CFluidPlane() = default;
|
||||
CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, float alpha,
|
||||
EFluidType fluidType, float rippleIntensity, const CFluidUVMotion& motion);
|
||||
|
||||
|
@ -64,11 +177,11 @@ public:
|
|||
float GetAlpha() const { return x40_alpha; }
|
||||
EFluidType GetFluidType() const { return x44_fluidType; }
|
||||
const CFluidUVMotion& GetUVMotion() const { return x4c_uvMotion; }
|
||||
const CTexture& GetColorTexture() const { return **x30_texColor; }
|
||||
const CTexture& GetColorTexture() const { return *x30_texColor; }
|
||||
bool HasColorTexture() const { return x30_texColor.operator bool(); }
|
||||
const CTexture& GetTexturePattern1() const { return **x10_texPattern1; }
|
||||
const CTexture& GetTexturePattern1() const { return *x10_texPattern1; }
|
||||
bool HasTexturePattern1() const { return x10_texPattern1.operator bool(); }
|
||||
const CTexture& GetTexturePattern2() const { return **x20_texPattern2; }
|
||||
const CTexture& GetTexturePattern2() const { return *x20_texPattern2; }
|
||||
bool HasTexturePattern2() const { return x20_texPattern2.operator bool(); }
|
||||
};
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,13 +3,14 @@
|
|||
|
||||
#include "CFluidPlane.hpp"
|
||||
#include "CRipple.hpp"
|
||||
#include "Graphics/Shaders/CFluidPlaneShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CFluidUVMotion;
|
||||
class CFluidPlaneCPU final : public CFluidPlane
|
||||
|
||||
class CFluidPlaneCPU : public CFluidPlane
|
||||
{
|
||||
protected:
|
||||
class CTurbulence
|
||||
{
|
||||
float x0_speed;
|
||||
|
@ -39,10 +40,10 @@ class CFluidPlaneCPU final : public CFluidPlane
|
|||
CAssetId xa4_texIdEnvMap;
|
||||
CAssetId xa8_texIdEnvBumpMap;
|
||||
CAssetId xac_texId4;
|
||||
std::experimental::optional<TLockedToken<CTexture>> xb0_bumpMap;
|
||||
std::experimental::optional<TLockedToken<CTexture>> xc0_envMap;
|
||||
std::experimental::optional<TLockedToken<CTexture>> xd0_envBumpMap;
|
||||
std::experimental::optional<TLockedToken<CTexture>> xe0_lightmap;
|
||||
TLockedToken<CTexture> xb0_bumpMap;
|
||||
TLockedToken<CTexture> xc0_envMap;
|
||||
TLockedToken<CTexture> xd0_envBumpMap;
|
||||
TLockedToken<CTexture> xe0_lightmap;
|
||||
zeus::CVector3f xf0_bumpLightDir;
|
||||
float xfc_bumpScale;
|
||||
float x100_tileSize;
|
||||
|
@ -56,16 +57,41 @@ class CFluidPlaneCPU final : public CFluidPlane
|
|||
CTurbulence x120_turbulence;
|
||||
|
||||
u32 m_maxVertCount;
|
||||
bool m_tessellation = false;
|
||||
|
||||
mutable std::vector<CFluidPlaneShader::Vertex> m_verts;
|
||||
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
||||
mutable bool m_cachedDoubleLightmapBlend;
|
||||
mutable bool m_cachedAdditive;
|
||||
|
||||
static bool PrepareRipple(const CRipple& ripple, const CFluidPlaneRender::SPatchInfo& info,
|
||||
CFluidPlaneRender::SRippleInfo& rippleOut);
|
||||
void ApplyTurbulence(float t, CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], const float sineWave[256],
|
||||
const CFluidPlaneRender::SPatchInfo& info,
|
||||
const zeus::CVector3f& areaCenter) const;
|
||||
void ApplyRipple(const CFluidPlaneRender::SRippleInfo& rippleInfo,
|
||||
CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
u8 (&flags)[9][9], const float sineWave[256],
|
||||
const CFluidPlaneRender::SPatchInfo& info) const;
|
||||
void ApplyRipples(const rstl::reserved_vector<CFluidPlaneRender::SRippleInfo, 32>& rippleInfos,
|
||||
CFluidPlaneRender::SHFieldSample (&heights)[46][46], u8 (&flags)[9][9],
|
||||
const float sineWave[256], const CFluidPlaneRender::SPatchInfo& info) const;
|
||||
static void UpdatePatchNoNormals(CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9],
|
||||
const CFluidPlaneRender::SPatchInfo& info);
|
||||
static void UpdatePatchWithNormals(CFluidPlaneRender::SHFieldSample (& heights)[46][46],
|
||||
const u8 (& flags)[9][9],
|
||||
const CFluidPlaneRender::SPatchInfo& info);
|
||||
bool UpdatePatch(float time, const CFluidPlaneRender::SPatchInfo& info,
|
||||
CFluidPlaneRender::SHFieldSample (&heights)[46][46], u8 (&flags)[9][9],
|
||||
const zeus::CVector3f& areaCenter,
|
||||
const std::experimental::optional<CRippleManager>& rippleManager,
|
||||
int fromX, int toX, int fromY, int toY) const;
|
||||
|
||||
public:
|
||||
CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap, CAssetId envBumpMap,
|
||||
CAssetId lightMap, float unitsPerLightmapTexel, float tileSize, u32 tileSubdivisions,
|
||||
EFluidType fluidType, float alpha, const zeus::CVector3f& bumpLightDir, float bumpScale,
|
||||
const CFluidUVMotion& mot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||
CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap,
|
||||
CAssetId envBumpMap, CAssetId lightMap, float unitsPerLightmapTexel, float tileSize,
|
||||
u32 tileSubdivisions, EFluidType fluidType, float alpha, const zeus::CVector3f& bumpLightDir,
|
||||
float bumpScale, const CFluidUVMotion& mot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
|
||||
float turbAmplitudeMin, float specularMin, float specularMax, float reflectionBlend,
|
||||
float reflectionSize, float rippleIntensity, u32 maxVertCount);
|
||||
|
@ -85,13 +111,13 @@ public:
|
|||
float GetReflectionSize() const { return x118_reflectionSize; }
|
||||
float GetBumpScale() const { return xfc_bumpScale; }
|
||||
bool HasBumpMap() const { return xb0_bumpMap.operator bool(); }
|
||||
const CTexture& GetBumpMap() const { return **xb0_bumpMap; }
|
||||
const CTexture& GetBumpMap() const { return *xb0_bumpMap; }
|
||||
bool HasEnvMap() const { return xc0_envMap.operator bool(); }
|
||||
const CTexture& GetEnvMap() const { return **xc0_envMap; }
|
||||
const CTexture& GetEnvMap() const { return *xc0_envMap; }
|
||||
bool HasEnvBumpMap() const { return xd0_envBumpMap.operator bool(); }
|
||||
const CTexture& GetEnvBumpMap() const { return **xd0_envBumpMap; }
|
||||
const CTexture& GetEnvBumpMap() const { return *xd0_envBumpMap; }
|
||||
bool HasLightMap() const { return xe0_lightmap.operator bool(); }
|
||||
const CTexture& GetLightMap() const { return **xe0_lightmap; }
|
||||
const CTexture& GetLightMap() const { return *xe0_lightmap; }
|
||||
const zeus::CVector3f& GetBumpLightDir() const { return xf0_bumpLightDir; }
|
||||
float GetTileSize() const { return x100_tileSize; }
|
||||
int GetTileSubdivisions() const { return x104_tileSubdivisions; }
|
||||
|
@ -102,115 +128,6 @@ public:
|
|||
bool HasTurbulence() const { return x120_turbulence.HasTurbulence(); }
|
||||
};
|
||||
|
||||
class CFluidPlaneCPURender
|
||||
{
|
||||
public:
|
||||
enum class NormalMode
|
||||
{
|
||||
None,
|
||||
NoNormals,
|
||||
Normals,
|
||||
NBT
|
||||
};
|
||||
|
||||
static int numTilesInHField;
|
||||
static int numSubdivisionsInTile;
|
||||
static int numSubdivisionsInHField;
|
||||
|
||||
struct SPatchInfo
|
||||
{
|
||||
u8 x0_xSubdivs, x1_ySubdivs;
|
||||
zeus::CVector2f x4_localMin, xc_globalMin;
|
||||
float x14_tileSize;
|
||||
float x18_rippleResolution;
|
||||
float x1c_tileHypRadius;
|
||||
float x20_ooTileSize;
|
||||
float x24_ooRippleResolution;
|
||||
u16 x28_tileX;
|
||||
u16 x2a_gridDimX;
|
||||
u16 x2c_gridDimY;
|
||||
u16 x2e_tileY;
|
||||
const bool* x30_gridFlags;
|
||||
u8 x34_redShift;
|
||||
u8 x35_greenShift;
|
||||
u8 x36_blueShift;
|
||||
NormalMode x37_normalMode;
|
||||
float x38_wavecapIntensityScale;
|
||||
public:
|
||||
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
||||
float rippleResolution, float tileSize, float wavecapIntensityScale, int numSubdivisionsInHField,
|
||||
NormalMode normalMode, int redShift, int greenShift, int blueShift, u32 tileX, u32 gridDimX,
|
||||
u32 gridDimY, u32 tileY, const bool* gridFlags)
|
||||
{
|
||||
x0_xSubdivs = std::min(s16((localMax.x - localMin.x) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||
numSubdivisionsInHField + 2);
|
||||
x1_ySubdivs = std::min(s16((localMax.y - localMin.y) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||
numSubdivisionsInHField + 2);
|
||||
float tileHypRadius = tileSize * tileSize * 2 * 0.25f;
|
||||
x4_localMin.x = localMin.x;
|
||||
x4_localMin.y = localMin.y;
|
||||
xc_globalMin = x4_localMin + zeus::CVector2f(pos.x, pos.y);
|
||||
x14_tileSize = tileSize;
|
||||
x18_rippleResolution = rippleResolution;
|
||||
if (tileHypRadius != 0.f)
|
||||
tileHypRadius = std::sqrt(tileHypRadius);
|
||||
x1c_tileHypRadius = tileHypRadius;
|
||||
x20_ooTileSize = 1.f / x14_tileSize;
|
||||
x24_ooRippleResolution = 1.f / x18_rippleResolution;
|
||||
x28_tileX = u16(tileX);
|
||||
x2a_gridDimX = u16(gridDimX);
|
||||
x2c_gridDimY = u16(gridDimY);
|
||||
x2e_tileY = u16(tileY);
|
||||
x30_gridFlags = gridFlags;
|
||||
x34_redShift = u8(redShift);
|
||||
x35_greenShift = u8(greenShift);
|
||||
x36_blueShift = u8(blueShift);
|
||||
x37_normalMode = normalMode;
|
||||
x38_wavecapIntensityScale = wavecapIntensityScale;
|
||||
}
|
||||
};
|
||||
|
||||
struct SRippleInfo
|
||||
{
|
||||
const CRipple& x0_ripple;
|
||||
int x4_fromX;
|
||||
int x8_toX;
|
||||
int xc_fromY;
|
||||
int x10_toY;
|
||||
int x14_gfromX;
|
||||
int x18_gtoX;
|
||||
int x1c_gfromY;
|
||||
int x20_gtoY;
|
||||
public:
|
||||
SRippleInfo(const CRipple& ripple, int fromX, int toX, int fromY, int toY)
|
||||
: x0_ripple(ripple), x14_gfromX(fromX), x18_gtoX(toX), x1c_gfromY(fromY), x20_gtoY(toY) {}
|
||||
};
|
||||
|
||||
struct SHFieldSample
|
||||
{
|
||||
float height;
|
||||
s8 nx;
|
||||
s8 ny;
|
||||
s8 nz;
|
||||
u8 wavecapIntensity;
|
||||
|
||||
zeus::CVector3f MakeNormal() const { return {nx / 63.f, ny / 63.f, nz / 63.f}; }
|
||||
zeus::CVector3f MakeBinormal() const { return {nx / 63.f, nz / 63.f, -ny / 63.f}; }
|
||||
zeus::CVector3f MakeTangent() const { return {nz / 63.f, ny / 63.f, -nx / 63.f}; }
|
||||
zeus::CColor MakeColor(const CFluidPlaneCPURender::SPatchInfo& info) const
|
||||
{
|
||||
return {(wavecapIntensity >> info.x34_redShift) / 255.f,
|
||||
(wavecapIntensity >> info.x35_greenShift) / 255.f,
|
||||
(wavecapIntensity >> info.x36_blueShift) / 255.f};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
|
||||
const CFluidPlaneCPURender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut);
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CFLUIDPLANECPU_HPP__
|
||||
|
|
|
@ -52,7 +52,7 @@ CFluidPlaneDoor::RenderSetup(const CStateManager& mgr, float alpha, const zeus::
|
|||
|
||||
/* Used to be part of locked cache
|
||||
* These are too big for stack allocation */
|
||||
static CFluidPlaneCPURender::SHFieldSample lc_heights[46][46] = {};
|
||||
static CFluidPlaneRender::SHFieldSample lc_heights[46][46] = {};
|
||||
static u8 lc_flags[9][9] = {};
|
||||
|
||||
void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||
|
@ -61,14 +61,15 @@ void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::
|
|||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const
|
||||
{
|
||||
CFluidPlaneShader::RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, aabb, noNormals);
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile = xa4_tileSubdivisions;
|
||||
CFluidPlaneCPURender::numTilesInHField = 42 / xa4_tileSubdivisions;
|
||||
CFluidPlaneCPURender::numSubdivisionsInHField = CFluidPlaneCPURender::numTilesInHField * xa4_tileSubdivisions;
|
||||
CFluidPlaneRender::numSubdivisionsInTile = xa4_tileSubdivisions;
|
||||
CFluidPlaneRender::numTilesInHField = 42 / xa4_tileSubdivisions;
|
||||
CFluidPlaneRender::numSubdivisionsInHField = CFluidPlaneRender::numTilesInHField * xa4_tileSubdivisions;
|
||||
zeus::CVector2f centerPlane(aabb.center().x, aabb.center().y);
|
||||
float patchSize = xa8_rippleResolution * CFluidPlaneCPURender::numSubdivisionsInHField;
|
||||
float patchSize = xa8_rippleResolution * CFluidPlaneRender::numSubdivisionsInHField;
|
||||
float ooSubdivSize = 1.f / xa8_rippleResolution;
|
||||
|
||||
m_verts.clear();
|
||||
m_pVerts.clear();
|
||||
m_shader->prepareDraw(setupInfo);
|
||||
|
||||
for (float curX = aabb.min.x ; curX < aabb.max.x ; curX += patchSize)
|
||||
|
@ -77,26 +78,27 @@ void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::
|
|||
for (float curY = aabb.min.y ; curY < aabb.max.y ; curY += patchSize)
|
||||
{
|
||||
float remSubdivsY = (aabb.max.y - curY) * ooSubdivSize;
|
||||
int remSubdivsXi = std::min(CFluidPlaneCPURender::numSubdivisionsInHField, int(remSubdivsX));
|
||||
int remSubdivsYi = std::min(CFluidPlaneCPURender::numSubdivisionsInHField, int(remSubdivsY));
|
||||
int remSubdivsXi = std::min(CFluidPlaneRender::numSubdivisionsInHField, int(remSubdivsX));
|
||||
int remSubdivsYi = std::min(CFluidPlaneRender::numSubdivisionsInHField, int(remSubdivsY));
|
||||
zeus::CAABox aabb2(aabb.min, zeus::CVector3f(xa8_rippleResolution * remSubdivsXi + curX,
|
||||
xa8_rippleResolution * remSubdivsYi + curY,
|
||||
aabb.max.z));
|
||||
if (frustum.aabbFrustumTest(aabb2.getTransformedAABox(xf)))
|
||||
{
|
||||
CFluidPlaneCPURender::SPatchInfo patchInfo(zeus::CVector3f(curX, curY, aabb.min.z),
|
||||
CFluidPlaneRender::SPatchInfo patchInfo(zeus::CVector3f(curX, curY, aabb.min.z),
|
||||
aabb2.max, xf.origin, xa8_rippleResolution,
|
||||
xa0_tileSize, 0.f,
|
||||
CFluidPlaneCPURender::numSubdivisionsInHField,
|
||||
CFluidPlaneCPURender::NormalMode::None,
|
||||
CFluidPlaneRender::numSubdivisionsInHField,
|
||||
CFluidPlaneRender::NormalMode::None,
|
||||
0, 0, 0, 0, 0, 0, 0, nullptr);
|
||||
|
||||
RenderPatch(patchInfo, lc_heights, lc_flags, true, true, m_verts);
|
||||
RenderPatch(patchInfo, lc_heights, lc_flags, true, true, m_verts, m_pVerts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_shader->loadVerts(m_verts);
|
||||
m_shader->loadVerts(m_verts, m_pVerts);
|
||||
m_shader->doneDrawing();
|
||||
}
|
||||
|
||||
}
|
|
@ -12,9 +12,6 @@ class CFluidPlaneDoor final : public CFluidPlane
|
|||
int xa4_tileSubdivisions;
|
||||
float xa8_rippleResolution;
|
||||
|
||||
mutable std::vector<CFluidPlaneShader::Vertex> m_verts;
|
||||
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
||||
|
||||
CFluidPlaneShader::RenderSetupInfo
|
||||
RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf,
|
||||
const zeus::CAABox& aabb, bool noNormals) const;
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#include "CFluidPlaneGPU.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CFluidPlaneGPU::CFluidPlaneGPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap,
|
||||
CAssetId envMap, CAssetId envBumpMap, CAssetId lightMap, float unitsPerLightmapTexel,
|
||||
float tileSize, u32 tileSubdivisions, EFluidType fluidType, float alpha,
|
||||
const zeus::CVector3f& bumpLightDir, float bumpScale, const CFluidUVMotion& mot,
|
||||
float turbSpeed, float turbDistance, float turbFreqMax, float turbFreqMin,
|
||||
float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax, float turbAmplitudeMin,
|
||||
float specularMin, float specularMax, float reflectionBlend, float reflectionSize,
|
||||
float rippleIntensity, u32 maxVertCount)
|
||||
: CFluidPlaneCPU(texPattern1, texPattern2, texColor, bumpMap, envMap, envBumpMap, lightMap, unitsPerLightmapTexel,
|
||||
tileSize, tileSubdivisions, fluidType, alpha, bumpLightDir, bumpScale, mot, turbSpeed, turbDistance,
|
||||
turbFreqMax, turbFreqMin, turbPhaseMax, turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin,
|
||||
specularMin, specularMax, reflectionBlend, reflectionSize, rippleIntensity, maxVertCount)
|
||||
{
|
||||
m_tessellation = true;
|
||||
}
|
||||
|
||||
void CFluidPlaneGPU::RenderStripWithRipples(float curY, const CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], int startYDiv,
|
||||
const CFluidPlaneRender::SPatchInfo& info,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
||||
std::vector<CFluidPlaneShader::PatchVertex>& pvOut) const
|
||||
{
|
||||
m_shader->bindTessellation();
|
||||
|
||||
int yTile = (startYDiv + CFluidPlaneRender::numSubdivisionsInTile - 1) /
|
||||
CFluidPlaneRender::numSubdivisionsInTile;
|
||||
int endXTile = (info.x0_xSubdivs + CFluidPlaneRender::numSubdivisionsInTile - 4) /
|
||||
CFluidPlaneRender::numSubdivisionsInTile;
|
||||
|
||||
float yMin = curY;
|
||||
float subdivF = CFluidPlaneRender::numSubdivisionsInTile;
|
||||
|
||||
float curX = info.x4_localMin.x;
|
||||
int gridCell = info.x28_tileX + info.x2a_gridDimX * (info.x2e_tileY + yTile - 1);
|
||||
int xTile = 1;
|
||||
int tileSpan;
|
||||
for (int i = 1 ; i < info.x0_xSubdivs - 2 ;
|
||||
i += CFluidPlaneRender::numSubdivisionsInTile * tileSpan, gridCell += tileSpan,
|
||||
xTile += tileSpan, curX += info.x14_tileSize * tileSpan)
|
||||
{
|
||||
tileSpan = 1;
|
||||
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell])
|
||||
continue;
|
||||
|
||||
CFluidPlaneShader::PatchVertex pv;
|
||||
size_t start = pvOut.size();
|
||||
|
||||
if ((flags[yTile][xTile] & 0x1f) == 0x1f)
|
||||
{
|
||||
for (; xTile+tileSpan<=endXTile ; ++tileSpan)
|
||||
{
|
||||
if ((flags[yTile][xTile+tileSpan] & 0x1f) != 0x1f)
|
||||
break;
|
||||
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell+tileSpan])
|
||||
break;
|
||||
}
|
||||
|
||||
std::fill(std::begin(pv.m_outerLevels), std::end(pv.m_outerLevels), subdivF);
|
||||
std::fill(std::begin(pv.m_innerLevels), std::end(pv.m_innerLevels), subdivF);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool r19 = (flags[yTile+1][xTile] & 0x2) != 0; // North
|
||||
bool r16 = (flags[yTile][xTile-1] & 0x8) != 0; // West
|
||||
bool r18 = (flags[yTile][xTile+1] & 0x4) != 0; // East
|
||||
bool r17 = (flags[yTile-1][xTile] & 0x1) != 0; // South
|
||||
|
||||
pv.m_outerLevels[0] = r16 ? subdivF : 1.f;
|
||||
pv.m_outerLevels[1] = r17 ? subdivF : 1.f;
|
||||
pv.m_outerLevels[2] = r18 ? subdivF : 1.f;
|
||||
pv.m_outerLevels[3] = r19 ? subdivF : 1.f;
|
||||
std::fill(std::begin(pv.m_innerLevels), std::end(pv.m_innerLevels), subdivF);
|
||||
}
|
||||
|
||||
float curTileY = yMin;
|
||||
float curTileX = curX;
|
||||
for (int t=0 ; t<tileSpan ; ++t)
|
||||
{
|
||||
pv.m_pos = zeus::CVector4f(curTileX, curTileY, curTileX + info.x14_tileSize, curTileY + info.x14_tileSize);
|
||||
pvOut.push_back(pv);
|
||||
curTileX += info.x14_tileSize;
|
||||
}
|
||||
|
||||
CGraphics::DrawArray(start, pvOut.size() - start);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef __URDE_CFLUIDPLANEGPU_HPP__
|
||||
#define __URDE_CFLUIDPLANEGPU_HPP__
|
||||
|
||||
#include "CFluidPlaneCPU.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CFluidPlaneGPU final : public CFluidPlaneCPU
|
||||
{
|
||||
public:
|
||||
CFluidPlaneGPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap,
|
||||
CAssetId envBumpMap, CAssetId lightMap, float unitsPerLightmapTexel, float tileSize,
|
||||
u32 tileSubdivisions, EFluidType fluidType, float alpha, const zeus::CVector3f& bumpLightDir,
|
||||
float bumpScale, const CFluidUVMotion& mot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
|
||||
float turbAmplitudeMin, float specularMin, float specularMax, float reflectionBlend,
|
||||
float reflectionSize, float rippleIntensity, u32 maxVertCount);
|
||||
|
||||
void RenderStripWithRipples(float curY, const CFluidPlaneRender::SHFieldSample (&heights)[46][46],
|
||||
const u8 (&flags)[9][9], int startYDiv,
|
||||
const CFluidPlaneRender::SPatchInfo& info,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
||||
std::vector<CFluidPlaneShader::PatchVertex>& pvOut) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CFLUIDPLANEGPU_HPP__
|
|
@ -92,12 +92,18 @@ void CFluidPlaneManager::CreateSplash(TUniqueId splasher, CStateManager& mgr, co
|
|||
}
|
||||
}
|
||||
|
||||
static bool g_RippleMapSetup = false;
|
||||
u8 CFluidPlaneManager::RippleValues[64][64] = {};
|
||||
u8 CFluidPlaneManager::RippleMins[64] = {};
|
||||
u8 CFluidPlaneManager::RippleMaxs[64] = {};
|
||||
boo::ObjToken<boo::ITextureS> CFluidPlaneManager::RippleMapTex;
|
||||
|
||||
void CFluidPlaneManager::SetupRippleMap()
|
||||
{
|
||||
if (g_RippleMapSetup)
|
||||
return;
|
||||
g_RippleMapSetup = true;
|
||||
|
||||
float curX = 0.f;
|
||||
for (int i=0 ; i<64 ; ++i)
|
||||
{
|
||||
|
@ -142,6 +148,13 @@ void CFluidPlaneManager::SetupRippleMap()
|
|||
RippleMaxs[i] = valC;
|
||||
curX += (1.f / 63.f);
|
||||
}
|
||||
|
||||
CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
RippleMapTex = ctx.newStaticTexture(64, 64, 1, boo::TextureFormat::I8,
|
||||
boo::TextureClampMode::ClampToBlack, RippleValues, 64 * 64);
|
||||
return true;
|
||||
} BooTrace);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,9 +3,21 @@
|
|||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "CRippleManager.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
enum class EFluidType
|
||||
{
|
||||
NormalWater,
|
||||
PoisonWater,
|
||||
Lava,
|
||||
PhazonFluid,
|
||||
Four,
|
||||
ThickLava
|
||||
};
|
||||
|
||||
class CStateManager;
|
||||
class CScriptWater;
|
||||
|
||||
|
@ -45,6 +57,7 @@ public:
|
|||
static u8 RippleValues[64][64];
|
||||
static u8 RippleMins[64];
|
||||
static u8 RippleMaxs[64];
|
||||
static boo::ObjToken<boo::ITextureS> RippleMapTex;
|
||||
|
||||
CFluidPlaneManager();
|
||||
void StartFrame(bool);
|
||||
|
|
|
@ -118,6 +118,7 @@ set(WORLD_SOURCES
|
|||
CGameLight.hpp CGameLight.cpp
|
||||
CFluidPlane.hpp CFluidPlane.cpp
|
||||
CFluidPlaneCPU.hpp CFluidPlaneCPU.cpp
|
||||
CFluidPlaneGPU.hpp CFluidPlaneGPU.cpp
|
||||
CFluidPlaneDoor.hpp CFluidPlaneDoor.cpp
|
||||
CRippleManager.hpp CRippleManager.cpp
|
||||
CRipple.hpp CRipple.cpp
|
||||
|
|
|
@ -930,7 +930,7 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager
|
|||
zeus::CVector3f position = x34_transform.origin + posOffset;
|
||||
position.z = water.GetTriggerBoundsWR().max.z;
|
||||
mgr.GetFluidPlaneManager()->CreateSplash(x8_uid, mgr, water, position, 0.3f, true);
|
||||
if (water.GetFluidPlane().GetFluidType() == CFluidPlane::EFluidType::NormalWater)
|
||||
if (water.GetFluidPlane().GetFluidType() == EFluidType::NormalWater)
|
||||
{
|
||||
float velMag = mgr.GetPlayer().GetVelocity().magnitude() / 10.f;
|
||||
mgr.GetEnvFxManager()->SetXB54(10.f * std::max(1.f, velMag));
|
||||
|
@ -2899,17 +2899,17 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
|
|||
{
|
||||
switch (water->GetFluidPlane().GetFluidType())
|
||||
{
|
||||
case CFluidPlane::EFluidType::NormalWater:
|
||||
case EFluidType::NormalWater:
|
||||
x2b0_outOfWaterTicks = 0;
|
||||
break;
|
||||
case CFluidPlane::EFluidType::Lava:
|
||||
case CFluidPlane::EFluidType::ThickLava:
|
||||
case EFluidType::Lava:
|
||||
case EFluidType::ThickLava:
|
||||
x2ac_surfaceRestraint = ESurfaceRestraints::Lava;
|
||||
break;
|
||||
case CFluidPlane::EFluidType::PoisonWater:
|
||||
case EFluidType::PoisonWater:
|
||||
x2b0_outOfWaterTicks = 0;
|
||||
break;
|
||||
case CFluidPlane::EFluidType::PhazonFluid:
|
||||
case EFluidType::PhazonFluid:
|
||||
x2ac_surfaceRestraint = ESurfaceRestraints::PhazonFluid;
|
||||
break;
|
||||
default: break;
|
||||
|
@ -6618,8 +6618,8 @@ void CPlayer::UpdateSubmerged(CStateManager& mgr)
|
|||
{
|
||||
x828_distanceUnderWater =
|
||||
-(zeus::CVector3f::skUp.dot(x34_transform.origin) - water->GetTriggerBoundsWR().max.z);
|
||||
CFluidPlane::EFluidType fluidType = water->GetFluidPlane().GetFluidType();
|
||||
x82c_inLava = (fluidType == CFluidPlane::EFluidType::Lava || fluidType == CFluidPlane::EFluidType::ThickLava);
|
||||
EFluidType fluidType = water->GetFluidPlane().GetFluidType();
|
||||
x82c_inLava = (fluidType == EFluidType::Lava || fluidType == EFluidType::ThickLava);
|
||||
CheckSubmerged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ CRipple::CRipple(TUniqueId id, const zeus::CVector3f& center, float intensity)
|
|||
x14_timeFalloff = 0.5f * tmp + 1.5f;
|
||||
x18_distFalloff = 4.f * tmp + 8.f;
|
||||
x1c_frequency = 2.f + tmp;
|
||||
x20_preAmplitude = 0.15f * tmp + 0.1f;
|
||||
x24_amplitude = x20_preAmplitude / 255.f;
|
||||
x20_amplitude = 0.15f * tmp + 0.1f;
|
||||
x24_lookupAmplitude = x20_amplitude / 255.f;
|
||||
}
|
||||
|
||||
x28_ooTimeFalloff = 1.f / x14_timeFalloff;
|
||||
|
|
|
@ -15,8 +15,8 @@ private:
|
|||
float x14_timeFalloff = 2.f;
|
||||
float x18_distFalloff = 12.f;
|
||||
float x1c_frequency = 3.f;
|
||||
float x20_preAmplitude = 0.25f;
|
||||
float x24_amplitude = 0.00098039221f;
|
||||
float x20_amplitude = 0.25f;
|
||||
float x24_lookupAmplitude = 0.00098039221f;
|
||||
float x28_ooTimeFalloff = 0.f;
|
||||
float x2c_ooDistFalloff = 0.f;
|
||||
float x30_ooPhase = 0.f;
|
||||
|
@ -32,11 +32,13 @@ public:
|
|||
float GetTimeFalloff() const { return x14_timeFalloff; }
|
||||
TUniqueId GetUniqueId() const { return x0_id; }
|
||||
float GetFrequency() const { return x1c_frequency; }
|
||||
float GetAmplitude() const { return x24_amplitude; }
|
||||
float GetAmplitude() const { return x20_amplitude; }
|
||||
float GetLookupAmplitude() const { return x24_lookupAmplitude; }
|
||||
float GetOODistanceFalloff() const { return x2c_ooDistFalloff; }
|
||||
float GetDistanceFalloff() const { return x18_distFalloff; }
|
||||
const zeus::CVector3f& GetCenter() const { return x8_center; }
|
||||
float GetOOTimeFalloff() const { return x28_ooTimeFalloff; }
|
||||
float GetPhase() const { return x34_phase; }
|
||||
float GetLookupPhase() const { return x38_lookupPhase; }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ CScriptDamageableTrigger::CScriptDamageableTrigger(TUniqueId uid, std::string_vi
|
|||
x14c_bounds(-extent * 0.5f, extent * 0.5f),
|
||||
x164_origHInfo(hInfo), x16c_hInfo(hInfo), x174_dVuln(dVuln), x1dc_faceFlag(faceFlag),
|
||||
x254_fluidPlane(patternTex1, patternTex2, colorTex, 1.f, 2,
|
||||
CFluidPlane::EFluidType::NormalWater, 1.f, CFluidUVMotion(6.f, 0.f))
|
||||
EFluidType::NormalWater, 1.f, CFluidUVMotion(6.f, 0.f))
|
||||
{
|
||||
x300_28_canOrbit = canOrbit == ECanOrbit::Orbit;
|
||||
if (x1dc_faceFlag & 0x1)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "World/CWorld.hpp"
|
||||
#include "Graphics/CBooRenderer.hpp"
|
||||
#include "Camera/CGameCamera.hpp"
|
||||
#include "CFluidPlaneGPU.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -22,10 +23,10 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, std::string_view n
|
|||
bool allowRender, CAssetId patternMap1, CAssetId patternMap2, CAssetId colorMap,
|
||||
CAssetId bumpMap, CAssetId envMap, CAssetId envBumpMap, CAssetId unusedMap,
|
||||
const zeus::CVector3f& bumpLightDir, float bumpScale, float morphInTime, float morphOutTime,
|
||||
bool active, CFluidPlane::EFluidType fluidType, bool b4, float alpha,
|
||||
bool active, EFluidType fluidType, bool b4, float alpha,
|
||||
const CFluidUVMotion& uvMot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
|
||||
float turbAmplitudeMin, const zeus::CColor& splashColor, const zeus::CColor& unkColor,
|
||||
float turbAmplitudeMin, const zeus::CColor& splashColor, const zeus::CColor& insideFogColor,
|
||||
CAssetId splashParticle1, CAssetId splashParticle2, CAssetId splashParticle3,
|
||||
CAssetId visorRunoffParticle, CAssetId unmorphVisorRunoffparticle, s32 visorRunoffSfx,
|
||||
s32 unmorphVisorRunoffSfx, s32 splashSfx1, s32 splashSfx2, s32 splashSfx3, float tileSize,
|
||||
|
@ -44,8 +45,8 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, std::string_view n
|
|||
x24c_unmorphVisorRunoffParticleId(unmorphVisorRunoffparticle),
|
||||
x260_visorRunoffSfx(CSfxManager::TranslateSFXID(visorRunoffSfx)),
|
||||
x262_unmorphVisorRunoffSfx(CSfxManager::TranslateSFXID(unmorphVisorRunoffSfx)),
|
||||
x2a4_splashColor(splashColor), x2a8_fogColor(unkColor), x2ac_alphaInTime(alphaInTime), x2b0_alphaOutTime(alphaOutTime),
|
||||
x2b4_alphaInRecip((alphaInTime != 0.f) ? 1.f / alphaInTime : 0.f),
|
||||
x2a4_splashColor(splashColor), x2a8_insideFogColor(insideFogColor), x2ac_alphaInTime(alphaInTime),
|
||||
x2b0_alphaOutTime(alphaOutTime), x2b4_alphaInRecip((alphaInTime != 0.f) ? 1.f / alphaInTime : 0.f),
|
||||
x2b8_alphaOutRecip((alphaOutTime != 0.f) ? 1.f / alphaOutTime : 0.f), x2bc_alpha(alpha), x2c0_tileSize(tileSize)
|
||||
{
|
||||
zeus::CAABox triggerAABB = GetTriggerBoundsWR();
|
||||
|
@ -56,14 +57,25 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, std::string_view n
|
|||
x2e8_27_allowRender = allowRender;
|
||||
x2e8_28_recomputeClipping = true;
|
||||
|
||||
x1b4_fluidPlane = std::make_unique<CFluidPlaneCPU>(patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap,
|
||||
lightmapId, unitsPerLightmapTexel, tileSize, tileSubdivisions,
|
||||
fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot,
|
||||
turbSpeed, turbDistance, turbFreqMax, turbFreqMin, turbPhaseMax,
|
||||
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin,
|
||||
specularMax, reflectionBlend, reflectionSize, rippleIntensity,
|
||||
x2cc_gridCellCount *
|
||||
((std::max(u32(2), tileSubdivisions) * 4 + 2) * 4));
|
||||
uint32_t maxPatchSize;
|
||||
if (CGraphics::g_BooFactory->isTessellationSupported(maxPatchSize))
|
||||
x1b4_fluidPlane = std::make_unique<CFluidPlaneGPU>(patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap,
|
||||
lightmapId, unitsPerLightmapTexel, tileSize, tileSubdivisions * 2,
|
||||
fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot,
|
||||
turbSpeed, turbDistance, turbFreqMax, turbFreqMin, turbPhaseMax,
|
||||
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin,
|
||||
specularMax, reflectionBlend, reflectionSize, rippleIntensity,
|
||||
x2cc_gridCellCount *
|
||||
((std::max(u32(2), tileSubdivisions * 2) * 4 + 2) * 4));
|
||||
else
|
||||
x1b4_fluidPlane = std::make_unique<CFluidPlaneCPU>(patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap,
|
||||
lightmapId, unitsPerLightmapTexel, tileSize, tileSubdivisions,
|
||||
fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot,
|
||||
turbSpeed, turbDistance, turbFreqMax, turbFreqMin, turbPhaseMax,
|
||||
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin,
|
||||
specularMax, reflectionBlend, reflectionSize, rippleIntensity,
|
||||
x2cc_gridCellCount *
|
||||
((std::max(u32(2), tileSubdivisions) * 4 + 2) * 4));
|
||||
u32Arr.reset();
|
||||
x264_splashEffects.resize(3);
|
||||
if (x22c_splashParticle1Id.IsValid())
|
||||
|
|
|
@ -43,7 +43,7 @@ private:
|
|||
rstl::reserved_vector<std::experimental::optional<TLockedToken<CGenDescription>>, 3> x264_splashEffects;
|
||||
rstl::reserved_vector<u16, 3> x298_splashSounds;
|
||||
zeus::CColor x2a4_splashColor;
|
||||
zeus::CColor x2a8_fogColor;
|
||||
zeus::CColor x2a8_insideFogColor;
|
||||
float x2ac_alphaInTime;
|
||||
float x2b0_alphaOutTime;
|
||||
float x2b4_alphaInRecip;
|
||||
|
@ -83,10 +83,10 @@ public:
|
|||
bool allowRender, CAssetId patternMap1, CAssetId patternMap2, CAssetId colorMap,
|
||||
CAssetId bumpMap, CAssetId envMap, CAssetId envBumpMap, CAssetId unusedMap,
|
||||
const zeus::CVector3f& bumpLightDir, float bumpScale, float morphInTime, float morphOutTime,
|
||||
bool active, CFluidPlane::EFluidType fluidType, bool b4, float alpha,
|
||||
bool active, EFluidType fluidType, bool b4, float alpha,
|
||||
const CFluidUVMotion& uvMot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
|
||||
float turbAmplitudeMin, const zeus::CColor& splashColor, const zeus::CColor& unkColor,
|
||||
float turbAmplitudeMin, const zeus::CColor& splashColor, const zeus::CColor& insideFogColor,
|
||||
CAssetId splashParticle1, CAssetId splashParticle2, CAssetId splashParticle3,
|
||||
CAssetId visorRunoffParticle, CAssetId unmorphVisorRunoffparticle, s32 visorRunoffSfx,
|
||||
s32 unmorphVisorRunoffSfx, s32 splashSfx1, s32 splashSfx2, s32 splashSfx3, float tileSize,
|
||||
|
@ -132,7 +132,7 @@ public:
|
|||
int GetPatchDimensionX() const { return x2d0_patchDimX; }
|
||||
int GetPatchDimensionY() const { return x2d4_patchDimY; }
|
||||
bool CanRippleAtPoint(const zeus::CVector3f& point) const;
|
||||
const zeus::CColor& GetFogColor() const { return x2a8_fogColor; }
|
||||
const zeus::CColor& GetInsideFogColor() const { return x2a8_insideFogColor; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1238,7 +1238,7 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
|
|||
float morphInTime = in.readFloatBig();
|
||||
float morphOutTime = in.readFloatBig();
|
||||
bool active = in.readBool();
|
||||
auto fluidType = CFluidPlane::EFluidType(in.readUint32Big());
|
||||
auto fluidType = EFluidType(in.readUint32Big());
|
||||
bool b4 = in.readBool();
|
||||
float alpha = in.readFloatBig();
|
||||
CFluidUVMotion uvMotion = LoadFluidUVMotion(in);
|
||||
|
@ -1253,8 +1253,8 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
|
|||
float turbAmplitudeMin = in.readFloatBig();
|
||||
zeus::CColor splashColor;
|
||||
splashColor.readRGBABig(in);
|
||||
zeus::CColor unkColor;
|
||||
unkColor.readRGBABig(in);
|
||||
zeus::CColor insideFogColor;
|
||||
insideFogColor.readRGBABig(in);
|
||||
CAssetId splashParticle1 = in.readUint32Big();
|
||||
CAssetId splashParticle2 = in.readUint32Big();
|
||||
CAssetId splashParticle3 = in.readUint32Big();
|
||||
|
@ -1312,7 +1312,7 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
|
|||
thermalCold, displaySurface, patternMap1, patternMap2, colorMap, bumpMap, envMap,
|
||||
envBumpMap, {}, bumpLightDir, bumpScale, morphInTime, morphOutTime, active, fluidType, b4,
|
||||
alpha, uvMotion, turbSpeed, turbDistance, turbFreqMax, turbFreqMin, turbPhaseMax,
|
||||
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, splashColor, unkColor, splashParticle1,
|
||||
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, splashColor, insideFogColor, splashParticle1,
|
||||
splashParticle2, splashParticle3, visorRunoffParticle, unmorphVisorRunoffParticle,
|
||||
visorRunoffSfx, unmorphVisorRunoffSfx, splashSfx1, splashSfx2, splashSfx3, tileSize,
|
||||
tileSubdivisions, specularMin, specularMax, reflectionSize, rippleIntensity,
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 788fa73884d56417d6bc70918983c9d9ac8032b4
|
||||
Subproject commit c9e057fa6e314257909edcd9758a0628bbc91918
|
Loading…
Reference in New Issue