mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-05 11:27:15 +00:00
fix(dashboard): scenery models keep their colors, lit like the game
Glom models (multishader) drew their trees, rocks, fences and water white. Their conversions kept on disk from before meshes carried their multishader tag were still served (the cache format version was never bumped), so every part fell back to the LEGO shader, whose texture alpha lays the (mostly grey) texture over the vertex colors that hold the actual colors. Browsers also kept those models for a week. - Bump the conversion format so old conversions are made again, and put it in the manifests; the viewers add it to model and texture URLs. - Light scenery as the client's shaders do: the scene's sun and ambient light from its .lvl (read as level_read_lighting_info, 0x0102f8f0, and EnvironmentManager::SetLightEnv, 0x01088aa0, do), per vertex, clamped, instead of the view's own lights, environment map and tone mapping. The zone takes the lighting most of its objects' scenes have. - Programmable shaders read vertex colors and ignore NiMaterialProperty's color and alpha; unlit and untextured shaders (by mapShaders gameValue) leave out lighting or the texture. Fixed function stays as it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -43,14 +43,46 @@ export function parseModel(buffer) {
|
||||
* their shader in their node names (mesh.shaderTag); a tag the client can't use falls back to the LEGO shader.
|
||||
*/
|
||||
export function textureAlphaMode(manifest, asset, mesh) {
|
||||
if (!manifest || !manifest.shaders || !manifest.textureAlpha) return 'opacity';
|
||||
let shader = manifest.shaders[asset];
|
||||
if (shader === undefined || shader === null) return 'opacity';
|
||||
if (shader === manifest.multishader) {
|
||||
const tagged = mesh && mesh.shaderTag >= 0 && manifest.shaderTags ? manifest.shaderTags[mesh.shaderTag] : undefined;
|
||||
shader = tagged !== undefined && tagged >= 3 && tagged <= 108 ? tagged : manifest.defaultShader;
|
||||
}
|
||||
return manifest.textureAlpha[shader] || 'opacity';
|
||||
if (!manifest || !manifest.textureAlpha) return 'opacity';
|
||||
const shader = shaderOf(manifest, asset, mesh);
|
||||
return shader === null ? 'opacity' : manifest.textureAlpha[shader] || 'opacity';
|
||||
}
|
||||
|
||||
/**
|
||||
* The shader (mapShaders.gameValue) the game draws a mesh of a model with, or null when the manifest doesn't say
|
||||
* (-1 is fixed function). A multishader model's parts name theirs in their node names (mesh.shaderTag, a mapShaders
|
||||
* id); a tag the client can't use falls back to the LEGO shader.
|
||||
*/
|
||||
export function shaderOf(manifest, asset, mesh) {
|
||||
if (!manifest || !manifest.shaders) return null;
|
||||
const shader = manifest.shaders[asset];
|
||||
if (shader === undefined || shader === null) return null;
|
||||
if (shader !== manifest.multishader) return shader;
|
||||
const tagged = mesh && mesh.shaderTag >= 0 && manifest.shaderTags ? manifest.shaderTags[mesh.shaderTag] : undefined;
|
||||
return tagged !== undefined && tagged >= 3 && tagged <= 108 ? tagged : manifest.defaultShader;
|
||||
}
|
||||
|
||||
// NifFile::eShaderLook bits
|
||||
export const SHADER_LOOK = { UNLIT: 1, NO_TEXTURE: 2, NO_VERTEX_COLORS: 4, MATERIAL_COLOR: 8 };
|
||||
|
||||
/**
|
||||
* How a mesh is drawn under the game's shaders, when the manifest has the zone's lighting: {lit, texture,
|
||||
* vertexColors, material} — whether the scene's sun and ambient light it, its texture and vertex colors are used, and
|
||||
* whether its NiMaterialProperty colors are (only fixed function and the "Material" shaders use them). Null without
|
||||
* lighting in the manifest (older servers), for the viewer's own lights.
|
||||
*/
|
||||
export function gameLook(manifest, asset, mesh) {
|
||||
if (!manifest || !manifest.lighting) return null;
|
||||
const shader = shaderOf(manifest, asset, mesh);
|
||||
const fixedFunction = shader === null || shader < 0;
|
||||
const bits = fixedFunction || !manifest.shaderLooks ? 0 : manifest.shaderLooks[shader] || 0;
|
||||
return {
|
||||
lit: !(bits & SHADER_LOOK.UNLIT),
|
||||
texture: !(bits & SHADER_LOOK.NO_TEXTURE),
|
||||
// Fixed function reads them as NiVertexColorProperty says; the shaders always do, unless they have none
|
||||
vertexColors: !!(mesh.colors && !(bits & SHADER_LOOK.NO_VERTEX_COLORS) && (!fixedFunction || mesh.vertexColors !== 0)),
|
||||
material: fixedFunction || !!(bits & SHADER_LOOK.MATERIAL_COLOR)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user