Various bug fixes

This commit is contained in:
Jack Andersen 2019-01-04 22:34:09 -10:00
parent d60fcc99c9
commit f9b0614327
19 changed files with 187 additions and 104 deletions

View File

@ -14,7 +14,7 @@ struct NewIntroBoss : IScriptObject {
Value<atVec3f> scale;
PatternedInfo patternedInfo;
ActorParameters actorParameters;
Value<float> turnRadius;
Value<float> minTurnAngle;
UniqueID32 weaponDesc;
DamageInfo damageInfo;
UniqueID32 beamContactFxId;

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -9,17 +9,20 @@ namespace urde {
static boo::ObjToken<boo::IShaderPipeline> s_Pipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AdditivePipeline;
static boo::ObjToken<boo::IShaderPipeline> s_FullAdditivePipeline;
static boo::ObjToken<boo::IShaderPipeline> 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<boo::IShaderPipeline>& SelectPipeline(CColoredStripShader::Mode mode) {
@ -31,6 +34,8 @@ static const boo::ObjToken<boo::IShaderPipeline>& SelectPipeline(CColoredStripSh
return s_AdditivePipeline;
case CColoredStripShader::Mode::FullAdditive:
return s_FullAdditivePipeline;
case CColoredStripShader::Mode::Subtractive:
return s_SubtractivePipeline;
}
}

View File

@ -12,7 +12,8 @@ public:
enum class Mode {
Alpha,
Additive,
FullAdditive
FullAdditive,
Subtractive
};
private:
struct Uniform {

View File

@ -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[];

View File

@ -34,6 +34,7 @@ enum EExtendedShader : uint8_t {
ForcedAdditiveNoCullNoZWrite,
DepthGEqualNoZWrite,
Disintegrate,
ForcedAdditiveNoZWriteDepthGreater,
MAX
};

View File

@ -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

View File

@ -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

View File

@ -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<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2, "
"float4 colorIn)\n"
"static float4 EXTMBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su, sampler samp,\n"
" sampler clampSamp, texture2d<float> extTex0, texture2d<float> extTex1,\n"
" texture2d<float> 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<float> 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"};

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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<CWeaponDescription>& 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

View File

@ -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<boo::ITexture> tex,

View File

@ -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)

View File

@ -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);
}

View File

@ -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