Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/game/scenery/isometric/metadata/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { getParams } from '../../../../params';
import { loadFx } from './fx/loader';
import Game from '../../../Game';
import { Fx } from './fx/Fx';
import { createTwinklingStar } from '../misc/twinkling_star';

const exporter = new GLTFExporter();

Expand Down Expand Up @@ -95,6 +96,47 @@ export async function loadFullSceneModel(
}
}
});

if (entry === 117) {
// Twinkling star effects for entry 117 (scene 173, Kurtz house)
// Specs: pos (Vector3), size (scale), color (hex Color), speed (twinkle rate)
const starSpecs = [
{
pos: new THREE.Vector3(41.3, 3.85, 35),
size: 1.0,
color: 0xefb810,
speed: 1.514
},
{
pos: new THREE.Vector3(41.17, 3.4, 35.5),
size: 0.6,
color: 0x3c341e,
speed: 1.259
}
// Add more stars by adding additional objects to this array.
];

for (const spec of starSpecs) {
const { pos, size, color, speed } = spec;
// Create a twinkling star (defined in ../misc/twinkling_star.ts)
const starEffect = await createTwinklingStar(
pos,
new THREE.Color(color),
size,
speed
);
// Add the star's mesh to the scene
threeObject.add(starEffect.threeObject);
// Register the star's update function to animate its twinkle each frame
effects.push({
init: () => {}, // no extra initialization needed
update: (_game, _scene, time) => {
starEffect.update(time); // update star effect (uses time.elapsed in shader)
}
});
}
}

const mixer = new THREE.AnimationMixer(threeObject);
applyAnimationUpdaters(threeObject, model.animations);
each(model.animations, (clip) => {
Expand Down
31 changes: 31 additions & 0 deletions src/game/scenery/isometric/misc/shaders/star_twinkle.frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
precision highp float;

// Varyings from the vertex shader
varying float vIntensity;
varying float vSparkle;
varying vec2 vUv;

// Uniforms set via Three.js
uniform sampler2D starTex;
uniform vec3 uColor;
uniform float time;
uniform float uSpeed;

void main() {
// Compute twinkle flicker factor
float flicker = sin(time * uSpeed + vSparkle * 10.0) * vSparkle;
float finalIntensity = vIntensity + flicker;

// Sample the star texture and apply the color tint
vec4 tex = texture2D(starTex, vUv);
vec3 invertedRGB = vec3(1.0) - tex.rgb;
vec3 tinted = invertedRGB * uColor;

// Apply the final intensity to color and alpha
vec4 color = vec4(tinted * finalIntensity, tex.a * finalIntensity);

// Discard nearly transparent pixels for cleaner edges
if (color.a < 0.01) discard;

gl_FragColor = color;
}
39 changes: 39 additions & 0 deletions src/game/scenery/isometric/misc/shaders/star_twinkle.vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
precision highp float;

// Standard vertex attributes (not automatically provided in RawShaderMaterial)
attribute vec3 position;
attribute vec2 uv;

// Custom attributes for brightness and sparkle effect
attribute float intensity;
attribute float size;
attribute float sparkle;

// Varyings to pass data to the fragment shader
varying float vIntensity;
varying float vSparkle;
varying vec2 vUv;

// Transformation matrices (provided by Three.js)
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

void main() {
// Pass custom attribute values to the fragment shader via varyings
vIntensity = intensity;
vSparkle = sparkle;
vUv = uv;

// Center UV coordinates at (0.5, 0.5) and scale by size
vec2 centeredUV = uv - vec2(0.5);
vec2 offset = centeredUV * size;

// Compute vertex position in camera space
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);

// Offset the X and Y position by the computed offset (billboard quad)
mvPosition.xy += offset;

// Project the vertex to clip space
gl_Position = projectionMatrix * mvPosition;
}
90 changes: 90 additions & 0 deletions src/game/scenery/isometric/misc/twinkling_star.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as THREE from 'three';
import STAR_VERT from './shaders/star_twinkle.vert.glsl';
import STAR_FRAG from './shaders/star_twinkle.frag.glsl';

const loader = new THREE.TextureLoader();

/**
* Create a twinkling star effect at a given position.
* Returns an object with the star's Three.js mesh and an update function.
*/
export async function createTwinklingStar(
position: THREE.Vector3,
color: number | string | THREE.Color,
size = 1.0,
speed = 1.5
) {
// Load star texture (with alpha channel for transparency)
const starTexture = await new Promise<THREE.Texture>((resolve) => {
loader.load('images/stars/B_OPC1.png', resolve);
});

// Create a RawShaderMaterial for the star using custom shaders
const starMaterial = new THREE.RawShaderMaterial({
vertexShader: STAR_VERT,
fragmentShader: STAR_FRAG,
uniforms: {
starTex: { value: starTexture },
uColor: { value: new THREE.Color(color) },
time: { value: 0.0 },
uSpeed: { value: speed }
},
transparent: true,
blending: THREE.AdditiveBlending,
depthWrite: false,
side: THREE.FrontSide
});

// Define star geometry as a quad (two triangles at the given position)
const starGeo = new THREE.BufferGeometry();
const positions: number[] = [];
const uvs: number[] = [];
const intensities: number[] = [];
const sizes: number[] = [];
const sparkles: number[] = [];

// Base attributes for the star
const baseIntensity = 0.4; // base brightness intensity
const baseSize = 0.1 * size; // base sprite size in world units
const baseSparkle = 0.7; // base sparkle variation factor

// Add 6 vertices at the star position (two triangles forming a quad)
for (let j = 0; j < 6; j += 1) {
positions.push(position.x, position.y, position.z);
intensities.push(baseIntensity);
sizes.push(baseSize);
sparkles.push(baseSparkle);
}
// Set UV coordinates for the two triangles (covering the full texture)
uvs.push(
0, 0,
0, 1,
1, 0,
1, 1,
1, 0,
0, 1
);

starGeo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
starGeo.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
starGeo.setAttribute('intensity', new THREE.Float32BufferAttribute(intensities, 1));
starGeo.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1));
starGeo.setAttribute('sparkle', new THREE.Float32BufferAttribute(sparkles, 1));
// Set the index buffer to form two triangles (0-1-2 and 3-4-5)
starGeo.setIndex([5, 4, 3, 2, 1, 0]);

