CModelShaders implementation updates (WIP)

This commit is contained in:
Luke Street 2020-10-21 01:43:53 -04:00
parent d07f5320bd
commit 7bffc621b8
2 changed files with 326 additions and 305 deletions

View File

@ -10,6 +10,69 @@
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
namespace urde {
using BlendMaterial = hecl::blender::Material;
using MaterialBlendMode = BlendMaterial::BlendMode;
enum class MaterialTexCoordSource : uint32_t {
Invalid = 0xff,
Position = 0,
Normal = 1,
Tex0 = 2,
Tex1 = 3,
Tex2 = 4,
Tex3 = 5,
Tex4 = 6,
Tex5 = 7,
Tex6 = 8,
Tex7 = 9,
};
// FIXME hsh bug: u8 generates '\xCC', '\xCC', '\xCC', '\xFF' which cause issues
template <bool HasValue, int R = 0, int G = 0, int B = 0, int A = 0>
struct ColorValue {
static constexpr bool Constant = HasValue;
static constexpr float R_ = u8(R) / 255.f;
static constexpr float G_ = u8(G) / 255.f;
static constexpr float B_ = u8(B) / 255.f;
static constexpr float A_ = u8(A) / 255.f;
};
template <MaterialTexCoordSource Source, bool Normalize, int MtxIdx, bool SampleAlpha,
class ConstantColor = ColorValue<false>>
struct PassTraits {
static constexpr MaterialTexCoordSource Source_ = Source;
static constexpr bool Normalize_ = Normalize;
static constexpr int MtxIdx_ = MtxIdx;
static constexpr bool SampleAlpha_ = SampleAlpha;
using ConstantColor_ = ConstantColor;
};
template <int R, int G, int B, int A = 255>
using PassConstantColor = PassTraits<MaterialTexCoordSource::Invalid, false, -1, false, ColorValue<true, R, G, B, A>>;
template <MaterialTexCoordSource Source, int MtxIdx = -1>
using PassTex = PassTraits<Source, false, MtxIdx, false>;
template <bool Normalize = true, int MtxIdx = -1>
using PassNormal = PassTraits<MaterialTexCoordSource::Normal, Normalize, MtxIdx, false>;
using PassNone = PassTraits<MaterialTexCoordSource::Invalid, false, -1, false>;
template <bool CubeReflection>
struct DynReflectionTex {
using type = hsh::texture2d;
};
template <>
struct DynReflectionTex<true> {
using type = hsh::texturecube;
};
template <bool CubeReflection>
using DynReflectionTexType = typename DynReflectionTex<CubeReflection>::type;
} // namespace urde
#include "CModelShaders.cpp.hshhead"
namespace urde { namespace urde {
void CModelShaders::FragmentUniform::ActivateLights(const std::vector<CLight>& lts) { void CModelShaders::FragmentUniform::ActivateLights(const std::vector<CLight>& lts) {
@ -60,109 +123,24 @@ void CModelShaders::FragmentUniform::ActivateLights(const std::vector<CLight>& l
} }
} }
using TexCoordSource = hecl::Backend::TexCoordSource; //constexpr std::array<hecl::Backend::TextureInfo, 1> ThermalTextures{{
// {TexCoordSource::Normal, 7, true},
constexpr std::array<hecl::Backend::TextureInfo, 1> ThermalTextures{{ //}};
{TexCoordSource::Normal, 7, true}, //
}}; //constexpr std::array<hecl::Backend::TextureInfo, 3> BallFadeTextures{{
// {TexCoordSource::Position, 0, false}, // ID tex
constexpr std::array<hecl::Backend::TextureInfo, 3> BallFadeTextures{{ // {TexCoordSource::Position, 0, false}, // Sphere ramp
{TexCoordSource::Position, 0, false}, // ID tex // {TexCoordSource::Position, 1, false}, // TXTR_BallFade
{TexCoordSource::Position, 0, false}, // Sphere ramp //}};
{TexCoordSource::Position, 1, false}, // TXTR_BallFade //
}}; //constexpr std::array<hecl::Backend::TextureInfo, 1> WorldShadowTextures{{
// {TexCoordSource::Position, 7, false}, // Shadow tex
constexpr std::array<hecl::Backend::TextureInfo, 1> WorldShadowTextures{{ //}};
{TexCoordSource::Position, 7, false}, // Shadow tex //
}}; //constexpr std::array<hecl::Backend::TextureInfo, 2> DisintegrateTextures{{
// {TexCoordSource::Position, 0, false}, // Ashy tex
constexpr std::array<hecl::Backend::TextureInfo, 2> DisintegrateTextures{{ // {TexCoordSource::Position, 1, false}, // Ashy tex
{TexCoordSource::Position, 0, false}, // Ashy tex //}};
{TexCoordSource::Position, 1, false}, // Ashy tex
}};
static std::array<hecl::Backend::ExtensionSlot, size_t(EExtendedShader::MAX)> 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.data(), 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, false, 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.data(), 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.data(), 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},
/* Disintegration */
{2, DisintegrateTextures.data(), hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false, false, true, false, false, true},
/* 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, false, false, true, false, false, false, true},
/* Normal lit shading with alpha */
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface},
/* Normal lit shading with alpha without Z-write or depth test */
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
hecl::Backend::ZTest::None, hecl::Backend::CullMode::Backface, true},
/* 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 */
{1, WorldShadowTextures.data(), hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
}};
// TODO: put somewhere common // TODO: put somewhere common
template <typename BitType> template <typename BitType>
@ -180,7 +158,7 @@ public:
constexpr explicit Flags(MaskType flags) noexcept : m_mask(flags) {} constexpr explicit Flags(MaskType flags) noexcept : m_mask(flags) {}
// relational operators // relational operators
auto operator<=>(Flags<BitType> const&) const = default; // auto operator<=>(Flags<BitType> const&) const = default;
// logical operator // logical operator
constexpr bool operator!() const noexcept { return !m_mask; } constexpr bool operator!() const noexcept { return !m_mask; }
@ -282,7 +260,7 @@ struct CCubeSurface {
float x20_normal[3]; float x20_normal[3];
}; };
struct CMetroidModelInstance { struct CMetroidModelInstance_ {
u32 x0_visorFlags; u32 x0_visorFlags;
zeus::CTransform x4_worldXf; zeus::CTransform x4_worldXf;
zeus::CAABox x34_worldAABB; zeus::CAABox x34_worldAABB;
@ -352,41 +330,6 @@ constexpr hsh::sampler ClampEdgeSamp(hsh::Linear, hsh::Linear, hsh::Linear, hsh:
constexpr hsh::sampler ReflectSamp(hsh::Linear, hsh::Linear, hsh::Linear, hsh::ClampToBorder, hsh::ClampToBorder, constexpr hsh::sampler ReflectSamp(hsh::Linear, hsh::Linear, hsh::Linear, hsh::ClampToBorder, hsh::ClampToBorder,
hsh::ClampToBorder); hsh::ClampToBorder);
template <bool CubeReflection>
struct DynReflectionTex {
using type = hsh::texture2d;
};
template <>
struct DynReflectionTex<true> {
using type = hsh::texturecube;
};
template <bool CubeReflection>
using DynReflectionTexType = typename DynReflectionTex<CubeReflection>::type;
using BlendMaterial = hecl::blender::Material;
using MaterialBlendMode = BlendMaterial::BlendMode;
using MaterialTexCoordSource = BlendMaterial::TexCoordSource;
struct NoColorValue {
static constexpr bool Constant = false;
};
template <float R, float G, float B, float A>
struct ColorValue {
static constexpr bool Constant = true;
static constexpr hsh::float3 RGB{R, G, B};
static constexpr float A_ = A;
};
template <MaterialTexCoordSource Source, bool Normalize, int MtxIdx, bool SampleAlpha, class ConstantColor = NoColorValue>
struct PassTraits {
static constexpr MaterialTexCoordSource Source_ = Source;
static constexpr bool Normalize_ = Normalize;
static constexpr int MtxIdx_ = MtxIdx;
static constexpr bool SampleAlpha_ = SampleAlpha;
using ConstantColor_ = ConstantColor;
};
template <MaterialBlendMode Mode> template <MaterialBlendMode Mode>
constexpr hsh::BlendFactor MaterialBlendModeSrcFactor = hsh::One; constexpr hsh::BlendFactor MaterialBlendModeSrcFactor = hsh::One;
template <> template <>
@ -407,15 +350,18 @@ constexpr hsh::ColorComponentFlags
(AlphaUpdate ? hsh::CC_Alpha : 0)); (AlphaUpdate ? hsh::CC_Alpha : 0));
template <MaterialBlendMode MaterialBlendMode, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha> template <MaterialBlendMode MaterialBlendMode, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha>
struct CModelShadersColorAttachmentBase struct CModelShadersColorAttachmentBase {
: color_attachment<MaterialBlendModeSrcFactor<MaterialBlendMode>, MaterialBlendModeDstFactor<MaterialBlendMode>, using type =
hsh::Add, DstAlpha ? hsh::ConstAlpha : hsh::Zero, hsh::Zero, hsh::Add, color_attachment<MaterialBlendModeSrcFactor<MaterialBlendMode>, MaterialBlendModeDstFactor<MaterialBlendMode>,
ColorUpdateFlags<ColorUpdate, AlphaUpdate>> {}; hsh::Add, DstAlpha ? hsh::ConstAlpha : hsh::Zero, hsh::Zero, hsh::Add,
ColorUpdateFlags<ColorUpdate, AlphaUpdate>>;
};
template <hsh::BlendFactor Src, hsh::BlendFactor Dst, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha> template <hsh::BlendFactor Src, hsh::BlendFactor Dst, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha>
struct CModelShadersColorAttachmentOverride struct CModelShadersColorAttachmentOverride {
: color_attachment<Src, Dst, hsh::Add, DstAlpha ? hsh::ConstAlpha : hsh::Zero, hsh::Zero, hsh::Add, using type = color_attachment<Src, Dst, hsh::Add, DstAlpha ? hsh::ConstAlpha : hsh::Zero, hsh::Zero, hsh::Add,
ColorUpdateFlags<ColorUpdate, AlphaUpdate>> {}; ColorUpdateFlags<ColorUpdate, AlphaUpdate>>;
};
template <MaterialBlendMode MaterialBlendMode, bool AlphaTest, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha> template <MaterialBlendMode MaterialBlendMode, bool AlphaTest, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha>
struct CModelShadersColorAttachment0To4 struct CModelShadersColorAttachment0To4
@ -451,7 +397,9 @@ struct CModelShadersColorAttachment7To8<MaterialBlendMode, true, ColorUpdate, Al
template <MaterialBlendMode MaterialBlendMode, u8 GameBlendMode, bool AlphaTest, bool ColorUpdate, bool AlphaUpdate, template <MaterialBlendMode MaterialBlendMode, u8 GameBlendMode, bool AlphaTest, bool ColorUpdate, bool AlphaUpdate,
bool DstAlpha> bool DstAlpha>
struct CModelShadersColorAttachment : color_attachment<> {}; struct CModelShadersColorAttachment {
using type = color_attachment<>;
};
template <MaterialBlendMode MaterialBlendMode, bool AlphaTest, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha> template <MaterialBlendMode MaterialBlendMode, bool AlphaTest, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha>
struct CModelShadersColorAttachment<MaterialBlendMode, 0, AlphaTest, ColorUpdate, AlphaUpdate, DstAlpha> struct CModelShadersColorAttachment<MaterialBlendMode, 0, AlphaTest, ColorUpdate, AlphaUpdate, DstAlpha>
@ -489,46 +437,55 @@ template <MaterialBlendMode MaterialBlendMode, bool AlphaTest, bool ColorUpdate,
struct CModelShadersColorAttachment<MaterialBlendMode, 8, AlphaTest, ColorUpdate, AlphaUpdate, DstAlpha> struct CModelShadersColorAttachment<MaterialBlendMode, 8, AlphaTest, ColorUpdate, AlphaUpdate, DstAlpha>
: CModelShadersColorAttachment7To8<MaterialBlendMode, AlphaTest, ColorUpdate, AlphaUpdate, DstAlpha> {}; : CModelShadersColorAttachment7To8<MaterialBlendMode, AlphaTest, ColorUpdate, AlphaUpdate, DstAlpha> {};
template <MaterialBlendMode MaterialBlendMode, u32 MaterialFlags, u8 GameBlendMode, u16 ModelFlags, bool ColorUpdate, template <MaterialBlendMode MaterialBlendMode, u16 MaterialFlags, u8 GameBlendMode, u16 ModelFlags, bool ColorUpdate,
bool AlphaUpdate, bool DstAlpha> bool AlphaUpdate, bool DstAlpha, ERglCullMode CullMode>
struct CModelShadersPipelineConfig struct CModelShadersPipelineConfig
: pipeline< : public pipeline<
CModelShadersColorAttachment<MaterialBlendMode, GameBlendMode, topology<hsh::TriangleStrip>,
MaterialFlags & u16(CCubeMaterialFlagBits::fAlphaTest), ColorUpdate, AlphaUpdate, typename CModelShadersColorAttachment<MaterialBlendMode, GameBlendMode,
DstAlpha>, (MaterialFlags & u16(CCubeMaterialFlagBits::fAlphaTest)) != 0, ColorUpdate,
AlphaUpdate, DstAlpha>::type,
depth_compare<ModelFlags & u16(CModelFlagsFlagBits::fDepthTest) depth_compare<ModelFlags & u16(CModelFlagsFlagBits::fDepthTest)
? (ModelFlags& u16(CModelFlagsFlagBits::kDepthGreater) ? (ModelFlags& u16(CModelFlagsFlagBits::kDepthGreater)
? (ModelFlags& u16(CModelFlagsFlagBits::fDepthNonInclusive) ? hsh::Greater : hsh::GEqual) ? (ModelFlags& u16(CModelFlagsFlagBits::fDepthNonInclusive) ? hsh::Greater : hsh::GEqual)
: (ModelFlags& u16(CModelFlagsFlagBits::fDepthNonInclusive) ? hsh::Less : hsh::LEqual)) : (ModelFlags& u16(CModelFlagsFlagBits::fDepthNonInclusive) ? hsh::Less : hsh::LEqual))
: hsh::Always>, : hsh::Always>,
depth_write<ModelFlags & u16(CModelFlagsFlagBits::fDepthWrite) && depth_write<ModelFlags & u16(CModelFlagsFlagBits::fDepthWrite) &&
MaterialFlags & u32(CCubeMaterialFlagBits::fDepthWrite)>, MaterialFlags & u16(CCubeMaterialFlagBits::fDepthWrite)>,
early_depth_stencil<(MaterialFlags & u16(CCubeMaterialFlagBits::fAlphaTest)) == 0>> { early_depth_stencil<(MaterialFlags & u16(CCubeMaterialFlagBits::fAlphaTest)) == 0>,
ERglCullModeAttachment<CullMode>> {
static constexpr bool AlphaTest = MaterialFlags & u16(CCubeMaterialFlagBits::fAlphaTest); static constexpr bool AlphaTest = MaterialFlags & u16(CCubeMaterialFlagBits::fAlphaTest);
}; };
template <uint32_t NSkinSlots, uint32_t NCol, uint32_t NUv, uint32_t NWeight, BlendMaterial::ShaderType Type, EPostType Post, template <uint32_t NSkinSlots, uint32_t NCol, uint32_t NUv, uint32_t NWeight, BlendMaterial::ShaderType Type,
bool WorldShadow, class LightmapTraits, class DiffuseTraits, EPostType Post, bool WorldShadow, class LightmapTraits, class DiffuseTraits, class EmissiveTraits,
class EmissiveTraits, class SpecularTraits, class ExtendedSpecularTraits, class ReflectionTraits, class SpecularTraits, class ExtendedSpecularTraits, class ReflectionTraits, class AlphaTraits,
class AlphaTraits, bool CubeReflection, MaterialBlendMode MaterialBlendMode, u32 MaterialFlags, bool CubeReflection, MaterialBlendMode MaterialBlendMode, u16 MaterialFlags,
u8 GameBlendMode, u16 ModelFlags, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha> // FIXME hsh bug: u8 generates broken characters for profiling
u16 GameBlendMode,
u16 ModelFlags, bool ColorUpdate = true, bool AlphaUpdate = false, bool DstAlpha = false,
ERglCullMode CullMode = ERglCullMode::Back>
struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, MaterialFlags, GameBlendMode, ModelFlags, struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, MaterialFlags, GameBlendMode, ModelFlags,
ColorUpdate, AlphaUpdate, DstAlpha> { ColorUpdate, AlphaUpdate, DstAlpha, CullMode> {
using PipelineConfig = CModelShadersPipelineConfig<MaterialBlendMode, MaterialFlags, GameBlendMode, ModelFlags,
ColorUpdate, AlphaUpdate, DstAlpha, CullMode>;
CModelShadersPipeline(hsh::uniform_buffer<CModelShaders::VertUniform<NSkinSlots>> vu, CModelShadersPipeline(hsh::uniform_buffer<CModelShaders::VertUniform<NSkinSlots>> vu,
hsh::uniform_buffer<CModelShaders::FragmentUniform> fragu HSH_VAR_STAGE(fragment), hsh::uniform_buffer<CModelShaders::FragmentUniform> fragu HSH_VAR_STAGE(fragment),
hsh::uniform_buffer<std::array<CModelShaders::TCGMatrix, 8>> tcgu, hsh::uniform_buffer<CModelShaders::TCGMatrixUniform> tcgu,
hsh::uniform_buffer<CModelShaders::ReflectMtx> refu, hsh::texture2d Lightmap, hsh::uniform_buffer<CModelShaders::ReflectMtx> refu, hsh::texture2d Lightmap,
hsh::texture2d Diffuse, hsh::texture2d Emissive, hsh::texture2d Specular, hsh::texture2d Diffuse, hsh::texture2d Emissive, hsh::texture2d Specular,
hsh::texture2d ExtendedSpecular, hsh::texture2d Reflection, hsh::texture2d Alpha, hsh::texture2d ExtendedSpecular, hsh::texture2d Reflection, hsh::texture2d Alpha,
hsh::texture2d ReflectionIndTex, hsh::texture2d ExtTex0, hsh::texture2d ExtTex1, hsh::texture2d ReflectionIndTex, hsh::texture2d ExtTex0, hsh::texture2d ExtTex1,
hsh::texture2d ExtTex2, DynReflectionTexType<CubeReflection> dynReflection, hsh::texture2d ExtTex2, DynReflectionTexType<CubeReflection> dynReflection,
hsh::vertex_buffer<CModelShaders::VertData<NCol, NUv, NWeight>> vd) { hsh::vertex_buffer<CModelShaders::VertData<NCol, NUv, NWeight>> vd,
hsh::index_buffer<u32> ibo) {
hsh::float4 mvPos; hsh::float4 mvPos;
hsh::float4 mvNorm; hsh::float4 mvNorm;
hsh::float4 objPos; hsh::float4 objPos;
hsh::float4 objNorm; hsh::float4 objNorm;
if constexpr (NSkinSlots != 0) { if constexpr (NSkinSlots > 0) {
objPos = hsh::float4(0.f); objPos = hsh::float4(0.f);
objNorm = hsh::float4(0.f); objNorm = hsh::float4(0.f);
for (uint32_t i = 0; i < NSkinSlots; ++i) { for (uint32_t i = 0; i < NSkinSlots; ++i) {
@ -566,39 +523,26 @@ struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, Ma
if constexpr (Pass##Traits::Source_ != MaterialTexCoordSource::Invalid) { \ if constexpr (Pass##Traits::Source_ != MaterialTexCoordSource::Invalid) { \
if constexpr (Pass##Traits::MtxIdx_ >= 0) { \ if constexpr (Pass##Traits::MtxIdx_ >= 0) { \
hsh::float4 src; \ hsh::float4 src; \
switch (Pass##Traits::Source_) { \ if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Position) { \
case MaterialTexCoordSource::Position: \
src = hsh::float4(objPos.xyz(), 1.f); \ src = hsh::float4(objPos.xyz(), 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Normal) { \
case MaterialTexCoordSource::Normal: \
src = hsh::float4(objNorm.xyz(), 1.f); \ src = hsh::float4(objNorm.xyz(), 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex0) { \
case MaterialTexCoordSource::Tex0: \
src = hsh::float4(vd->uvIn[0], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[0], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex1) { \
case MaterialTexCoordSource::Tex1: \
src = hsh::float4(vd->uvIn[1], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[1], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex2) { \
case MaterialTexCoordSource::Tex2: \
src = hsh::float4(vd->uvIn[2], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[2], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex3) { \
case MaterialTexCoordSource::Tex3: \
src = hsh::float4(vd->uvIn[3], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[3], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex4) { \
case MaterialTexCoordSource::Tex4: \
src = hsh::float4(vd->uvIn[4], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[4], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex5) { \
case MaterialTexCoordSource::Tex5: \
src = hsh::float4(vd->uvIn[5], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[5], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex6) { \
case MaterialTexCoordSource::Tex6: \
src = hsh::float4(vd->uvIn[6], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[6], 0.f, 1.f); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex7) { \
case MaterialTexCoordSource::Tex7: \
src = hsh::float4(vd->uvIn[7], 0.f, 1.f); \ src = hsh::float4(vd->uvIn[7], 0.f, 1.f); \
break; \
case MaterialTexCoordSource::Invalid: \
break; \
} \ } \
hsh::float3 tmp = ((*tcgu)[Pass##Traits::MtxIdx_].mtx * src).xyz(); \ hsh::float3 tmp = ((*tcgu)[Pass##Traits::MtxIdx_].mtx * src).xyz(); \
if constexpr (Pass##Traits::Normalize_) \ if constexpr (Pass##Traits::Normalize_) \
@ -606,39 +550,26 @@ struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, Ma
hsh::float4 tmpProj = (*tcgu)[Pass##Traits::MtxIdx_].postMtx * hsh::float4(tmp, 1.f); \ hsh::float4 tmpProj = (*tcgu)[Pass##Traits::MtxIdx_].postMtx * hsh::float4(tmp, 1.f); \
Pass##Uv = (tmpProj / tmpProj.w).xy(); \ Pass##Uv = (tmpProj / tmpProj.w).xy(); \
} else { \ } else { \
switch (Pass##Traits::Source_) { \ if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Position) { \
case MaterialTexCoordSource::Position: \
Pass##Uv = objPos.xy(); \ Pass##Uv = objPos.xy(); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Normal) { \
case MaterialTexCoordSource::Normal: \
Pass##Uv = objNorm.xy(); \ Pass##Uv = objNorm.xy(); \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex0) { \
case MaterialTexCoordSource::Tex0: \
Pass##Uv = vd->uvIn[0]; \ Pass##Uv = vd->uvIn[0]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex1) { \
case MaterialTexCoordSource::Tex1: \
Pass##Uv = vd->uvIn[1]; \ Pass##Uv = vd->uvIn[1]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex2) { \
case MaterialTexCoordSource::Tex2: \
Pass##Uv = vd->uvIn[2]; \ Pass##Uv = vd->uvIn[2]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex3) { \
case MaterialTexCoordSource::Tex3: \
Pass##Uv = vd->uvIn[3]; \ Pass##Uv = vd->uvIn[3]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex4) { \
case MaterialTexCoordSource::Tex4: \
Pass##Uv = vd->uvIn[4]; \ Pass##Uv = vd->uvIn[4]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex5) { \
case MaterialTexCoordSource::Tex5: \
Pass##Uv = vd->uvIn[5]; \ Pass##Uv = vd->uvIn[5]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex6) { \
case MaterialTexCoordSource::Tex6: \
Pass##Uv = vd->uvIn[6]; \ Pass##Uv = vd->uvIn[6]; \
break; \ } else if constexpr (Pass##Traits::Source_ == MaterialTexCoordSource::Tex7) { \
case MaterialTexCoordSource::Tex7: \
Pass##Uv = vd->uvIn[7]; \ Pass##Uv = vd->uvIn[7]; \
break; \
case MaterialTexCoordSource::Invalid: \
break; \
} \ } \
} \ } \
} }
@ -658,14 +589,10 @@ struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, Ma
} }
hsh::float3 lighting; hsh::float3 lighting;
switch (Post) { if constexpr (Post == EPostType::ThermalHot || Post == EPostType::ThermalCold || Post == EPostType::Solid ||
case EPostType::ThermalHot: Post == EPostType::MBShadow) {
case EPostType::ThermalCold:
case EPostType::Solid:
case EPostType::MBShadow:
lighting = hsh::float3(1.f); lighting = hsh::float3(1.f);
break; } else {
default:
lighting = fragu->ambient.xyz(); lighting = fragu->ambient.xyz();
for (int i = 0; i < URDE_MAX_LIGHTS; ++i) { for (int i = 0; i < URDE_MAX_LIGHTS; ++i) {
@ -685,19 +612,14 @@ struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, Ma
} }
lighting = hsh::saturate(lighting); lighting = hsh::saturate(lighting);
break;
} }
hsh::float3 DynReflectionSample HSH_VAR_STAGE(fragment); hsh::float3 DynReflectionSample HSH_VAR_STAGE(fragment);
if constexpr ((MaterialFlags & u32(CCubeMaterialFlagBits::fSamusReflectionIndirectTexture)) != 0) { if constexpr ((MaterialFlags & u32(CCubeMaterialFlagBits::fSamusReflectionIndirectTexture)) != 0) {
DynReflectionSample = dynReflection DynReflectionUv +=
.template sample<float>((ReflectionIndTex.sample<float>(DynReflectionIndUv, Samp).xw() - (ReflectionIndTex.sample<float>(DynReflectionIndUv, Samp).xw() - hsh::float2(0.5f)) * hsh::float2(0.5f);
hsh::float2(0.5f)) * DynReflectionSample =
hsh::float2(0.5f) + dynReflection.template sample<float>(DynReflectionUv, ReflectSamp).xyz() * refu->reflectAlpha;
DynReflectionUv,
ReflectSamp)
.xyz() *
refu->reflectAlpha;
} else if constexpr ((MaterialFlags & u32(CCubeMaterialFlagBits::fSamusReflection)) != 0) { } else if constexpr ((MaterialFlags & u32(CCubeMaterialFlagBits::fSamusReflection)) != 0) {
DynReflectionSample = DynReflectionSample =
dynReflection.template sample<float>(DynReflectionUv, ReflectSamp).xyz() * refu->reflectAlpha; dynReflection.template sample<float>(DynReflectionUv, ReflectSamp).xyz() * refu->reflectAlpha;
@ -705,70 +627,82 @@ struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, Ma
DynReflectionSample = hsh::float3(0.f); DynReflectionSample = hsh::float3(0.f);
} }
const hsh::float3 kRGBToYPrime = hsh::float3(0.257f, 0.504f, 0.098f); const hsh::float3 kRGBToYPrime = hsh::float3(0.299f, 0.587f, 0.114f);
#define Sample(Pass) \ #define Sample(Pass) \
(Pass##Traits::SampleAlpha_ \ (Pass##Traits::SampleAlpha_ \
? (Pass##Traits::ConstantColor_::Constant ? hsh::float3(Pass##Traits::ConstantColor_::A_) \ ? (Pass##Traits::ConstantColor_::Constant ? hsh::float3(Pass##Traits::ConstantColor_::A_) \
: hsh::float3(Pass.sample<float>(Pass##Uv, Samp).w)) \ : hsh::float3(Pass.sample<float>(Pass##Uv, Samp).w)) \
: (Pass##Traits::ConstantColor_::Constant ? Pass##Traits::ConstantColor_::RGB \ : (Pass##Traits::ConstantColor_::Constant \
: Pass.sample<float>(Pass##Uv, Samp).xyz())) ? hsh::float3(Pass##Traits::ConstantColor_::R_, Pass##Traits::ConstantColor_::G_, \
Pass##Traits::ConstantColor_::B_) \
: Pass.sample<float>(Pass##Uv, Samp).xyz()))
#define SampleAlpha(Pass) \ #define SampleAlpha(Pass) \
(Pass##Traits::SampleAlpha_ \ (Pass##Traits::SampleAlpha_ \
? (Pass##Traits::ConstantColor_::Constant ? Pass##Traits::ConstantColor_::A_ \ ? (Pass##Traits::ConstantColor_::Constant ? Pass##Traits::ConstantColor_::A_ \
: Pass.sample<float>(Pass##Uv, Samp).w) \ : Pass.sample<float>(Pass##Uv, Samp).w) \
: (Pass##Traits::ConstantColor_::Constant ? hsh::dot(Pass##Traits::ConstantColor_::RGB, kRGBToYPrime) \ : (Pass##Traits::ConstantColor_::Constant \
: hsh::dot(Pass.sample<float>(Pass##Uv, Samp).xyz(), kRGBToYPrime))) ? hsh::dot(hsh::float3(Pass##Traits::ConstantColor_::R_, Pass##Traits::ConstantColor_::G_, \
Pass##Traits::ConstantColor_::B_), \
kRGBToYPrime) \
: hsh::dot(Pass.sample<float>(Pass##Uv, Samp).xyz(), kRGBToYPrime)))
switch (Type) { if constexpr (Type == BlendMaterial::ShaderType::Invalid) {
case BlendMaterial::ShaderType::Invalid:
this->color_out[0] = hsh::float4(Sample(Diffuse), SampleAlpha(Alpha)); this->color_out[0] = hsh::float4(Sample(Diffuse), SampleAlpha(Alpha));
break; } else if constexpr (Type == BlendMaterial::ShaderType::RetroShader) {
case BlendMaterial::ShaderType::RetroShader: hsh::float3 rgb = Sample(Lightmap) * fragu->lightmapMul.xyz() + lighting;
this->color_out[0] = hsh::float4( rgb *= Sample(Diffuse);
(Sample(Lightmap) * fragu->lightmapMul.xyz() + lighting) * Sample(Diffuse) + Sample(Emissive) + rgb += Sample(Emissive);
(Sample(Specular) + Sample(ExtendedSpecular) * lighting) * Sample(Reflection) + DynReflectionSample, hsh::float3 specular = Sample(Specular) + Sample(ExtendedSpecular) * lighting;
SampleAlpha(Alpha)); rgb += specular * Sample(Reflection);
break; rgb += DynReflectionSample;
case BlendMaterial::ShaderType::RetroDynamicShader: this->color_out[0] = hsh::float4(rgb, SampleAlpha(Alpha));
this->color_out[0] = hsh::float4( } else if constexpr (Type == BlendMaterial::ShaderType::RetroDynamicShader) {
(Sample(Lightmap) * fragu->lightmapMul.xyz() + lighting) * (Sample(Diffuse) + Sample(Emissive)) * hsh::float3 rgb = Sample(Lightmap) * fragu->lightmapMul.xyz() + lighting;
fragu->lightmapMul.xyz() + rgb *= Sample(Diffuse) * Sample(Emissive);
(Sample(Specular) + Sample(ExtendedSpecular) * lighting) * Sample(Reflection) + DynReflectionSample, rgb *= fragu->lightmapMul.xyz();
SampleAlpha(Alpha)); hsh::float3 specular = Sample(Specular) + Sample(ExtendedSpecular) * lighting;
break; rgb += specular * Sample(Reflection);
case BlendMaterial::ShaderType::RetroDynamicAlphaShader: rgb += DynReflectionSample;
this->color_out[0] = hsh::float4( this->color_out[0] = hsh::float4(rgb, SampleAlpha(Alpha));
(Sample(Lightmap) * fragu->lightmapMul.xyz() + lighting) * (Sample(Diffuse) + Sample(Emissive)) * } else if constexpr (Type == BlendMaterial::ShaderType::RetroDynamicAlphaShader) {
fragu->lightmapMul.xyz() + hsh::float3 rgb = Sample(Lightmap) * fragu->lightmapMul.xyz() + lighting;
(Sample(Specular) + Sample(ExtendedSpecular) * lighting) * Sample(Reflection) + DynReflectionSample, rgb *= Sample(Diffuse) * Sample(Emissive);
SampleAlpha(Alpha) * fragu->lightmapMul.w); rgb *= fragu->lightmapMul.xyz();
break; hsh::float3 specular = Sample(Specular) + Sample(ExtendedSpecular) * lighting;
case BlendMaterial::ShaderType::RetroDynamicCharacterShader: rgb += specular * Sample(Reflection);
this->color_out[0] = hsh::float4( rgb += DynReflectionSample;
(Sample(Lightmap) + lighting) * Sample(Diffuse) + Sample(Emissive) * fragu->lightmapMul.xyz() + this->color_out[0] = hsh::float4(rgb, SampleAlpha(Alpha) * fragu->lightmapMul.w);
(Sample(Specular) + Sample(ExtendedSpecular) * lighting) * Sample(Reflection) + DynReflectionSample, } else if constexpr (Type == BlendMaterial::ShaderType::RetroDynamicCharacterShader) {
SampleAlpha(Alpha)); hsh::float3 rgb = Sample(Lightmap) + lighting;
break; rgb *= Sample(Diffuse);
rgb += Sample(Emissive) * fragu->lightmapMul.xyz();
hsh::float3 specular = Sample(Specular) + Sample(ExtendedSpecular) * lighting;
rgb += specular * Sample(Reflection);
rgb += DynReflectionSample;
this->color_out[0] = hsh::float4(rgb, SampleAlpha(Alpha));
} }
FOG_SHADER(fragu->fog) FOG_SHADER(fragu->fog)
if constexpr (Post == EPostType::Normal) { if constexpr (Post == EPostType::Normal) {
if constexpr (this->DstColorBlendFactor<0> == hsh::One) if constexpr (PipelineConfig::template DstColorBlendFactor<0> == hsh::One) {
this->color_out[0] = this->color_out[0] =
hsh::float4(hsh::lerp(this->color_out[0], hsh::float4(0.f), fogZ).xyz(), this->color_out[0].w); hsh::float4(hsh::lerp(this->color_out[0], hsh::float4(0.f), fogZ).xyz(), this->color_out[0].w);
else } else {
this->color_out[0] = this->color_out[0] =
hsh::float4(hsh::lerp(this->color_out[0], fragu->fog.m_color, fogZ).xyz(), this->color_out[0].w); hsh::float4(hsh::lerp(this->color_out[0], fragu->fog.m_color, fogZ).xyz(), this->color_out[0].w);
}
if constexpr (GameBlendMode == 2) { if constexpr (GameBlendMode == 2) {
if (this->DstColorBlendFactor<0> != hsh::One) if constexpr (PipelineConfig::template DstColorBlendFactor<0> != hsh::One) {
this->color_out[0] += fragu->flagsColor; this->color_out[0] += fragu->flagsColor;
}
} else if constexpr (GameBlendMode != 0) { } else if constexpr (GameBlendMode != 0) {
this->color_out[0] *= fragu->flagsColor; this->color_out[0] *= fragu->flagsColor;
} }
} else if constexpr (Post == EPostType::ThermalHot) { } else if constexpr (Post == EPostType::ThermalHot) {
this->color_out[0] = hsh::float4(ExtTex0.sample<float>(ExtUv0, Samp).x) * fragu->flagsColor + fragu->ambient; this->color_out[0] = hsh::float4(ExtTex0.sample<float>(ExtUv0, Samp).x) * fragu->flagsColor;
this->color_out[0] += fragu->ambient;
} else if constexpr (Post == EPostType::ThermalCold) { } else if constexpr (Post == EPostType::ThermalCold) {
this->color_out[0] *= hsh::float4(0.75f); this->color_out[0] *= hsh::float4(0.75f);
} else if constexpr (Post == EPostType::Solid) { } else if constexpr (Post == EPostType::Solid) {
@ -787,36 +721,113 @@ struct CModelShadersPipeline : CModelShadersPipelineConfig<MaterialBlendMode, Ma
hsh::float4 texel1 = ExtTex0.sample<float>(ExtUv1, Samp); hsh::float4 texel1 = ExtTex0.sample<float>(ExtUv1, Samp);
this->color_out[0] = hsh::lerp(hsh::float4(0.f), texel1, texel0); this->color_out[0] = hsh::lerp(hsh::float4(0.f), texel1, texel0);
this->color_out[0] = hsh::float4(fragu->flagsColor.xyz() + this->color_out[0].xyz(), this->color_out[0].w); this->color_out[0] = hsh::float4(fragu->flagsColor.xyz() + this->color_out[0].xyz(), this->color_out[0].w);
if constexpr (this->DstColorBlendFactor<0> == hsh::One) if constexpr (PipelineConfig::template DstColorBlendFactor<0> == hsh::One) {
this->color_out[0] = this->color_out[0] =
hsh::float4(hsh::lerp(this->color_out[0], hsh::float4(0.f), fogZ).xyz(), this->color_out[0].w); hsh::float4(hsh::lerp(this->color_out[0], hsh::float4(0.f), fogZ).xyz(), this->color_out[0].w);
else } else {
this->color_out[0] = this->color_out[0] =
hsh::float4(hsh::lerp(this->color_out[0], fragu->fog.m_color, fogZ).xyz(), this->color_out[0].w); hsh::float4(hsh::lerp(this->color_out[0], fragu->fog.m_color, fogZ).xyz(), this->color_out[0].w);
}
} }
if (this->AlphaTest && this->color_out[0].w < 0.25f) if (PipelineConfig::AlphaTest && this->color_out[0].w < 0.25f) {
hsh::discard(); hsh::discard();
}
} }
}; };
#if 0 void CModelShaders::SetCurrent(hsh::binding& binding, const CModelFlags& modelFlags, const CBooModel& model,
template <uint32_t NSkinSlots, uint32_t NCol, uint32_t NUv, uint32_t NWeight, EShaderType Type, EPostType Post, const ModelInstance& inst, const CBooSurface& surface) {
bool WorldShadow, class LightmapTraits, class DiffuseTraits,
class EmissiveTraits, class SpecularTraits, class ExtendedSpecularTraits, class ReflectionTraits,
class AlphaTraits, bool CubeReflection, MaterialBlendMode MaterialBlendMode, u32 MaterialFlags,
u8 GameBlendMode, u16 ModelFlags, bool ColorUpdate, bool AlphaUpdate, bool DstAlpha>
#endif
hsh::binding& CModelShaders::SetCurrent(const CModelFlags& modelFlags, const CBooSurface& surface, const CBooModel& model) {
const auto& material = model.x4_matSet->materials[surface.m_data.matIdx]; const auto& material = model.x4_matSet->materials[surface.m_data.matIdx];
const auto& vtxFmt = model.m_vtxFmt; const auto& vtxFmt = model.m_vtxFmt;
material.chunks
m_dataBind.hsh_bind(CModelShadersPipeline<vtxFmt.NSkinSlots, vtxFmt.NCol, vtxFmt.NUv, vtxFmt.NWeight, material.shaderType, std::array<MaterialTexCoordSource, 7> texSources{};
modelFlags.m_postType, CBooModel::g_shadowMap, >()); texSources.fill(MaterialTexCoordSource::Invalid);
return m_dataBind; std::array<bool, 7> normalize{};
std::array<bool, 7> alpha{};
std::array<hsh::texture2d, 12> texs{
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
g_Renderer->m_whiteTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->x220_sphereRamp.get(),
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
};
std::array<bool, 7> hasPassColor{};
std::array<std::array<u8, 4>, 7> passColors{};
std::array<uint32_t, 7> tcgMtxIdxs{};
tcgMtxIdxs.fill(-1);
uint32_t tcgMtxIdx = 0;
for (const auto& chunk : material.chunks) {
if (const auto& pass = chunk.get_if<Material::PASS>()) {
unsigned idx = Material::TexMapIdx(pass->type);
auto search = model.x1c_textures.find(pass->texId.toUint32());
if (search != model.x1c_textures.cend()) {
if (hsh::texture2d tex = search->second->GetBooTexture())
texs[idx] = tex;
}
texSources[idx] = MaterialTexCoordSource(pass->source);
normalize[idx] = pass->shouldNormalizeUv();
if (pass->uvAnimType != BlendMaterial::UVAnimType::Invalid)
tcgMtxIdxs[idx] = tcgMtxIdx;
tcgMtxIdx++;
alpha[idx] = pass->alpha;
} else if (const auto& clr = chunk.get_if<Material::CLR>()) {
passColors[Material::TexMapIdx(clr->type)] = {
static_cast<u8>(clr->color.simd[0] * 255.f),
static_cast<u8>(clr->color.simd[1] * 255.f),
static_cast<u8>(clr->color.simd[2] * 255.f),
static_cast<u8>(clr->color.simd[3] * 255.f),
};
hasPassColor[Material::TexMapIdx(clr->type)] = true;
}
}
hsh::uniform_buffer_typeless vu = inst.m_geometryUniforms[surface.m_data.skinMtxBankIdx].get();
auto refu = inst.m_reflectUniforms[surface.selfIdx].get();
auto tcgu = inst.m_tcgUniforms[surface.m_data.matIdx].get();
auto fragu = inst.m_fragmentUniform.get();
auto vd = inst.GetBooVBO(model);
if (modelFlags.m_postType == EPostType::ThermalHot) {
texs[8] = g_Renderer->x220_sphereRamp.get();
} else if (modelFlags.m_postType == EPostType::MBShadow) {
// texs[8] = g_Renderer->m_ballShadowId.get_color(0);
texs[9] = g_Renderer->x220_sphereRamp.get();
texs[10] = g_Renderer->m_ballFade;
} else if (modelFlags.m_postType == EPostType::Disintegrate && CBooModel::g_disintegrateTexture) {
texs[8] = CBooModel::g_disintegrateTexture;
} else if (CBooModel::g_shadowMap) {
texs[8] = CBooModel::g_shadowMap;
}
binding.hsh_bind(
CModelShadersPipeline<vtxFmt.NSkinSlots, vtxFmt.NCol, vtxFmt.NUv, vtxFmt.NWeight, material.shaderType,
modelFlags.m_postType, CBooModel::g_shadowMap,
PassTraits<texSources[0], normalize[0], tcgMtxIdxs[0], alpha[0],
ColorValue<hasPassColor[0], passColors[0][0], passColors[0][1], passColors[0][2],
passColors[0][3]>>, // lightmap
PassTraits<texSources[1], normalize[1], tcgMtxIdxs[1], alpha[1],
ColorValue<hasPassColor[1], passColors[1][0], passColors[1][1], passColors[1][2],
passColors[1][3]>>, // diffuse
PassTraits<texSources[2], normalize[2], tcgMtxIdxs[2], alpha[2],
ColorValue<hasPassColor[2], passColors[2][0], passColors[2][1], passColors[2][2],
passColors[2][3]>>, // emissive
PassTraits<texSources[3], normalize[3], tcgMtxIdxs[3], alpha[3],
ColorValue<hasPassColor[3], passColors[3][0], passColors[3][1], passColors[3][2],
passColors[3][3]>>, // specular
PassTraits<texSources[4], normalize[4], tcgMtxIdxs[4], alpha[4],
ColorValue<hasPassColor[4], passColors[4][0], passColors[4][1], passColors[4][2],
passColors[4][3]>>, // extended specular
PassTraits<texSources[5], normalize[5], tcgMtxIdxs[5], alpha[5],
ColorValue<hasPassColor[5], passColors[5][0], passColors[5][1], passColors[5][2],
passColors[5][3]>>, // reflection
PassTraits<texSources[6], normalize[6], tcgMtxIdxs[6], alpha[6],
ColorValue<hasPassColor[6], passColors[6][0], passColors[6][1], passColors[6][2],
passColors[6][3]>>, // alpha
false, // cube reflection
material.blendMode, material.flags.flags, modelFlags.x0_blendMode, modelFlags.x2_flags,
gx_ColorUpdate, gx_AlphaUpdate, gx_DstAlpha, gx_CullMode>(
vu, fragu, tcgu, refu, texs[0], texs[1], texs[2], texs[3], texs[4], texs[5], texs[6], texs[7], texs[8],
texs[9], texs[10], texs[11], vd, model.m_staticIbo));
} }
#if 0
struct CCubeMaterial { struct CCubeMaterial {
const u8* x0_data; const u8* x0_data;
static u32 sReflectionType; static u32 sReflectionType;
@ -1170,5 +1181,6 @@ struct CCubeMaterial {
// SetNumColorChans(finalNumColorChans); // SetNumColorChans(finalNumColorChans);
} }
}; };
#endif
} // namespace urde } // namespace urde

View File

@ -55,50 +55,46 @@ enum class EExtendedShader : uint8_t {
MAX MAX
}; };
enum class EShaderType : uint8_t { enum class EShaderType : uint8_t { DiffuseOnly, Normal, Dynamic, DynamicAlpha, DynamicCharacter };
DiffuseOnly,
Normal,
Dynamic,
DynamicAlpha,
DynamicCharacter
};
enum class EPostType : uint8_t { enum class EPostType : uint8_t { Normal, ThermalHot, ThermalCold, Solid, MBShadow, Disintegrate };
Normal,
ThermalHot, struct ModelInstance;
ThermalCold,
Solid,
MBShadow,
Disintegrate
};
class CModelShaders { class CModelShaders {
friend class CModel; friend class CModel;
hsh::binding m_dataBind;
public: public:
template <uint32_t NCol, uint32_t NUv, uint32_t NWeight> template <uint32_t NCol, uint32_t NUv, uint32_t NWeight>
struct VertData { struct VertData {
hsh::float3 posIn; hsh::float3 posIn;
hsh::float3 normIn; hsh::float3 normIn;
std::array<hsh::float4, NCol> colIn; // FIXME: compiler bug?
std::array<hsh::float2, NUv> uvIn; // [[no_unique_address]] hsh::array<hsh::float4, NCol> colIn;
std::array<hsh::float4, NWeight> weightIn; [[no_unique_address]] hsh::array<hsh::float2, NUv> uvIn;
[[no_unique_address]] hsh::array<hsh::float4, NWeight> weightIn;
}; };
static_assert(sizeof(VertData<0, 0, 0>) == 24, "VertData size incorrect");
static_assert(sizeof(VertData<0, 1, 0>) == 32, "VertData size incorrect");
static_assert(sizeof(VertData<0, 2, 0>) == 40, "VertData size incorrect");
static_assert(sizeof(VertData<0, 1, 1>) == 48, "VertData size incorrect");
template <uint32_t NSkinSlots> template <uint32_t NSkinSlots>
struct VertUniform { struct VertUniform {
std::array<hsh::float4x4, NSkinSlots> objs; hsh::array<hsh::float4x4, NSkinSlots> objs [[no_unique_address]];
std::array<hsh::float4x4, NSkinSlots> objsInv; hsh::array<hsh::float4x4, NSkinSlots> objsInv [[no_unique_address]];
hsh::float4x4 mv; hsh::float4x4 mv;
hsh::float4x4 mvInv; hsh::float4x4 mvInv;
hsh::float4x4 proj; hsh::float4x4 proj;
}; };
static_assert(sizeof(VertUniform<0>) == 192, "VertUniform size incorrect");
static_assert(sizeof(VertUniform<1>) == 320, "VertUniform size incorrect");
struct TCGMatrix { struct TCGMatrix {
hsh::float4x4 mtx; hsh::float4x4 mtx;
hsh::float4x4 postMtx; hsh::float4x4 postMtx;
}; };
using TCGMatrixUniform = std::array<CModelShaders::TCGMatrix, 8>;
struct ReflectMtx { struct ReflectMtx {
hsh::float4x4 indMtx; hsh::float4x4 indMtx;
@ -110,8 +106,8 @@ public:
alignas(16) hsh::float3 pos; alignas(16) hsh::float3 pos;
alignas(16) hsh::float3 dir; alignas(16) hsh::float3 dir;
alignas(16) hsh::float4 color; alignas(16) hsh::float4 color;
alignas(16) hsh::float3 linAtt; alignas(16) hsh::float3 linAtt{1.f, 0.f, 0.f};
alignas(16) hsh::float3 angAtt; alignas(16) hsh::float3 angAtt{1.f, 0.f, 0.f};
}; };
struct FragmentUniform { struct FragmentUniform {
@ -124,9 +120,22 @@ public:
void ActivateLights(const std::vector<CLight>& lts); void ActivateLights(const std::vector<CLight>& lts);
}; };
hsh::binding& SetCurrent(const CModelFlags& modelFlags, const CBooSurface& surface, const CBooModel& model); static void SetCurrent(hsh::binding& binding, const CModelFlags& modelFlags, const CBooModel& model,
const ModelInstance& inst, const CBooSurface& surface);
using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material; using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material;
}; };
struct ModelInstance {
hsh::dynamic_owner<hsh::uniform_buffer<CModelShaders::FragmentUniform>> m_fragmentUniform;
std::vector<hsh::dynamic_owner<hsh::uniform_buffer<CModelShaders::TCGMatrixUniform>>> m_tcgUniforms;
std::vector<hsh::dynamic_owner<hsh::uniform_buffer<CModelShaders::ReflectMtx>>> m_reflectUniforms;
std::vector<hsh::dynamic_owner<hsh::uniform_buffer_typeless>> m_geometryUniforms;
std::vector<hsh::binding> m_shaderDataBindings;
mutable hsh::dynamic_owner<hsh::vertex_buffer_typeless> m_dynamicVbo;
hsh::vertex_buffer_typeless GetBooVBO(const CBooModel& model) const;
};
} // namespace urde } // namespace urde