Use MeshLambertMaterial for original game-like rendering

Switch from MeshStandardMaterial (PBR) to MeshLambertMaterial for flat,
vibrant colors matching the original game. Simplify lighting setup for
solid colors without visible shadows.
This commit is contained in:
Christian Semmler 2026-02-01 16:00:14 -08:00
parent 94f857a695
commit 9c46c8cc6c
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
2 changed files with 15 additions and 36 deletions

View File

@ -32,20 +32,12 @@ export class VehiclePartRenderer {
} }
setupLighting() { setupLighting() {
const ambient = new THREE.AmbientLight(0xffffff, 0.6); const ambient = new THREE.AmbientLight(0xffffff, 0.8);
this.scene.add(ambient); this.scene.add(ambient);
const keyLight = new THREE.DirectionalLight(0xffffff, 0.8); const sunLight = new THREE.DirectionalLight(0xffffff, 0.6);
keyLight.position.set(2, 2, 3); sunLight.position.set(1, 2, 3);
this.scene.add(keyLight); this.scene.add(sunLight);
const fillLight = new THREE.DirectionalLight(0xffffff, 0.4);
fillLight.position.set(-2, 1, 2);
this.scene.add(fillLight);
const rimLight = new THREE.DirectionalLight(0xffffff, 0.3);
rimLight.position.set(0, 1, -3);
this.scene.add(rimLight);
} }
/** /**
@ -145,11 +137,9 @@ export class VehiclePartRenderer {
if (isColorable) { if (isColorable) {
// Mesh has INH prefix - use the LEGO color // Mesh has INH prefix - use the LEGO color
material = new THREE.MeshStandardMaterial({ material = new THREE.MeshLambertMaterial({
color: legoColor, color: legoColor,
side: THREE.DoubleSide, side: THREE.DoubleSide,
roughness: 0.7,
metalness: 0.1,
transparent: isTransparent, transparent: isTransparent,
opacity: opacity, opacity: opacity,
depthWrite: !isTransparent depthWrite: !isTransparent
@ -157,11 +147,9 @@ export class VehiclePartRenderer {
this.colorableMeshes.push(null); // Placeholder, will set after mesh creation this.colorableMeshes.push(null); // Placeholder, will set after mesh creation
} else if (hasUVs && meshTextureName && this.textures.has(meshTextureName)) { } else if (hasUVs && meshTextureName && this.textures.has(meshTextureName)) {
// Mesh has its own texture // Mesh has its own texture
material = new THREE.MeshStandardMaterial({ material = new THREE.MeshLambertMaterial({
map: this.textures.get(meshTextureName), map: this.textures.get(meshTextureName),
side: THREE.DoubleSide, side: THREE.DoubleSide,
roughness: 0.8,
metalness: 0.1,
transparent: isTransparent, transparent: isTransparent,
opacity: opacity, opacity: opacity,
depthWrite: !isTransparent depthWrite: !isTransparent
@ -169,11 +157,9 @@ export class VehiclePartRenderer {
} else { } else {
// Fallback to mesh's vertex color // Fallback to mesh's vertex color
const meshColor = mesh.properties?.color || { r: 128, g: 128, b: 128 }; const meshColor = mesh.properties?.color || { r: 128, g: 128, b: 128 };
material = new THREE.MeshStandardMaterial({ material = new THREE.MeshLambertMaterial({
color: new THREE.Color(meshColor.r / 255, meshColor.g / 255, meshColor.b / 255), color: new THREE.Color(meshColor.r / 255, meshColor.g / 255, meshColor.b / 255),
side: THREE.DoubleSide, side: THREE.DoubleSide,
roughness: 0.8,
metalness: 0.1,
transparent: isTransparent, transparent: isTransparent,
opacity: opacity, opacity: opacity,
depthWrite: !isTransparent depthWrite: !isTransparent

View File

@ -35,14 +35,12 @@ export class WdbModelRenderer {
* Setup scene lighting - override to customize * Setup scene lighting - override to customize
*/ */
setupLighting() { setupLighting() {
// Flat, even lighting similar to in-game const ambient = new THREE.AmbientLight(0xffffff, 0.8);
const ambient = new THREE.AmbientLight(0xffffff, 1.5);
this.scene.add(ambient); this.scene.add(ambient);
// Soft front light const sunLight = new THREE.DirectionalLight(0xffffff, 0.6);
const frontLight = new THREE.DirectionalLight(0xffffff, 0.3); sunLight.position.set(1, 2, 3);
frontLight.position.set(0, 0, 5); this.scene.add(sunLight);
this.scene.add(frontLight);
} }
/** /**
@ -62,22 +60,18 @@ export class WdbModelRenderer {
this.texture.magFilter = THREE.LinearFilter; this.texture.magFilter = THREE.LinearFilter;
if (texturedGeometry) { if (texturedGeometry) {
const texturedMaterial = new THREE.MeshStandardMaterial({ const texturedMaterial = new THREE.MeshLambertMaterial({
map: this.texture, map: this.texture,
side: THREE.DoubleSide, side: THREE.DoubleSide
roughness: 0.8,
metalness: 0.1
}); });
this.texturedMesh = new THREE.Mesh(texturedGeometry, texturedMaterial); this.texturedMesh = new THREE.Mesh(texturedGeometry, texturedMaterial);
this.modelGroup.add(this.texturedMesh); this.modelGroup.add(this.texturedMesh);
} }
for (const { geometry, color } of nonTexturedGeometries) { for (const { geometry, color } of nonTexturedGeometries) {
const material = new THREE.MeshStandardMaterial({ const material = new THREE.MeshLambertMaterial({
color: new THREE.Color(color.r / 255, color.g / 255, color.b / 255), color: new THREE.Color(color.r / 255, color.g / 255, color.b / 255),
side: THREE.DoubleSide, side: THREE.DoubleSide
roughness: 0.8,
metalness: 0.1
}); });
const mesh = new THREE.Mesh(geometry, material); const mesh = new THREE.Mesh(geometry, material);
this.modelGroup.add(mesh); this.modelGroup.add(mesh);
@ -126,7 +120,6 @@ export class WdbModelRenderer {
} }
} }
// Build mesh vertices following brickolini-island logic
const meshVertices = []; const meshVertices = [];
const meshNormals = []; const meshNormals = [];
const meshUvs = []; const meshUvs = [];