mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-22 20:52:49 +00:00
fix(ugc): transparent bricks drawn see-through in mixed models; dUgcServer in folders by role
- The client puts a shape in its sorted, blended pass only when its NiMaterialProperty alpha is under 0.99999 (ShaderCommon::GetAlphaFlags 0x0109f5a0; the NiAlphaProperty blend flag isn't read); at 1.0 it's drawn solid with blending off. Transparent (and transparent glitter) shapes now get a material with alpha 0.9999, as the S01_Alpha shapes of the game's own brick models (res/BrickModels/ndmade) do; opaque shapes keep 1.0. Models with a transparent brick change; the others are byte for byte the same. - dUgcServer's files move into Bricks/, Model/, Render/, Formats/ and Processing/ (the CMakeLists says what each holds); includes are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,25 +1,34 @@
|
||||
# The UGC server (docs/UgcServer.md), in folders by role:
|
||||
# Bricks/ the client's brick data: primitives, Materials.xml, LU Toolbox's palette, the CDClient's module data
|
||||
# Model/ player models built from LXFML, car and rocket module combinations, glitter
|
||||
# Render/ the software rasterizer, ambient occlusion, hidden-face removal, icon parameters and pose
|
||||
# Formats/ the files written for the client and the dashboard (NIF, DDS, PNG, sd0)
|
||||
# Processing/ the job queue and workers, the CPU budget, stored files
|
||||
# UgcServer.cpp the server: settings, the master link, HTTP routes
|
||||
|
||||
# The pure part of the UGC server (brick data, meshes, rendering, file formats, storage), shared with the tests
|
||||
set(DUGC_SOURCES
|
||||
"UgcBricks.cpp"
|
||||
"UgcFormats.cpp"
|
||||
"UgcGlitter.cpp"
|
||||
"UgcHsr.cpp"
|
||||
"UgcIconParams.cpp"
|
||||
"UgcIconPose.cpp"
|
||||
"UgcJobs.cpp"
|
||||
"UgcModel.cpp"
|
||||
"UgcModular.cpp"
|
||||
"UgcPalette.cpp"
|
||||
"UgcRender.cpp"
|
||||
"UgcStorage.cpp"
|
||||
"UgcThrottle.cpp"
|
||||
"Bricks/UgcBricks.cpp"
|
||||
"Bricks/UgcPalette.cpp"
|
||||
"Formats/UgcFormats.cpp"
|
||||
"Model/UgcGlitter.cpp"
|
||||
"Model/UgcModel.cpp"
|
||||
"Model/UgcModular.cpp"
|
||||
"Processing/UgcJobs.cpp"
|
||||
"Processing/UgcStorage.cpp"
|
||||
"Processing/UgcThrottle.cpp"
|
||||
"Render/UgcHsr.cpp"
|
||||
"Render/UgcIconParams.cpp"
|
||||
"Render/UgcIconPose.cpp"
|
||||
"Render/UgcRender.cpp"
|
||||
)
|
||||
|
||||
add_library(dUgc STATIC ${DUGC_SOURCES})
|
||||
target_include_directories(dUgc PUBLIC "." "${PROJECT_SOURCE_DIR}/thirdparty/MD5" "${PROJECT_SOURCE_DIR}/thirdparty/nlohmann")
|
||||
target_include_directories(dUgc PUBLIC "." "Bricks" "Formats" "Model" "Processing" "Render"
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/MD5" "${PROJECT_SOURCE_DIR}/thirdparty/nlohmann")
|
||||
target_link_libraries(dUgc PUBLIC dCommon glm::glm tinyxml2 MD5)
|
||||
|
||||
add_executable(UgcServer "UgcServer.cpp" "UgcProcessor.cpp" "UgcCdClient.cpp")
|
||||
add_executable(UgcServer "UgcServer.cpp" "Processing/UgcProcessor.cpp" "Bricks/UgcCdClient.cpp")
|
||||
|
||||
target_include_directories(UgcServer PRIVATE
|
||||
"${PROJECT_SOURCE_DIR}/dCommon"
|
||||
@@ -42,5 +51,5 @@ target_link_libraries(UgcServer ${COMMON_LIBRARIES} dWeb dServer dUgc)
|
||||
|
||||
# Rendering is far too slow unoptimized (minutes a model instead of seconds), so it is optimized in every build type
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties("UgcRender.cpp" "UgcHsr.cpp" "UgcModel.cpp" "UgcPalette.cpp" "UgcGlitter.cpp" PROPERTIES COMPILE_OPTIONS "-O2")
|
||||
set_source_files_properties("Render/UgcRender.cpp" "Render/UgcHsr.cpp" "Model/UgcModel.cpp" "Bricks/UgcPalette.cpp" "Model/UgcGlitter.cpp" PROPERTIES COMPILE_OPTIONS "-O2")
|
||||
endif()
|
||||
|
||||
@@ -228,8 +228,8 @@ namespace {
|
||||
m_VertexColor = nif.Add("NiVertexColorProperty", std::move(vertexColor.Data()));
|
||||
}
|
||||
|
||||
// A white NiMaterialProperty with this emissive color (grey)
|
||||
static std::string Material(float emissive) {
|
||||
// A white NiMaterialProperty with this emissive color (grey) and alpha
|
||||
static std::string Material(float emissive, float alpha = 1.0f) {
|
||||
Writer material;
|
||||
WriteNet(material, -1);
|
||||
for (int i = 0; i < 3; i++) material.Float(1.0f); // ambient
|
||||
@@ -237,7 +237,7 @@ namespace {
|
||||
for (int i = 0; i < 3; i++) material.Float(0.0f); // specular
|
||||
for (int i = 0; i < 3; i++) material.Float(emissive);
|
||||
material.Float(4.0f); // glossiness, as the game's brick models
|
||||
material.Float(1.0f); // alpha
|
||||
material.Float(alpha);
|
||||
return std::move(material.Data());
|
||||
}
|
||||
|
||||
@@ -383,8 +383,15 @@ namespace {
|
||||
specular.U16(0); // off
|
||||
m_Specular = m_Nif.Add("NiSpecularProperty", std::move(specular.Data()));
|
||||
}
|
||||
(void)transparent;
|
||||
// The client draws a shape in its sorted, blended pass only when the material's alpha is under 0.99999
|
||||
// (ShaderCommon::GetAlphaFlags 0x0109f5a0; the NiAlphaProperty's blend flag isn't read): at 1.0 a
|
||||
// transparent brick is drawn solid, with blending off. The game's own brick models give their S01_Alpha
|
||||
// shapes 0.9999, and so do we (made once a file, only when there is a transparent shape).
|
||||
int32_t material = m_Material;
|
||||
if (transparent) {
|
||||
if (m_MaterialAlpha < 0) m_MaterialAlpha = m_Nif.Add("NiMaterialProperty", Material(0.0f, 0.9999f));
|
||||
material = m_MaterialAlpha;
|
||||
}
|
||||
if (emissive > 0.0f) {
|
||||
auto [it, added] = m_Emissive.try_emplace(emissive, -1);
|
||||
if (added) it->second = m_Nif.Add("NiMaterialProperty", Material(emissive));
|
||||
@@ -409,6 +416,7 @@ namespace {
|
||||
private:
|
||||
NifBuilder& m_Nif;
|
||||
int32_t m_Material{ -1 };
|
||||
int32_t m_MaterialAlpha{ -1 }; // transparent shapes' (alpha 0.9999)
|
||||
int32_t m_VertexColor{ -1 };
|
||||
int32_t m_Alpha{ -1 };
|
||||
int32_t m_Specular{ -1 };
|
||||
Reference in New Issue
Block a user