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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user