mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-15 09:04:10 +00:00
feat(ugc): opt-in metal and glow shader groups in made models
Player models are multishader (RenderComponent shader 100): the client wraps each NiLODNode and draws it with the mapShaders id in its name. With shader_metal, shader_brushed or shader_glow set, the opaque bricks are split by look into S<id>_Metal_Model, S<id>_Brushed_Model and S<id>_Glow_Model beside S01_Opaque_Model and S01_Alpha_Model, each with every LOD level. Metal is LU Toolbox's metallic colors plus Materials.xml types (shinySteel; brushedSteel and matteSteel for brushed), glow its glow colors. Glow shapes get an emissive material (glow_emissive) and their plain color, not the baked one. Transparent glow stays in S01_Alpha. All off by default, which writes the same bytes as before (tested). Not how live looked; models already made change only when made again. The icon renderer reads the groups back by tag and draws glow at its plain color and metal with a tinted reflection and highlight. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -483,8 +483,28 @@ namespace UgcRender {
|
||||
// The sun's highlight (Blinn-Phong), white, on top of the color
|
||||
const float highlight = direct > 0.0f ? options.specular * options.sunStrength / 3.14159265f * sun * std::pow(std::max(0.0f, glm::dot(normal, halfway)), std::max(options.shininess, 1.0f)) : 0.0f;
|
||||
const float exposure = std::max(options.exposure, 0.0f);
|
||||
return glm::vec4((ToLinear(base.r) * lighting + highlight) * exposure, (ToLinear(base.g) * lighting + highlight) * exposure,
|
||||
(ToLinear(base.b) * lighting + highlight) * exposure, std::clamp(base.a, 0.0f, 1.0f));
|
||||
const auto look = isOpaque && mesh.looks.size() == mesh.positions.size() ? mesh.looks[i0] : UgcModel::eLook::PLASTIC;
|
||||
if (look == UgcModel::eLook::PLASTIC) {
|
||||
return glm::vec4((ToLinear(base.r) * lighting + highlight) * exposure, (ToLinear(base.g) * lighting + highlight) * exposure,
|
||||
(ToLinear(base.b) * lighting + highlight) * exposure, std::clamp(base.a, 0.0f, 1.0f));
|
||||
}
|
||||
const glm::vec3 linear(ToLinear(base.r), ToLinear(base.g), ToLinear(base.b));
|
||||
glm::vec3 shaded = (linear * lighting + glm::vec3(highlight)) * exposure;
|
||||
if (look == UgcModel::eLook::METAL || look == UgcModel::eLook::BRUSHED) {
|
||||
// A reflection of a bright sky over a dark ground, tinted by the color (polished: sharp; brushed: blurred
|
||||
// and duller), over a dimmed diffuse light, and the sun's highlight in the metal's color
|
||||
const bool polished = look == UgcModel::eLook::METAL;
|
||||
const auto reflected = glm::reflect(-toCamera, normal);
|
||||
const float up = polished ? glm::smoothstep(-0.15f, 0.5f, reflected.y) : 0.5f + 0.5f * reflected.y;
|
||||
const float environment = glm::mix(0.06f, polished ? 1.1f : 0.75f, up);
|
||||
const float spot = direct > 0.0f ? options.sunStrength / 3.14159265f * sun *
|
||||
std::pow(std::max(0.0f, glm::dot(normal, halfway)), polished ? 180.0f : 30.0f) * (polished ? 4.0f : 1.2f) : 0.0f;
|
||||
shaded = linear * (lighting * 0.35f + environment + spot) * exposure;
|
||||
} else if (look == UgcModel::eLook::GLOW) {
|
||||
// LEGO-Emissive: lerp(lit, vertex color, vertex alpha * the material's emissive red)
|
||||
shaded = glm::mix(shaded, linear, std::clamp(options.glowEmissive, 0.0f, 1.0f));
|
||||
}
|
||||
return glm::vec4(shaded, std::clamp(base.a, 0.0f, 1.0f));
|
||||
};
|
||||
|
||||
// Opaque first, with the depth buffer
|
||||
|
||||
Reference in New Issue
Block a user