From d11f8122f3cced82511cd09fa33125a599c72ed6 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 18 Sep 2022 15:37:22 +0200 Subject: [PATCH] Differ between multiple particle_cloud modes --- raw/iw4/statemaps/wip_particle_cloud.sm | 82 +++++++++++++++++++ .../techniques/particle_cloud.tech.template | 2 +- src/ObjCommon/Game/IW4/MaterialConstantsIW4.h | 6 ++ .../IW4/AssetLoaders/AssetLoaderMaterial.cpp | 35 ++++++-- .../IW4/AssetDumpers/AssetDumperMaterial.cpp | 74 +++++++++++++++++ 5 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 raw/iw4/statemaps/wip_particle_cloud.sm diff --git a/raw/iw4/statemaps/wip_particle_cloud.sm b/raw/iw4/statemaps/wip_particle_cloud.sm new file mode 100644 index 00000000..9d5f729f --- /dev/null +++ b/raw/iw4/statemaps/wip_particle_cloud.sm @@ -0,0 +1,82 @@ +// WIP +// Based on default +// Can merge back if possible + +alphaTest +{ + mtlAlphaTest == Always && mtlBlendOp == Add && mtlSrcBlend == SrcAlpha && mtlDestBlend == InvSrcAlpha: // Used + mtlAlphaTest == Always && mtlBlendOp == Add && mtlSrcBlend == SrcAlpha && mtlDestBlend == One: // Used + GT0; + default: + passthrough; +} + +blendFunc +{ + default: + passthrough; +} + +separateAlphaBlendFunc +{ + mtlBlendOp == Disable: // Unused + Disable, One, Zero; + + mtlAlphaTest == Disable: // Used + Add, Zero, One; + + default: + Add, InvDestAlpha, One; +} + +cullFace +{ + default: + passthrough; +} + +depthTest +{ + default: + passthrough; // Always lessEqual, might be coincidence because it is default +} + +depthWrite +{ + mtlBlendOp == Disable: + Enable; + default: + Disable; +} + +colorWrite +{ + mtlPolygonOffset == 0: + Enable, Enable; + default: + Enable, Enable; +} + +gammaWrite +{ + default: + passthrough; // Always false, might be coincidence because it is default +} + +polygonOffset +{ + default: + passthrough; +} + +stencil +{ + default: + passthrough; +} + +wireframe +{ + default: + Disable; +} diff --git a/raw/iw4/techniques/particle_cloud.tech.template b/raw/iw4/techniques/particle_cloud.tech.template index 41e22e6e..cec68295 100644 --- a/raw/iw4/techniques/particle_cloud.tech.template +++ b/raw/iw4/techniques/particle_cloud.tech.template @@ -44,7 +44,7 @@ #set PIXEL_SHADER "particle_cloud" + SPARK_SUFFIX + OUTDOOR_SUFFIX + SPOT_SUFFIX + SHADOW_SUFFIX + PREMUL_SUFFIX + ".hlsl" { - stateMap "default"; + stateMap "wip_particle_cloud"; vertexShader 3.0 "VERTEX_SHADER" { diff --git a/src/ObjCommon/Game/IW4/MaterialConstantsIW4.h b/src/ObjCommon/Game/IW4/MaterialConstantsIW4.h index 3f198b2c..4c0413aa 100644 --- a/src/ObjCommon/Game/IW4/MaterialConstantsIW4.h +++ b/src/ObjCommon/Game/IW4/MaterialConstantsIW4.h @@ -468,6 +468,8 @@ namespace IW4 MATERIAL_TYPE_MODEL_UNLIT, MATERIAL_TYPE_OBJECTIVE, MATERIAL_TYPE_PARTICLE_CLOUD, + MATERIAL_TYPE_SPARK_CLOUD, + MATERIAL_TYPE_SPARK_FOUNTAIN, MATERIAL_TYPE_SKY, MATERIAL_TYPE_TOOLS, MATERIAL_TYPE_UNLIT, @@ -489,6 +491,8 @@ namespace IW4 constexpr auto GDT_MATERIAL_TYPE_MODEL_UNLIT = "model unlit"; constexpr auto GDT_MATERIAL_TYPE_OBJECTIVE = "objective"; constexpr auto GDT_MATERIAL_TYPE_PARTICLE_CLOUD = "particle cloud"; + constexpr auto GDT_MATERIAL_TYPE_SPARK_CLOUD = "spark cloud"; + constexpr auto GDT_MATERIAL_TYPE_SPARK_FOUNTAIN = "spark fountain"; constexpr auto GDT_MATERIAL_TYPE_SKY = "sky"; constexpr auto GDT_MATERIAL_TYPE_TOOLS = "tools"; constexpr auto GDT_MATERIAL_TYPE_UNLIT = "unlit"; @@ -509,6 +513,8 @@ namespace IW4 GDT_MATERIAL_TYPE_MODEL_UNLIT, GDT_MATERIAL_TYPE_OBJECTIVE, GDT_MATERIAL_TYPE_PARTICLE_CLOUD, + GDT_MATERIAL_TYPE_SPARK_CLOUD, + GDT_MATERIAL_TYPE_SPARK_FOUNTAIN, GDT_MATERIAL_TYPE_SKY, GDT_MATERIAL_TYPE_TOOLS, GDT_MATERIAL_TYPE_UNLIT, diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp index e4237382..60f2567a 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp @@ -99,6 +99,14 @@ namespace IW4 { mtl_distortion_template(); } + else if (materialType == GDT_MATERIAL_TYPE_SPARK_FOUNTAIN) + { + mtl_sparkfountain_template(); + } + else if (materialType == GDT_MATERIAL_TYPE_SPARK_CLOUD) + { + mtl_sparkcloud_template(); + } else if (materialType == GDT_MATERIAL_TYPE_PARTICLE_CLOUD) { mtl_particlecloud_template(); @@ -212,7 +220,22 @@ namespace IW4 } } + void mtl_sparkfountain_template() + { + particlecloud_common_template("_sparkf"); + } + + void mtl_sparkcloud_template() + { + particlecloud_common_template("_spark"); + } + void mtl_particlecloud_template() + { + particlecloud_common_template(""); + } + + void particlecloud_common_template(const std::string& particleCloudSuffix) { refblend_template(); sort_template(); @@ -231,21 +254,23 @@ namespace IW4 if (outdoorOnly) outdoorSuffix = "_outdoor"; - std::string addSuffix; + std::string blendFuncSuffix; const auto blendFunc = ReadStringProperty("blendFunc"); - if (blendFunc == GDT_BLEND_FUNC_ADD || blendFunc == GDT_BLEND_FUNC_SCREEN_ADD) - addSuffix = "_add"; + if (blendFunc == GDT_BLEND_FUNC_ADD) + blendFuncSuffix = "_add"; + else if(blendFunc == GDT_BLEND_FUNC_SCREEN_ADD) + blendFuncSuffix = "_screen"; std::string spotSuffix; const auto useSpotLight = ReadBoolProperty("useSpotLight"); if (useSpotLight) - spotSuffix = "_spot"; + spotSuffix = "_spot_sm"; if (outdoorOnly && useSpotLight) throw GdtReadingException("Outdoor and spot aren't supported on particle cloud materials"); std::ostringstream ss; - ss << "particle_cloud" << outdoorSuffix << addSuffix << spotSuffix; + ss << "particle_cloud" << particleCloudSuffix << outdoorSuffix << blendFuncSuffix << spotSuffix; SetTechniqueSet(ss.str()); const auto colorMapName = ReadStringProperty("colorMap"); diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp index 616c3579..9626afae 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp @@ -815,6 +815,69 @@ namespace IW4 ExamineCommonUnlitTechsetInfo(); } + void ExamineParticleCloudTechsetInfo() + { + const auto nameParts = GetTechsetNameParts(m_techset_info.m_techset_base_name); + bool inCustomName = false; + bool customNameStart = true; + std::ostringstream customNameStream; + + for (auto iNamePart = nameParts.begin() + 2; iNamePart != nameParts.end(); ++iNamePart) + { + const auto& namePart = *iNamePart; + + if (inCustomName) + { + if (customNameStart) + customNameStart = false; + else + customNameStream << "_"; + customNameStream << namePart; + continue; + } + + // Anything after a custom part is part of its custom name + if (namePart == "custom") + { + inCustomName = true; + continue; + } + + if (namePart == "falloff") + m_techset_info.m_falloff = true; + else if (namePart == "distfalloff") + m_techset_info.m_dist_falloff = true; + else if (namePart == "zfeather") + m_techset_info.m_zfeather = true; + else if (namePart == "nofog") + m_techset_info.m_no_fog = true; + else if (namePart == "nocast") + m_techset_info.m_no_cast_shadow = true; + else if (namePart == "spot") + m_techset_info.m_use_spot_light = true; + else if (namePart == "lin") + m_techset_info.m_effect_lin_flag = true; + else if (namePart == "outdoor") + m_techset_info.m_outdoor_only = true; + else if (namePart == "ua") + m_techset_info.m_uv_anim = true; + else + { + if (namePart != "add" && namePart != "replace" && namePart != "blend" && namePart != "eyeoffset" && namePart != "screen" && namePart != "effect" && namePart != "unlit" + && namePart != "multiply" && namePart != "sm" && namePart != "spark" && namePart != "sparkf") + { + std::cout << "Unknown name part \"" << namePart << "\"\n"; + assert(false); + } + } + } + + if (inCustomName) + { + m_techset_info.m_gdt_custom_string = customNameStream.str(); + } + } + void ExamineTechsetInfo() { if (!m_material->techniqueSet || !m_material->techniqueSet->name) @@ -871,9 +934,20 @@ namespace IW4 { m_techset_info.m_gdt_material_type = MATERIAL_TYPE_DISTORTION; } + else if (m_techset_info.m_techset_base_name.rfind("particle_cloud_sparkf", 0) == 0) + { + m_techset_info.m_gdt_material_type = MATERIAL_TYPE_SPARK_FOUNTAIN; + ExamineParticleCloudTechsetInfo(); + } + else if (m_techset_info.m_techset_base_name.rfind("particle_cloud_spark", 0) == 0) + { + m_techset_info.m_gdt_material_type = MATERIAL_TYPE_SPARK_CLOUD; + ExamineParticleCloudTechsetInfo(); + } else if (m_techset_info.m_techset_base_name.rfind("particle_cloud", 0) == 0) { m_techset_info.m_gdt_material_type = MATERIAL_TYPE_PARTICLE_CLOUD; + ExamineParticleCloudTechsetInfo(); } else if (m_techset_info.m_techset_base_name == "grain_overlay") {