metaforce/Runtime/Graphics/Shaders/CModelShaders.cpp

212 lines
9.8 KiB
C++
Raw Normal View History

#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"
2019-06-06 00:07:50 +00:00
#include "CStopwatch.hpp"
2018-12-08 05:30:43 +00:00
namespace urde {
2018-10-07 02:59:17 +00:00
std::unordered_map<uint64_t, CModelShaders::ShaderPipelines> CModelShaders::g_ShaderPipelines;
2018-12-08 05:30:43 +00:00
void CModelShaders::LightingUniform::ActivateLights(const std::vector<CLight>& lts) {
ambient = zeus::skClear;
2018-12-08 05:30:43 +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;
2017-08-08 06:03:57 +00:00
}
}
2018-12-08 05:30:43 +00:00
}
for (; curLight < URDE_MAX_LIGHTS; ++curLight) {
CModelShaders::Light& lightOut = lights[curLight];
lightOut.pos = zeus::skZero3f;
lightOut.dir = zeus::skDown;
lightOut.color = zeus::skClear;
2018-12-08 05:30:43 +00:00
lightOut.linAtt[0] = 1.f;
lightOut.linAtt[1] = 0.f;
lightOut.linAtt[2] = 0.f;
lightOut.angAtt[0] = 1.f;
lightOut.angAtt[1] = 0.f;
lightOut.angAtt[2] = 0.f;
}
2017-08-08 06:03:57 +00:00
}
using TexCoordSource = hecl::Backend::TexCoordSource;
static const hecl::Backend::TextureInfo ThermalTextures[] = {{TexCoordSource::Normal, 7, true}};
2016-07-31 20:52:04 +00:00
2018-12-08 05:30:43 +00:00
static const hecl::Backend::TextureInfo BallFadeTextures[] = {
{TexCoordSource::Position, 0, false}, // ID tex
{TexCoordSource::Position, 0, false}, // Sphere ramp
{TexCoordSource::Position, 1, false} // TXTR_BallFade
2017-03-05 07:57:12 +00:00
};
2018-12-08 05:30:43 +00:00
static const hecl::Backend::TextureInfo WorldShadowTextures[] = {
{TexCoordSource::Position, 7, false} // Shadow tex
};
2018-12-08 05:30:43 +00:00
static const hecl::Backend::TextureInfo DisintegrateTextures[] = {
{TexCoordSource::Position, 0, false}, // Ashy tex
{TexCoordSource::Position, 1, false} // Ashy tex
2018-11-08 00:53:38 +00:00
};
2018-12-08 05:30:43 +00:00
static hecl::Backend::ExtensionSlot g_ExtensionSlots[] = {
2018-10-07 02:59:17 +00:00
/* Default solid shading */
{},
/* Normal lit shading */
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
2018-10-07 02:59:17 +00:00
/* Thermal Visor shading */
{1, ThermalTextures, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, false, true},
2018-10-07 02:59:17 +00:00
/* Forced alpha shading */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
2018-10-07 02:59:17 +00:00
/* Forced additive shading */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
2019-02-25 08:14:59 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
2018-10-07 02:59:17 +00:00
/* Solid color */
{0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, false, false, false},
2018-10-07 02:59:17 +00:00
/* Solid color additive */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, true, false, true},
2018-10-07 02:59:17 +00:00
/* Alpha-only Solid color frontface cull, LEqual */
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Frontface, false, true, false},
2018-10-07 02:59:17 +00:00
/* Alpha-only Solid color frontface cull, Always, No Z-write */
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::None, hecl::Backend::CullMode::Frontface, true, true, false},
2018-10-07 02:59:17 +00:00
/* Alpha-only Solid color backface cull, LEqual */
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, false, true, false},
2018-10-07 02:59:17 +00:00
/* Alpha-only Solid color backface cull, Greater, No Z-write */
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::Backface, true, true, false},
2018-10-07 02:59:17 +00:00
/* MorphBall shadow shading */
2019-05-10 04:09:01 +00:00
{3, BallFadeTextures, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
hecl::Backend::ZTest::Equal, hecl::Backend::CullMode::Backface, false, false, true, false, true},
2018-10-07 02:59:17 +00:00
/* World shadow shading (modified lighting) */
{1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
2018-10-07 02:59:17 +00:00
/* Forced alpha shading without culling */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true},
2018-10-07 02:59:17 +00:00
/* Forced additive shading without culling */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true},
2018-10-07 02:59:17 +00:00
/* Forced alpha shading without Z-write */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true},
2018-10-07 02:59:17 +00:00
/* Forced additive shading without Z-write */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true},
2018-10-07 02:59:17 +00:00
/* Forced alpha shading without culling or Z-write */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true},
2018-10-07 02:59:17 +00:00
/* Forced additive shading without culling or Z-write */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true},
2018-10-07 02:59:17 +00:00
/* Depth GEqual no Z-write */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
2018-12-08 05:30:43 +00:00
hecl::Backend::ZTest::GEqual, hecl::Backend::CullMode::Backface, true, false, true},
2018-11-08 00:53:38 +00:00
/* Disintegration */
2019-05-10 04:09:01 +00:00
{2, DisintegrateTextures, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false, false, true, false, false, true},
2019-01-05 08:34:09 +00:00
/* Forced additive shading without culling or Z-write and greater depth test */
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::None, true, false, true},
/* Thermal cold shading */
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original,
2019-02-25 08:14:59 +00:00
false, false, true, false, false, false, true},
/* Normal lit shading with alpha */
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
2019-06-01 03:41:01 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface},
/* Normal lit shading with cube reflection */
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
/* Normal lit shading with cube reflection and world shadow */
2019-06-01 09:28:12 +00:00
{1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
2019-06-01 03:41:01 +00:00
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}};
2018-10-07 02:59:17 +00:00
2019-05-10 04:09:01 +00:00
static const char* ShaderMacros[] = {
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_THERMAL_HOT",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_SOLID",
"URDE_SOLID",
"URDE_SOLID",
"URDE_SOLID",
"URDE_SOLID",
"URDE_SOLID",
"URDE_MB_SHADOW",
"URDE_LIGHTING_SHADOW",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_LIGHTING",
"URDE_DISINTEGRATE",
"URDE_LIGHTING",
"URDE_THERMAL_COLD",
"URDE_LIGHTING",
2019-06-01 03:41:01 +00:00
"URDE_LIGHTING_CUBE_REFLECTION",
"URDE_LIGHTING_CUBE_REFLECTION_SHADOW",
};
2018-12-08 05:30:43 +00:00
void CModelShaders::Initialize() {
const char** macro = ShaderMacros;
for (auto& ext : g_ExtensionSlots)
ext.shaderMacro = *macro++;
}
2018-12-08 05:30:43 +00:00
void CModelShaders::Shutdown() { g_ShaderPipelines.clear(); }
2018-10-07 02:59:17 +00:00
CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag,
const Material& material) {
2018-12-08 05:30:43 +00:00
auto search = g_ShaderPipelines.find(tag.val64());
if (search != g_ShaderPipelines.cend())
return search->second;
2019-02-04 00:01:44 +00:00
2018-12-08 05:30:43 +00:00
ShaderPipelines& newPipelines = g_ShaderPipelines[tag.val64()];
newPipelines = std::make_shared<ShaderPipelinesData>();
2019-02-04 00:01:44 +00:00
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
size_t idx = 0;
for (const auto& ext : g_ExtensionSlots)
(*newPipelines)[idx++] = hecl::conv->convert(ctx, Shader_CModelShaders(SModelShadersInfo(material, tag, ext)));
2019-02-04 00:01:44 +00:00
return true;
} BooTrace);
2018-12-08 05:30:43 +00:00
return newPipelines;
}
2018-12-08 05:30:43 +00:00
} // namespace urde