2016-07-22 02:32:23 +00:00
|
|
|
#include "CModelShaders.hpp"
|
2017-08-08 06:03:57 +00:00
|
|
|
#include "Graphics/CLight.hpp"
|
2018-10-07 02:59:17 +00:00
|
|
|
#include "hecl/Pipeline.hpp"
|
2016-07-22 02:32:23 +00:00
|
|
|
|
|
|
|
namespace urde
|
|
|
|
{
|
|
|
|
|
2018-10-07 02:59:17 +00:00
|
|
|
std::unordered_map<uint64_t, CModelShaders::ShaderPipelines> CModelShaders::g_ShaderPipelines;
|
2016-07-22 02:32:23 +00:00
|
|
|
|
2017-08-08 06:03:57 +00:00
|
|
|
void CModelShaders::LightingUniform::ActivateLights(const std::vector<CLight>& lts)
|
|
|
|
{
|
2018-02-09 07:12:26 +00:00
|
|
|
ambient = zeus::CColor::skClear;
|
2017-08-08 06:03:57 +00:00
|
|
|
size_t curLight = 0;
|
|
|
|
|
|
|
|
for (const CLight& light : lts)
|
|
|
|
{
|
|
|
|
switch (light.GetType())
|
|
|
|
{
|
|
|
|
case ELightType::LocalAmbient:
|
|
|
|
ambient += light.GetColor();
|
|
|
|
break;
|
|
|
|
case ELightType::Point:
|
|
|
|
case ELightType::Spot:
|
|
|
|
case ELightType::Custom:
|
|
|
|
case ELightType::Directional:
|
|
|
|
{
|
|
|
|
if (curLight >= URDE_MAX_LIGHTS)
|
|
|
|
continue;
|
|
|
|
CModelShaders::Light& lightOut = lights[curLight++];
|
|
|
|
lightOut.pos = CGraphics::g_CameraMatrix * light.GetPosition();
|
|
|
|
lightOut.dir = CGraphics::g_CameraMatrix.basis * light.GetDirection();
|
|
|
|
lightOut.dir.normalize();
|
|
|
|
lightOut.color = light.GetColor();
|
|
|
|
lightOut.linAtt[0] = light.GetAttenuationConstant();
|
|
|
|
lightOut.linAtt[1] = light.GetAttenuationLinear();
|
|
|
|
lightOut.linAtt[2] = light.GetAttenuationQuadratic();
|
|
|
|
lightOut.angAtt[0] = light.GetAngleAttenuationConstant();
|
|
|
|
lightOut.angAtt[1] = light.GetAngleAttenuationLinear();
|
|
|
|
lightOut.angAtt[2] = light.GetAngleAttenuationQuadratic();
|
|
|
|
|
|
|
|
if (light.GetType() == ELightType::Directional)
|
|
|
|
lightOut.pos = (-lightOut.dir) * 1048576.f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; curLight<URDE_MAX_LIGHTS ; ++curLight)
|
|
|
|
{
|
|
|
|
CModelShaders::Light& lightOut = lights[curLight];
|
|
|
|
lightOut.color = zeus::CColor::skClear;
|
|
|
|
lightOut.linAtt[0] = 1.f;
|
|
|
|
lightOut.angAtt[0] = 1.f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-07 02:59:17 +00:00
|
|
|
static const hecl::Backend::TextureInfo ThermalTextures[] =
|
2016-07-31 20:52:04 +00:00
|
|
|
{
|
|
|
|
{hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true}
|
|
|
|
};
|
|
|
|
|
2018-10-07 02:59:17 +00:00
|
|
|
static const hecl::Backend::TextureInfo BallFadeTextures[] =
|
2017-03-05 07:57:12 +00:00
|
|
|
{
|
|
|
|
{hecl::Backend::TexGenSrc::Position, 0, 0, 0, false}, // ID tex
|
|
|
|
{hecl::Backend::TexGenSrc::Position, 1, 0, 0, false}, // Sphere ramp
|
|
|
|
{hecl::Backend::TexGenSrc::Position, 2, 0, 1, false} // TXTR_BallFade
|
|
|
|
};
|
|
|
|
|
2018-10-07 02:59:17 +00:00
|
|
|
static const hecl::Backend::TextureInfo WorldShadowTextures[] =
|
2017-10-01 04:26:46 +00:00
|
|
|
{
|
|
|
|
{hecl::Backend::TexGenSrc::Position, 7, 0, 7, false} // Shadow tex
|
|
|
|
};
|
|
|
|
|
2018-10-07 02:59:17 +00:00
|
|
|
static hecl::Backend::ExtensionSlot g_ExtensionSlots[] =
|
|
|
|
{
|
|
|
|
/* Default solid shading */
|
|
|
|
{},
|
|
|
|
/* Normal lit shading */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::Original,
|
|
|
|
hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Backface, false, false, true},
|
|
|
|
/* Thermal Visor shading */
|
|
|
|
{1, ThermalTextures, hecl::Backend::BlendFactor::One,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Backface, false, false, false, true},
|
|
|
|
/* Forced alpha shading */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Backface, false, false, true},
|
|
|
|
/* Forced additive shading */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Backface, true, false, true},
|
|
|
|
/* Solid color */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::One,
|
|
|
|
hecl::Backend::BlendFactor::Zero, hecl::Backend::ZTest::LEqual,
|
|
|
|
hecl::Backend::CullMode::Backface, false, false, false},
|
|
|
|
/* Solid color additive */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual,
|
|
|
|
hecl::Backend::CullMode::Backface, true, false, true},
|
|
|
|
/* Alpha-only Solid color frontface cull, LEqual */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::Zero,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual,
|
|
|
|
hecl::Backend::CullMode::Frontface, false, true, false},
|
|
|
|
/* Alpha-only Solid color frontface cull, Always, No Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::Zero,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::None,
|
|
|
|
hecl::Backend::CullMode::Frontface, true, true, false},
|
|
|
|
/* Alpha-only Solid color backface cull, LEqual */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::Zero,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual,
|
|
|
|
hecl::Backend::CullMode::Backface, false, true, false},
|
|
|
|
/* Alpha-only Solid color backface cull, Greater, No Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::Zero,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Greater,
|
|
|
|
hecl::Backend::CullMode::Backface, true, true, false},
|
|
|
|
/* MorphBall shadow shading */
|
|
|
|
{3, BallFadeTextures,
|
|
|
|
hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::InvSrcAlpha,
|
|
|
|
hecl::Backend::ZTest::Equal,
|
|
|
|
hecl::Backend::CullMode::Backface, false, false, true, false, true},
|
|
|
|
/* World shadow shading (modified lighting) */
|
|
|
|
{1, WorldShadowTextures, hecl::Backend::BlendFactor::Original,
|
|
|
|
hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Backface, false, false, true},
|
|
|
|
/* Forced alpha shading without culling */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::None, false, false, true},
|
|
|
|
/* Forced additive shading without culling */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::None, false, false, true},
|
|
|
|
/* Forced alpha shading without Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Original, true, false, true},
|
|
|
|
/* Forced additive shading without Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::Original, true, false, true},
|
|
|
|
/* Forced alpha shading without culling or Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::None, true, false, true},
|
|
|
|
/* Forced additive shading without culling or Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
|
|
|
hecl::Backend::CullMode::None, true, false, true},
|
|
|
|
/* Depth GEqual no Z-write */
|
|
|
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha,
|
|
|
|
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::GEqual,
|
|
|
|
hecl::Backend::CullMode::Backface, true, false, true}
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const hecl::Backend::Function ExtensionLightingFuncsGLSL[];
|
|
|
|
extern const hecl::Backend::Function ExtensionPostFuncsGLSL[];
|
|
|
|
extern const hecl::Backend::Function ExtensionLightingFuncsHLSL[];
|
|
|
|
extern const hecl::Backend::Function ExtensionPostFuncsHLSL[];
|
|
|
|
extern const hecl::Backend::Function ExtensionLightingFuncsMetal[];
|
|
|
|
extern const hecl::Backend::Function ExtensionPostFuncsMetal[];
|
2016-07-22 02:32:23 +00:00
|
|
|
|
2018-10-07 02:59:17 +00:00
|
|
|
void CModelShaders::Initialize()
|
2016-07-22 02:32:23 +00:00
|
|
|
{
|
2018-10-07 02:59:17 +00:00
|
|
|
const hecl::Backend::Function* lightingFuncs;
|
|
|
|
const hecl::Backend::Function* postFuncs;
|
|
|
|
switch (CGraphics::g_BooPlatform)
|
|
|
|
{
|
|
|
|
case boo::IGraphicsDataFactory::Platform::OpenGL:
|
|
|
|
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
|
|
|
case boo::IGraphicsDataFactory::Platform::NX:
|
|
|
|
default:
|
|
|
|
lightingFuncs = ExtensionLightingFuncsGLSL;
|
|
|
|
postFuncs = ExtensionPostFuncsGLSL;
|
2018-10-11 20:50:05 +00:00
|
|
|
break;
|
2018-10-07 02:59:17 +00:00
|
|
|
case boo::IGraphicsDataFactory::Platform::D3D11:
|
|
|
|
lightingFuncs = ExtensionLightingFuncsHLSL;
|
|
|
|
postFuncs = ExtensionPostFuncsHLSL;
|
2018-10-11 20:50:05 +00:00
|
|
|
break;
|
2018-10-07 02:59:17 +00:00
|
|
|
case boo::IGraphicsDataFactory::Platform::Metal:
|
|
|
|
lightingFuncs = ExtensionLightingFuncsMetal;
|
|
|
|
postFuncs = ExtensionPostFuncsMetal;
|
2018-10-11 20:50:05 +00:00
|
|
|
break;
|
2018-10-07 02:59:17 +00:00
|
|
|
}
|
|
|
|
for (auto& ext : g_ExtensionSlots)
|
|
|
|
{
|
|
|
|
ext.lighting = *lightingFuncs++;
|
|
|
|
ext.post = *postFuncs++;
|
|
|
|
}
|
2016-07-22 02:32:23 +00:00
|
|
|
}
|
|
|
|
|
2017-03-14 07:03:58 +00:00
|
|
|
void CModelShaders::Shutdown()
|
|
|
|
{
|
2018-10-07 02:59:17 +00:00
|
|
|
g_ShaderPipelines.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag,
|
|
|
|
const hecl::Frontend::IR& ir)
|
|
|
|
{
|
2018-10-11 20:50:05 +00:00
|
|
|
auto search = g_ShaderPipelines.find(tag.val64());
|
2018-10-07 02:59:17 +00:00
|
|
|
if (search != g_ShaderPipelines.cend())
|
|
|
|
return search->second;
|
2018-10-11 20:50:05 +00:00
|
|
|
ShaderPipelines& newPipelines = g_ShaderPipelines[tag.val64()];
|
2018-10-07 02:59:17 +00:00
|
|
|
newPipelines = std::make_shared<ShaderPipelinesData>();
|
2018-10-14 20:16:21 +00:00
|
|
|
size_t idx = 0;
|
2018-10-07 02:59:17 +00:00
|
|
|
for (const auto& ext : g_ExtensionSlots)
|
|
|
|
(*newPipelines)[idx++] = hecl::conv->convert(hecl::HECLIR(ir, tag, ext));
|
|
|
|
return newPipelines;
|
2017-03-14 07:03:58 +00:00
|
|
|
}
|
2016-07-22 02:32:23 +00:00
|
|
|
}
|