2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 18:24:55 +00:00

Implement CFluidPlaneGPU for GPU-computed water ripples

This commit is contained in:
Jack Andersen
2018-06-06 18:43:26 -10:00
parent e63102e180
commit ac424ff9eb
31 changed files with 1651 additions and 1060 deletions

View File

@@ -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));
}
}

View File

@@ -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();
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"