// Create the star mesh with its geometry and material
const starMesh = new THREE.Mesh(starGeo, starMaterial);
starMesh.name = 'twinkling_star';
starMesh.frustumCulled = false; // always render (disable frustum culling)
starMesh.renderOrder = 2; // draw after scene objects to avoid overlap

// Return the Three.js mesh and an update function for the twinkle animation
return {
threeObject: starMesh,
update: (time: { elapsed: number }) => {
// Update the time uniform to animate the flicker effect
starMaterial.uniforms.time.value = time.elapsed;
}
};
}
20 changes: 20 additions & 0 deletions www/metadata/lba2/grids.json
Original file line number Diff line number Diff line change
Expand Up @@ -6250,6 +6250,20 @@
0,
6.123233995736766e-17
]
},
{
"name": "FI_053_liquor_bottle_and_mug.glb",
"position": {
"x": 41,
"y": 1.5,
"z": 31.5
},
"quaternion": [
0,
0.7071067811865475,
0,
0.7071067811865476
]
}
],
"patches": {
Expand Down Expand Up @@ -7317,6 +7331,12 @@
},
"14x1x37": {
"hide": true
},
"41x3x32": {
"hide": true
},
"41x4x32": {
"hide": true
}
}
},
Expand Down
65 changes: 65 additions & 0 deletions www/metadata/lba2/layouts.json
Original file line number Diff line number Diff line change
Expand Up @@ -5285,6 +5285,16 @@
}
},
"15": {
"0": {
"replace": true,
"file": "FI_000_001_010_011_padded_armchair.glb",
"orientation": 0
},
"1": {
"replace": true,
"file": "FI_000_001_010_011_padded_armchair.glb",
"orientation": 1
},
"2": {
"replace": true,
"file": "FI_002_003_francos_building_wall.glb",
Expand Down Expand Up @@ -5320,6 +5330,26 @@
"file": "FI_008_francos_building_wall_round_corner.glb",
"orientation": 0
},
"9": {
"replace": true,
"file": "FI_009_padded_armchair_long.glb",
"orientation": 0
},
"10": {
"replace": true,
"file": "FI_000_001_010_011_padded_armchair.glb",
"orientation": 3
},
"11": {
"replace": true,
"file": "FI_000_001_010_011_padded_armchair.glb",
"orientation": 2
},
"12": {
"replace": true,
"file": "FI_012_padded_beanbag.glb",
"orientation": 0
},
"17": {
"replace": true,
"file": "FI_017_francos_building_wall_window_big.glb",
Expand All @@ -5340,6 +5370,11 @@
"file": "FI_020_francos_building_wall_window.glb",
"orientation": 0
},
"22": {
"replace": true,
"file": "FI_022_padded_stool.glb",
"orientation": 0
},
"23": {
"replace": true,
"file": "FI_023_francos_doorframe.glb",
Expand All @@ -5350,6 +5385,11 @@
"file": "FI_024_francos_doorframe.glb",
"orientation": 0
},
"25": {
"replace": true,
"file": "FI_025_round_table.glb",
"orientation": 0
},
"26": {
"replace": true,
"file": "FI_026_ice_creams_and_cup.glb",
Expand Down Expand Up @@ -5485,11 +5525,26 @@
"file": "FI_069_short_stool.glb",
"orientation": 0
},
"70": {
"replace": true,
"file": "FI_070_baby_cushion.glb",
"orientation": 0
},
"71": {
"replace": true,
"file": "FI_071_red_soup.glb",
"orientation": 0
},
"72": {
"replace": true,
"file": "FI_072_baby_bottles.glb",
"orientation": 0
},
"73": {
"replace": true,
"file": "FI_073_little_doll.glb",
"orientation": 0
},
"74": {
"replace": true,
"file": "FI_074_abacus.glb",
Expand All @@ -5515,6 +5570,11 @@
"file": "FI_079_big_candle.glb",
"orientation": 0
},
"80": {
"replace": true,
"file": "FI_080_big_dry_flower_pot.glb",
"orientation": 0
},
"81": {
"replace": true,
"file": "FI_081_francos_building_wall_window_covered.glb",
Expand All @@ -5525,6 +5585,11 @@
"file": "FI_082_francos_building_wall_window_big_covered.glb",
"orientation": 0
},
"83": {
"replace": true,
"file": "FI_083_shiny_globe.glb",
"orientation": 0
},
"84": {
"replace": true,
"file": "FI_084_dark_monk_altar.glb",
Expand Down
Binary file modified www/models/lba2/iso_scenes/115.glb
Binary file not shown.
Binary file modified www/models/lba2/iso_scenes/116.glb
Binary file not shown.
Binary file modified www/models/lba2/iso_scenes/117.glb
Binary file not shown.
Binary file modified www/models/lba2/iso_scenes/118.glb
Binary file not shown.
Binary file modified www/models/lba2/iso_scenes/119.glb
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added www/models/lba2/layouts/FI_070_baby_cushion.glb
Binary file not shown.
Binary file added www/models/lba2/layouts/FI_071_red_soup.glb
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading