mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-25 14:12:49 +00:00
feat(ugc): glitter flecks (LEGO-AnimUV) and milky satin in made models
Glitter colors (Materials.xml type glitter, glitter_colors 114,117) go into S21_Glitter_Model and, transparent, S21_GlitterAlpha_Model (shader_glitter, default 21, LEGO-AnimUV). Their shapes get box-projected UVs, an NiTexturingProperty with a stored 128 px mipmapped fleck texture (NiSourceTexture + NiPersistentSrcTextureRendererData, as the client's own env_ag_ocean-maelstrom.nif) and two NiTextureTransformControllers looping the base map's translation (glitter_size, glitter_density, glitter_speed). The shader lays the texture over the vertex color by its alpha and outputs the vertex alpha, so transparent glitter blends as S01_Alpha does. Satin colors (satin_colors, LEGO's opal colors) stay in S01_Alpha but get satin_opacity and are whitened by satin_whiten. NifFile reads the base map's scroll speed (uvScroll) from the controllers; the icon draws still flecks, the UGC 3D view and the LXFML viewers moving ones. stats.json counts the glitter groups. With shader_glitter 0 and no satin colors the files are the same bytes as before (tested). Also keeps glow_emissive for the icon (it was reset by the icon settings). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
import * as THREE from 'three';
|
||||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
||||
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
|
||||
import { parseModel, mergeMeshes, linearColors, nearPlaneFor } from '/js/scenery-core.js';
|
||||
import { parseModel, mergeMeshes, linearColors, nearPlaneFor, addGlitter } from '/js/scenery-core.js';
|
||||
|
||||
const GEOMETRY_MAGIC = 0x42473031; // "10GB"
|
||||
const MAX_PARALLEL_FETCHES = 6;
|
||||
@@ -174,11 +174,13 @@ async function loadGeneratedModel(url) {
|
||||
// ---- Viewer ----
|
||||
|
||||
const materialCache = new Map();
|
||||
// The glitter colours' moving flecks (window.LDD_GLITTER, the UGC server's glitter settings), updated each frame
|
||||
const glitterMaterials = [];
|
||||
function material(id) {
|
||||
if (!materialCache.has(id)) {
|
||||
const c = (window.LDD_MATERIALS || {})[id] || [160, 160, 160, 255];
|
||||
const transparent = c[3] < 255;
|
||||
materialCache.set(id, new THREE.MeshPhysicalMaterial({
|
||||
const created = new THREE.MeshPhysicalMaterial({
|
||||
color: new THREE.Color().setRGB(c[0] / 255, c[1] / 255, c[2] / 255, THREE.SRGBColorSpace),
|
||||
roughness: 0.28,
|
||||
metalness: 0,
|
||||
@@ -187,7 +189,14 @@ function material(id) {
|
||||
transparent,
|
||||
opacity: c[3] / 255,
|
||||
depthWrite: !transparent
|
||||
}));
|
||||
});
|
||||
const glitter = window.LDD_GLITTER;
|
||||
if (glitter && (glitter.colors || []).includes(Number(id))) {
|
||||
// Moving as the game moves its fleck texture: a tile in U in 7 s and in V in 11 s at speed 1
|
||||
const speed = glitter.speed || 0;
|
||||
glitterMaterials.push(addGlitter(created, { coordinates: 'position', tile: glitter.tile || 1.6, flecks: glitter.flecks || 50, scroll: [speed / 7, speed / 11] }));
|
||||
}
|
||||
materialCache.set(id, created);
|
||||
}
|
||||
return materialCache.get(id);
|
||||
}
|
||||
@@ -749,6 +758,7 @@ export function createViewer(container, { onProgress, onSelect, onTick, brickUrl
|
||||
const dt = Math.min((now - lastTime) / 1000, 0.1);
|
||||
lastTime = now;
|
||||
if (onTick) onTick(dt);
|
||||
for (const glitter of glitterMaterials) glitter.update(now / 1000);
|
||||
updateBubbles(now);
|
||||
controls.update();
|
||||
// The near plane follows how far out the camera is (depth precision for the scenery far away), but never
|
||||
|
||||
Reference in New Issue
Block a user