mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-12 07:43:43 +00:00
feat(dashboard): metal and glow looks in the UGC and zone 3D views
NifFile::ShaderLookFor knows Polished Metal (98), Brushed Steel (99) and LEGO-Emissive (53). The UGC mesh route sends each mesh's look (from its multishader tag), and the UGC 3D view draws metal as reflective and glow unlit. The zone views draw LEGO-Emissive objects going to their vertex color by its alpha, as the shader does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -687,7 +687,7 @@ namespace NifFile {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ShaderLookFor(int32_t shader) {
|
||||
uint16_t ShaderLookFor(int32_t shader) {
|
||||
// By the technique each shader class sets up (ShaderManager's factory table at 0x01889608, indexed by gameValue;
|
||||
// the class's technique setup names it). Checked in the client: 33 and 82 Technique_Basic_NoLighting_VertColor_
|
||||
// NoTexture, 35 and 84 Technique_Basic_NoLighting_VertColor, 37 Technique_Basic_Lighting_VertColor_NoTexture,
|
||||
@@ -730,6 +730,15 @@ namespace NifFile {
|
||||
case 8: case 10: case 54: case 15: case 23: case 35: case 52: case 57: case 62: case 68: case 70: case 73: case 81:
|
||||
case 84: case 87: case 101:
|
||||
return UNLIT;
|
||||
// Polished Metal (Technique_Lighting_PolishedMetal_VertColor in Metallic.fx) and Brushed Steel (its noise
|
||||
// in object space); both load their reflection textures themselves
|
||||
case 98:
|
||||
return REFLECTIVE;
|
||||
case 99:
|
||||
return REFLECTIVE | BRUSHED;
|
||||
// LEGO-Emissive
|
||||
case 53:
|
||||
return EMISSIVE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -744,7 +753,7 @@ namespace NifFile {
|
||||
return Parser(data, 0).Dds(block, error);
|
||||
}
|
||||
|
||||
std::string Encode(const Model& model, const std::vector<std::string>& textures, const std::vector<std::string>& darkTextures) {
|
||||
std::string Encode(const Model& model, const std::vector<std::string>& textures, const std::vector<std::string>& darkTextures, const std::vector<uint16_t>& looks) {
|
||||
std::string body;
|
||||
nlohmann::json meshes = nlohmann::json::array();
|
||||
std::vector<std::string> names;
|
||||
@@ -771,6 +780,7 @@ namespace NifFile {
|
||||
{"vertexColors", material.vertexColorMode}, {"texture", textureIndex}, {"clampU", material.clampU}, {"clampV", material.clampV},
|
||||
{"shaderTag", material.shaderTag}, {"darkTexture", uv2 ? darkIndex : -1}, {"uv2", uv2}
|
||||
};
|
||||
if (m < looks.size()) entry["look"] = looks[m];
|
||||
Append(body, mesh.positions.data(), mesh.positions.size() * sizeof(float));
|
||||
if (!mesh.normals.empty()) {
|
||||
std::vector<int8_t> packed(mesh.normals.size());
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace NifFile {
|
||||
* BasicShaders.fx, LEGOPPLighting.fx and Ocean.fx). Fixed function (-1) has none of these: Gamebryo lights it with
|
||||
* the material and NiVertexColorProperty.
|
||||
*/
|
||||
enum eShaderLook : uint8_t {
|
||||
enum eShaderLook : uint16_t {
|
||||
UNLIT = 1, // no lighting: the colors as they are (the "NoLighting" techniques)
|
||||
NO_TEXTURE = 2, // the texture isn't sampled ("NoTexture")
|
||||
NO_VERTEX_COLORS = 4, // vertex colors aren't read
|
||||
@@ -91,11 +91,18 @@ namespace NifFile {
|
||||
// Two textures (base and dark, each with its UV set): blended by the vertex alpha, which is then no opacity
|
||||
// ("Two Layers Blended"), or added, weighted by the material's diffuse red and green ("Two Textures Added")
|
||||
TWO_LAYERS_BLENDED = 16,
|
||||
TWO_LAYERS_ADDED = 32
|
||||
TWO_LAYERS_ADDED = 32,
|
||||
// Metal (Metallic.fx): the lit color plus an environment map (textures/metal/metal_reflection_*.dds, which the
|
||||
// shader loads itself) tinted by the vertex color, polished or, with BRUSHED, brushed with object space noise
|
||||
REFLECTIVE = 64,
|
||||
BRUSHED = 128,
|
||||
// LEGO-Emissive: lerp(lit, vertex color, vertex alpha * NiMaterialProperty's emissive red); the vertex alpha is
|
||||
// that mask, not opacity
|
||||
EMISSIVE = 256
|
||||
};
|
||||
|
||||
// eShaderLook bits of a shader (mapShaders.gameValue); 0 for the usual lit look and for fixed function
|
||||
uint8_t ShaderLookFor(int32_t shader);
|
||||
uint16_t ShaderLookFor(int32_t shader);
|
||||
|
||||
// Where a node is in the model's space: p' = rotation * p + translation (row-major, scale folded in)
|
||||
struct NodeTransform {
|
||||
@@ -125,9 +132,11 @@ namespace NifFile {
|
||||
* int8 normals (3 per vertex, times 127, padded to 4 bytes) when "normals", float32 UVs (2 per vertex) when "uv",
|
||||
* float32 dark texture UVs when "uv2", uint8 RGBA colors when "colors", then uint16 indices (padded to 4 bytes).
|
||||
* `textures[i]` is where mesh i's texture is (empty: none) and `darkTextures[i]` its dark texture; the header
|
||||
* lists each once in "textures" and a mesh's "texture" and "darkTexture" index it (-1: none).
|
||||
* lists each once in "textures" and a mesh's "texture" and "darkTexture" index it (-1: none). `looks[i]`, when
|
||||
* given, is mesh i's "look" (eShaderLook bits of the shader it is drawn with, for views without a scenery manifest).
|
||||
*/
|
||||
std::string Encode(const Model& model, const std::vector<std::string>& textures, const std::vector<std::string>& darkTextures = {});
|
||||
std::string Encode(const Model& model, const std::vector<std::string>& textures, const std::vector<std::string>& darkTextures = {},
|
||||
const std::vector<uint16_t>& looks = {});
|
||||
|
||||
/**
|
||||
* A texture stored inside a .nif (NiPixelData or NiPersistentSrcTextureRendererData, block `block`) as a DDS file
|
||||
|
||||
Reference in New Issue
Block a user