diff --git a/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp b/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp index c56dffe33..1b6a1b6c4 100644 --- a/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp @@ -14,7 +14,7 @@ struct NewIntroBoss : IScriptObject { Value scale; PatternedInfo patternedInfo; ActorParameters actorParameters; - Value turnRadius; + Value minTurnAngle; UniqueID32 weaponDesc; DamageInfo damageInfo; UniqueID32 beamContactFxId; diff --git a/Runtime/Camera/CFirstPersonCamera.cpp b/Runtime/Camera/CFirstPersonCamera.cpp index 0f749a2ee..6db68a749 100644 --- a/Runtime/Camera/CFirstPersonCamera.cpp +++ b/Runtime/Camera/CFirstPersonCamera.cpp @@ -98,7 +98,7 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt) { zeus::CTransform playerXf = player->GetTransform(); zeus::CVector3f rVec = playerXf.rotate( - {0.f, std::min(std::fabs(std::cos(x1c0_pitch)), 1.0f), std::min(std::fabs(std::sin(x1c0_pitch)), 1.0f)}); + {0.f, zeus::clamp(-1.f, std::cos(x1c0_pitch), 1.0f), zeus::clamp(-1.f, std::sin(x1c0_pitch), 1.0f)}); if (player->x3dc_inFreeLook) { float angle = player->x3ec_freeLookPitchAngle; float angleClamp = g_tweakPlayer->GetVerticalFreeLookAngleVel() - std::fabs(x1c0_pitch); diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index d3e0ee319..ec9dd2452 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -25,6 +25,7 @@ struct CModelFlags { EExtendedShader m_extendedShader = EExtendedShader::Lighting; bool m_noCull = false; bool m_noZWrite = false; + bool m_depthGreater = false; u16 x2_flags = 0; /* Flags */ zeus::CColor x4_color; /* Set into kcolor slot specified by material */ zeus::CColor addColor = zeus::CColor::skClear; diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 0409e549f..07d320708 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -531,19 +531,23 @@ static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data, if (flags.m_extendedShader == EExtendedShader::Lighting) { if (data.heclIr.m_blendSrc == boo::BlendFactor::One && data.heclIr.m_blendDst == boo::BlendFactor::Zero) { /* Override shader if originally opaque (typical for FRME models) */ - if (flags.x0_blendMode > 6) - extended = + if (flags.x0_blendMode > 6) { + if (flags.m_depthGreater) + extended = EExtendedShader::ForcedAdditiveNoZWriteDepthGreater; + else + extended = flags.m_noCull - ? (noZWrite ? EExtendedShader::ForcedAdditiveNoCullNoZWrite : EExtendedShader::ForcedAdditiveNoCull) - : (noZWrite ? EExtendedShader::ForcedAdditiveNoZWrite : EExtendedShader::ForcedAdditive); - else if (flags.x0_blendMode > 4) + ? (noZWrite ? EExtendedShader::ForcedAdditiveNoCullNoZWrite : EExtendedShader::ForcedAdditiveNoCull) + : (noZWrite ? EExtendedShader::ForcedAdditiveNoZWrite : EExtendedShader::ForcedAdditive); + } else if (flags.x0_blendMode > 4) { extended = flags.m_noCull - ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) - : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::ForcedAlpha); - else + ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) + : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::ForcedAlpha); + } else { extended = flags.m_noCull - ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) - : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::Lighting); + ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) + : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::Lighting); + } } else if (flags.m_noCull && noZWrite) { /* Substitute no-cull,no-zwrite pipeline if available */ if (data.heclIr.m_blendDst == boo::BlendFactor::One) diff --git a/Runtime/Graphics/Shaders/CColoredStripShader.cpp b/Runtime/Graphics/Shaders/CColoredStripShader.cpp index 0c2cb2bc1..bfb86b819 100644 --- a/Runtime/Graphics/Shaders/CColoredStripShader.cpp +++ b/Runtime/Graphics/Shaders/CColoredStripShader.cpp @@ -9,17 +9,20 @@ namespace urde { static boo::ObjToken s_Pipeline; static boo::ObjToken s_AdditivePipeline; static boo::ObjToken s_FullAdditivePipeline; +static boo::ObjToken s_SubtractivePipeline; void CColoredStripShader::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CColoredStripShader{}); s_AdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderAdditive{}); s_FullAdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderFullAdditive{}); + s_SubtractivePipeline = hecl::conv->convert(Shader_CColoredStripShaderSubtractive{}); } void CColoredStripShader::Shutdown() { s_Pipeline.reset(); s_AdditivePipeline.reset(); s_FullAdditivePipeline.reset(); + s_SubtractivePipeline.reset(); } static const boo::ObjToken& SelectPipeline(CColoredStripShader::Mode mode) { @@ -31,6 +34,8 @@ static const boo::ObjToken& SelectPipeline(CColoredStripSh return s_AdditivePipeline; case CColoredStripShader::Mode::FullAdditive: return s_FullAdditivePipeline; + case CColoredStripShader::Mode::Subtractive: + return s_SubtractivePipeline; } } diff --git a/Runtime/Graphics/Shaders/CColoredStripShader.hpp b/Runtime/Graphics/Shaders/CColoredStripShader.hpp index 6530c01ee..aa4c8116e 100644 --- a/Runtime/Graphics/Shaders/CColoredStripShader.hpp +++ b/Runtime/Graphics/Shaders/CColoredStripShader.hpp @@ -12,7 +12,8 @@ public: enum class Mode { Alpha, Additive, - FullAdditive + FullAdditive, + Subtractive }; private: struct Uniform { diff --git a/Runtime/Graphics/Shaders/CModelShaders.cpp b/Runtime/Graphics/Shaders/CModelShaders.cpp index 3dce58a16..58ccdc7ae 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.cpp +++ b/Runtime/Graphics/Shaders/CModelShaders.cpp @@ -140,7 +140,10 @@ static hecl::Backend::ExtensionSlot g_ExtensionSlots[] = { /* Disintegration */ {1, BlockNames, 2, DisintegrateTextures, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false, - false, true, false, false, true}}; + false, true, false, false, true}, + /* Forced additive shading without culling or Z-write and greater depth test */ + {1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, + hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::None, true, false, true}}; extern const hecl::Backend::Function ExtensionLightingFuncsGLSL[]; extern const hecl::Backend::Function ExtensionPostFuncsGLSL[]; diff --git a/Runtime/Graphics/Shaders/CModelShaders.hpp b/Runtime/Graphics/Shaders/CModelShaders.hpp index d004647d2..8aa248fd8 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.hpp +++ b/Runtime/Graphics/Shaders/CModelShaders.hpp @@ -34,6 +34,7 @@ enum EExtendedShader : uint8_t { ForcedAdditiveNoCullNoZWrite, DepthGEqualNoZWrite, Disintegrate, + ForcedAdditiveNoZWriteDepthGreater, MAX }; diff --git a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp index a97494a3b..dfc5bf980 100644 --- a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp @@ -238,6 +238,7 @@ const hecl::Backend::Function ExtensionLightingFuncsGLSL[] = { {LightingGLSL, "LightingFunc"}, {LightingGLSL, "LightingFunc"}, {}, + {LightingGLSL, "LightingFunc"}, }; const hecl::Backend::Function ExtensionPostFuncsGLSL[] = { @@ -262,6 +263,7 @@ const hecl::Backend::Function ExtensionPostFuncsGLSL[] = { {MainPostGLSL, "MainPostFunc"}, {MainPostGLSL, "MainPostFunc"}, {DisintegratePostGLSL, "DisintegratePostFunc"}, + {MainPostGLSL, "MainPostFunc"}, }; } // namespace urde diff --git a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp index 6ad783999..0584bc1d3 100644 --- a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp @@ -6,6 +6,46 @@ using namespace std::literals; extern const hecl::Backend::Function ExtensionLightingFuncsHLSL[]; extern const hecl::Backend::Function ExtensionPostFuncsHLSL[]; +#define FOG_STRUCT_HLSL \ + "struct Fog\n" \ + "{\n" \ + " int mode;\n" \ + " float4 color;\n" \ + " float rangeScale;\n" \ + " float start;\n" \ + "};\n" + +#define FOG_ALGORITHM_HLSL \ + " float fogZ, temp;\n" \ + " switch (fog.mode)\n" \ + " {\n" \ + " case 2:\n" \ + " fogZ = (-vtf.mvPos.z - fog.start) * fog.rangeScale;\n" \ + " break;\n" \ + " case 4:\n" \ + " fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - fog.start) * fog.rangeScale);\n" \ + " break;\n" \ + " case 5:\n" \ + " temp = (-vtf.mvPos.z - fog.start) * fog.rangeScale;\n" \ + " fogZ = 1.0 - exp2(-8.0 * temp * temp);\n" \ + " break;\n" \ + " case 6:\n" \ + " fogZ = exp2(-8.0 * (fog.start + vtf.mvPos.z) * fog.rangeScale);\n" \ + " break;\n" \ + " case 7:\n" \ + " temp = (fog.start + vtf.mvPos.z) * fog.rangeScale;\n" \ + " fogZ = exp2(-8.0 * temp * temp);\n" \ + " break;\n" \ + " default:\n" \ + " fogZ = 0.0;\n" \ + " break;\n" \ + " }\n" \ + "#ifdef BLEND_DST_ONE\n" \ + " return float4(lerp(colorIn, float4(0.0, 0.0, 0.0, 0.0), saturate(fogZ)).rgb, colorIn.a);\n" \ + "#else\n" \ + " return float4(lerp(colorIn, fog.color, saturate(fogZ)).rgb, colorIn.a);\n" \ + "#endif\n" + static std::string_view LightingHLSL = "struct Light\n" "{\n" @@ -15,13 +55,7 @@ static std::string_view LightingHLSL = " float4 linAtt;\n" " float4 angAtt;\n" "};\n" -"struct Fog\n" -"{\n" -" int mode;\n" -" float4 color;\n" -" float rangeScale;\n" -" float start;\n" -"};\n" +FOG_STRUCT_HLSL "\n" "cbuffer LightingUniform : register(b2)\n" "{\n" @@ -118,36 +152,7 @@ static std::string_view LightingShadowHLSL = static std::string_view MainPostHLSL = "static float4 MainPostFunc(in VertToFrag vtf, float4 colorIn)\n" - "{\n" - " float fogZ, temp;\n" - " switch (fog.mode)\n" - " {\n" - " case 2:\n" - " fogZ = (-vtf.mvPos.z - fog.start) * fog.rangeScale;\n" - " break;\n" - " case 4:\n" - " fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - fog.start) * fog.rangeScale);\n" - " break;\n" - " case 5:\n" - " temp = (-vtf.mvPos.z - fog.start) * fog.rangeScale;\n" - " fogZ = 1.0 - exp2(-8.0 * temp * temp);\n" - " break;\n" - " case 6:\n" - " fogZ = exp2(-8.0 * (fog.start + vtf.mvPos.z) * fog.rangeScale);\n" - " break;\n" - " case 7:\n" - " temp = (fog.start + vtf.mvPos.z) * fog.rangeScale;\n" - " fogZ = exp2(-8.0 * temp * temp);\n" - " break;\n" - " default:\n" - " fogZ = 0.0;\n" - " break;\n" - " }\n" - "#ifdef BLEND_DST_ONE\n" - " return float4(lerp(colorIn, float4(0.0, 0.0, 0.0, 0.0), saturate(fogZ)).rgb, colorIn.a);\n" - "#else\n" - " return float4(lerp(colorIn, fog.color, saturate(fogZ)).rgb, colorIn.a);\n" - "#endif\n" + "{\n" FOG_ALGORITHM_HLSL "}\n" "\n"sv; @@ -193,6 +198,21 @@ static std::string_view MBShadowPostHLSL = "}\n" "\n"sv; +static std::string_view DisintegratePostHLSL = FOG_STRUCT_HLSL + "cbuffer DisintegrateUniform : register(b2)\n" + "{\n" + " float4 addColor;\n" + " Fog fog;\n" + "};\n" + "float4 DisintegratePostFunc(float4 colorIn)\n" + "{\n" + " float4 texel0 = extTex7.Sample(samp, vtf.extTcgs[0]);\n" + " float4 texel1 = extTex7.Sample(samp, vtf.extTcgs[1]);\n" + " colorIn = mix(float4(0.0), texel1, texel0);\n" + " colorIn.rgb += addColor.rgb;\n" FOG_ALGORITHM_HLSL + "}\n" + "\n"sv; + const hecl::Backend::Function ExtensionLightingFuncsHLSL[] = {{}, {LightingHLSL, "LightingFunc"}, {}, @@ -212,6 +232,8 @@ const hecl::Backend::Function ExtensionLightingFuncsHLSL[] = {{}, {LightingHLSL, "LightingFunc"}, {LightingHLSL, "LightingFunc"}, {LightingHLSL, "LightingFunc"}, + {LightingHLSL, "LightingFunc"}, + {}, {LightingHLSL, "LightingFunc"}}; const hecl::Backend::Function ExtensionPostFuncsHLSL[] = { @@ -235,6 +257,8 @@ const hecl::Backend::Function ExtensionPostFuncsHLSL[] = { {MainPostHLSL, "MainPostFunc"}, {MainPostHLSL, "MainPostFunc"}, {MainPostHLSL, "MainPostFunc"}, + {DisintegratePostHLSL, "DisintegratePostFunc"}, + {MainPostHLSL, "MainPostFunc"}, }; } // namespace urde diff --git a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp index cedc598b2..2ee671292 100644 --- a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp @@ -6,6 +6,46 @@ using namespace std::literals; extern const hecl::Backend::Function ExtensionLightingFuncsMetal[]; extern const hecl::Backend::Function ExtensionPostFuncsMetal[]; +#define FOG_STRUCT_METAL \ + "struct Fog\n" \ + "{\n" \ + " int mode;\n" \ + " float4 color;\n" \ + " float rangeScale;\n" \ + " float start;\n" \ + "};\n" + +#define FOG_ALGORITHM_METAL \ + " float fogZ, temp;\n" \ + " switch (lu.fog.mode)\n" \ + " {\n" \ + " case 2:\n" \ + " fogZ = (-vtf.mvPos.z - lu.fog.start) * lu.fog.rangeScale;\n" \ + " break;\n" \ + " case 4:\n" \ + " fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - lu.fog.start) * lu.fog.rangeScale);\n" \ + " break;\n" \ + " case 5:\n" \ + " temp = (-vtf.mvPos.z - lu.fog.start) * lu.fog.rangeScale;\n" \ + " fogZ = 1.0 - exp2(-8.0 * temp * temp);\n" \ + " break;\n" \ + " case 6:\n" \ + " fogZ = exp2(-8.0 * (lu.fog.start + vtf.mvPos.z) * lu.fog.rangeScale);\n" \ + " break;\n" \ + " case 7:\n" \ + " temp = (lu.fog.start + vtf.mvPos.z) * lu.fog.rangeScale;\n" \ + " fogZ = exp2(-8.0 * temp * temp);\n" \ + " break;\n" \ + " default:\n" \ + " fogZ = 0.0;\n" \ + " break;\n" \ + " }\n" \ + "#ifdef BLEND_DST_ONE\n" \ + " return float4(mix(colorIn, float4(0.0), saturate(fogZ)).rgb, colorIn.a);\n" \ + "#else\n" \ + " return float4(mix(colorIn, lu.fog.color, saturate(fogZ)).rgb, colorIn.a);\n" \ + "#endif\n" + static std::string_view LightingMetal = "struct Light\n" "{\n" @@ -15,13 +55,7 @@ static std::string_view LightingMetal = " float4 linAtt;\n" " float4 angAtt;\n" "};\n" -"struct Fog\n" -"{\n" -" int mode;\n" -" float4 color;\n" -" float rangeScale;\n" -" float start;\n" -"};\n" +FOG_STRUCT_METAL "\n" "struct LightingUniform\n" "{\n" @@ -119,36 +153,7 @@ static std::string_view LightingShadowMetal = static std::string_view MainPostMetal = "float4 MainPostFunc(thread VertToFrag& vtf, constant LightingUniform& lu, float4 colorIn)\n" - "{\n" - " float fogZ, temp;\n" - " switch (lu.fog.mode)\n" - " {\n" - " case 2:\n" - " fogZ = (-vtf.mvPos.z - lu.fog.start) * lu.fog.rangeScale;\n" - " break;\n" - " case 4:\n" - " fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - lu.fog.start) * lu.fog.rangeScale);\n" - " break;\n" - " case 5:\n" - " temp = (-vtf.mvPos.z - lu.fog.start) * lu.fog.rangeScale;\n" - " fogZ = 1.0 - exp2(-8.0 * temp * temp);\n" - " break;\n" - " case 6:\n" - " fogZ = exp2(-8.0 * (lu.fog.start + vtf.mvPos.z) * lu.fog.rangeScale);\n" - " break;\n" - " case 7:\n" - " temp = (lu.fog.start + vtf.mvPos.z) * lu.fog.rangeScale;\n" - " fogZ = exp2(-8.0 * temp * temp);\n" - " break;\n" - " default:\n" - " fogZ = 0.0;\n" - " break;\n" - " }\n" - "#ifdef BLEND_DST_ONE\n" - " return float4(mix(colorIn, float4(0.0), saturate(fogZ)).rgb, colorIn.a);\n" - "#else\n" - " return float4(mix(colorIn, lu.fog.color, saturate(fogZ)).rgb, colorIn.a);\n" - "#endif\n" + "{\n" FOG_ALGORITHM_METAL "}\n" "\n"sv; @@ -184,10 +189,9 @@ static std::string_view MBShadowPostMetal = " float4 shadowUp;\n" " float shadowId;\n" "};\n" - "static float4 EXTMBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su, sampler samp, sampler " - "clampSamp,\n" - " texture2d extTex0, texture2d extTex1, texture2d extTex2, " - "float4 colorIn)\n" + "static float4 EXTMBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su, sampler samp,\n" + " sampler clampSamp, texture2d extTex0, texture2d extTex1,\n" + " texture2d extTex2, float4 colorIn)\n" "{\n" " float idTexel = extTex0.sample(samp, vtf.extTcgs0).a;\n" " float sphereTexel = extTex1.sample(samp, vtf.extTcgs1).a;\n" @@ -199,6 +203,22 @@ static std::string_view MBShadowPostMetal = "}\n" "\n"sv; +static std::string_view DisintegratePostMetal = FOG_STRUCT_METAL + "struct DisintegrateUniform\n" + "{\n" + " float4 addColor;\n" + " Fog fog;\n" + "};\n" + "static float4 EXTDisintegratePostFunc(thread VertToFrag& vtf, constant DisintegrateUniform& lu, sampler samp,\n" + " sampler clampSamp, texture2d extTex7, float4 colorIn)\n" + "{\n" + " float4 texel0 = extTex7.sample(samp, vtf.extTcgs[0]);\n" + " float4 texel1 = extTex7.sample(samp, vtf.extTcgs[1]);\n" + " colorIn = mix(float4(0.0), texel1, texel0);\n" + " colorIn.rgb += addColor.rgb;\n" FOG_ALGORITHM_METAL + "}\n" + "\n"sv; + const hecl::Backend::Function ExtensionLightingFuncsMetal[] = {{}, {LightingMetal, "LightingFunc"}, {}, @@ -218,6 +238,8 @@ const hecl::Backend::Function ExtensionLightingFuncsMetal[] = {{}, {LightingMetal, "LightingFunc"}, {LightingMetal, "LightingFunc"}, {LightingMetal, "LightingFunc"}, + {LightingMetal, "LightingFunc"}, + {}, {LightingMetal, "LightingFunc"}}; const hecl::Backend::Function ExtensionPostFuncsMetal[] = { @@ -241,6 +263,8 @@ const hecl::Backend::Function ExtensionPostFuncsMetal[] = { {MainPostMetal, "MainPostFunc"}, {MainPostMetal, "MainPostFunc"}, {MainPostMetal, "MainPostFunc"}, + {DisintegratePostMetal, "EXTDisintegratePostFunc"}, + {MainPostMetal, "MainPostFunc"}, }; static const char* BlockNames[] = {"LightingUniform"}; diff --git a/Runtime/GuiSys/CGuiModel.cpp b/Runtime/GuiSys/CGuiModel.cpp index a038cf291..0f6d9164a 100644 --- a/Runtime/GuiSys/CGuiModel.cpp +++ b/Runtime/GuiSys/CGuiModel.cpp @@ -74,6 +74,7 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const { CModelFlags flags(7, 0, (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest), moduCol); flags.m_noCull = !xb6_29_cullFaces; flags.m_noZWrite = !xb7_24_depthWrite; + flags.m_depthGreater = xb6_30_depthGreater; model->Draw(flags); break; } diff --git a/Runtime/MP1/World/CNewIntroBoss.cpp b/Runtime/MP1/World/CNewIntroBoss.cpp index 0b51c2f7b..a3e017291 100644 --- a/Runtime/MP1/World/CNewIntroBoss.cpp +++ b/Runtime/MP1/World/CNewIntroBoss.cpp @@ -14,11 +14,11 @@ namespace urde::MP1 { CNewIntroBoss::CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - float turnRadius, CAssetId projectile, const CDamageInfo& dInfo, CAssetId beamContactFxId, + float minTurnAngle, CAssetId projectile, const CDamageInfo& dInfo, CAssetId beamContactFxId, CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId) : CPatterned(ECharacter::NewIntroBoss, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Flyer, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Medium) -, x570_turnRadius(turnRadius) +, x570_minTurnAngle(minTurnAngle) , x574_boneTracking(*GetModelData()->GetAnimationData(), "Head_1"sv, zeus::degToRad(80.f), zeus::degToRad(180.f), false) , x5ac_projectileInfo(projectile, dInfo) , x5f0_beamContactFxId(beamContactFxId) @@ -328,7 +328,7 @@ bool CNewIntroBoss::ShouldTurn(CStateManager& mgr, float dt) { zeus::CVector2f diffPos = (x604_predictedPlayerPos - GetTranslation()).toVec2f(); return zeus::CVector2f::getAngleDiff(GetTransform().frontVector().toVec2f(), diffPos) > - zeus::degToRad(x570_turnRadius); + zeus::degToRad(x570_minTurnAngle); } bool CNewIntroBoss::ShouldAttack(CStateManager& mgr, float dt) { diff --git a/Runtime/MP1/World/CNewIntroBoss.hpp b/Runtime/MP1/World/CNewIntroBoss.hpp index 81553bb74..4dab6b3be 100644 --- a/Runtime/MP1/World/CNewIntroBoss.hpp +++ b/Runtime/MP1/World/CNewIntroBoss.hpp @@ -12,7 +12,7 @@ namespace MP1 { class CNewIntroBoss : public CPatterned { pas::ELocomotionType x568_locomotion = pas::ELocomotionType::Relaxed; u32 x56c_stateProg = 0; - float x570_turnRadius; + float x570_minTurnAngle; CBoneTracking x574_boneTracking; CProjectileInfo x5ac_projectileInfo; TUniqueId x5d4_stage1Projectile = kInvalidUniqueId; @@ -49,7 +49,7 @@ public: DEFINE_PATTERNED(NewIntroBoss) CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - float turnRadius, CAssetId projectile, const CDamageInfo& dInfo, CAssetId beamContactFxId, + float minTurnAngle, CAssetId projectile, const CDamageInfo& dInfo, CAssetId beamContactFxId, CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId); void Accept(IVisitor& visitor); diff --git a/Runtime/Weapon/CPlasmaProjectile.cpp b/Runtime/Weapon/CPlasmaProjectile.cpp index 834df64c1..d3547da27 100644 --- a/Runtime/Weapon/CPlasmaProjectile.cpp +++ b/Runtime/Weapon/CPlasmaProjectile.cpp @@ -17,6 +17,10 @@ CPlasmaProjectile::RenderObjects::RenderObjects(boo::IGraphicsDataFactory::Conte , m_beamStrip2(ctx, 10, CColoredStripShader::Mode::FullAdditive, tex) , m_beamStrip3(ctx, 18, CColoredStripShader::Mode::FullAdditive, tex) , m_beamStrip4(ctx, 14, CColoredStripShader::Mode::Additive, glowTex) +, m_beamStrip1Sub(ctx, 8, CColoredStripShader::Mode::Subtractive, {}) +, m_beamStrip2Sub(ctx, 10, CColoredStripShader::Mode::Subtractive, tex) +, m_beamStrip3Sub(ctx, 18, CColoredStripShader::Mode::Subtractive, tex) +, m_beamStrip4Sub(ctx, 14, CColoredStripShader::Mode::Subtractive, glowTex) , m_motionBlurStrip(ctx, 16, CColoredStripShader::Mode::Alpha, {}) {} CPlasmaProjectile::CPlasmaProjectile(const TToken& wDesc, std::string_view name, EWeaponType wType, @@ -418,19 +422,23 @@ void CPlasmaProjectile::Render(const CStateManager& mgr) const { // Pass1: alpha-controlled additive CGraphics::SetModelMatrix(xf); - RenderBeam(3, 0.25f * x4b8_beamWidth, zeus::CColor(1.f, 0.3f), flags | 0x4, m_renderObjs->m_beamStrip1); + RenderBeam(3, 0.25f * x4b8_beamWidth, zeus::CColor(1.f, 0.3f), flags | 0x4, + (flags & 0x10) ? m_renderObjs->m_beamStrip1Sub : m_renderObjs->m_beamStrip1); // Pass2: textured CGraphics::SetModelMatrix(xf * zeus::CTransform::RotateY(zeus::degToRad(x4c8_beamAngle))); - RenderBeam(4, 0.5f * x4b8_beamWidth, x490_innerColor, flags | 0x1, m_renderObjs->m_beamStrip2); + RenderBeam(4, 0.5f * x4b8_beamWidth, x490_innerColor, flags | 0x1, + (flags & 0x10) ? m_renderObjs->m_beamStrip2Sub : m_renderObjs->m_beamStrip2); // Pass3: textured | length-controlled UVY CGraphics::SetModelMatrix(xf * zeus::CTransform::RotateY(zeus::degToRad(-x4c8_beamAngle))); - RenderBeam(8, x4b8_beamWidth, x494_outerColor, flags | 0x3, m_renderObjs->m_beamStrip3); + RenderBeam(8, x4b8_beamWidth, x494_outerColor, flags | 0x3, + (flags & 0x10) ? m_renderObjs->m_beamStrip3Sub : m_renderObjs->m_beamStrip3); // Pass4: textured | alpha-controlled additive | glow texture CGraphics::SetModelMatrix(xf); - RenderBeam(6, 1.25f * x4b8_beamWidth, x494_outerColor, flags | 0xd, m_renderObjs->m_beamStrip4); + RenderBeam(6, 1.25f * x4b8_beamWidth, x494_outerColor, flags | 0xd, + (flags & 0x10) ? m_renderObjs->m_beamStrip4Sub : m_renderObjs->m_beamStrip4); } } // namespace urde diff --git a/Runtime/Weapon/CPlasmaProjectile.hpp b/Runtime/Weapon/CPlasmaProjectile.hpp index 6c3c87431..087e969e2 100644 --- a/Runtime/Weapon/CPlasmaProjectile.hpp +++ b/Runtime/Weapon/CPlasmaProjectile.hpp @@ -74,6 +74,10 @@ private: CColoredStripShader m_beamStrip2; CColoredStripShader m_beamStrip3; CColoredStripShader m_beamStrip4; + CColoredStripShader m_beamStrip1Sub; + CColoredStripShader m_beamStrip2Sub; + CColoredStripShader m_beamStrip3Sub; + CColoredStripShader m_beamStrip4Sub; CColoredStripShader m_motionBlurStrip; RenderObjects(boo::IGraphicsDataFactory::Context& ctx, boo::ObjToken tex, diff --git a/Runtime/World/CActorModelParticles.cpp b/Runtime/World/CActorModelParticles.cpp index 82d703101..41ff7d20b 100644 --- a/Runtime/World/CActorModelParticles.cpp +++ b/Runtime/World/CActorModelParticles.cpp @@ -646,7 +646,8 @@ void CActorModelParticles::Render(const CStateManager& mgr, const CActor& actor) } if (mgr.GetThermalDrawFlag() != EThermalDrawFlag::Cold) { for (const auto& gen : search->x8_onFireGens) - gen.first->Render(); + if (gen.first) + gen.first->Render(); if (mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot && search->x78_ashGen) search->x78_ashGen->Render(); if (search->xb8_firePopGen) diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 0b8e55b7f..54e0328ae 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -790,7 +790,7 @@ CEntity* ScriptLoader::LoadNewIntroBoss(CStateManager& mgr, CInputStream& in, in CActorParameters actParms = LoadActorParameters(in); - float turnRadius = in.readFloatBig(); + float minTurnAngle = in.readFloatBig(); CAssetId projectile(in); CDamageInfo dInfo(in); @@ -808,7 +808,7 @@ CEntity* ScriptLoader::LoadNewIntroBoss(CStateManager& mgr, CInputStream& in, in CAnimRes res(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), true); return new MP1::CNewIntroBoss(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, res, pInfo, actParms, - turnRadius, projectile, dInfo, beamContactFxId, beamPulseFxId, beamTextureId, + minTurnAngle, projectile, dInfo, beamContactFxId, beamPulseFxId, beamTextureId, beamGlowTextureId); } diff --git a/Shaders/CColoredStripShader.shader b/Shaders/CColoredStripShader.shader index 16487bef7..16401b019 100644 --- a/Shaders/CColoredStripShader.shader +++ b/Shaders/CColoredStripShader.shader @@ -149,3 +149,7 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]], #shader CColoredStripShaderFullAdditive : CColoredStripShader #srcfac one #dstfac one + +#shader CColoredStripShaderSubtractive : CColoredStripShader +#srcfac subtract +#dstfac subtract