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
14 changes: 13 additions & 1 deletion src/core/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ export interface ConfigType {
glow: {
startOffsetMinutes: number;
endOffsetMinutes: number;
glowPulseFrequency: number;
glowPulseAmplitude: number;
glowIntensityMax: number;
glowColorMap: Record<string, number>;
};
noteColorMap: {
global: Record<string, number>;
Expand Down Expand Up @@ -154,7 +158,15 @@ export const CONFIG: ConfigType = {
glow: {
startOffsetMinutes: 30, // Start glowing 30 min before sunset
endOffsetMinutes: 30, // Stop glowing 30 min after sunrise (or before? usually before dawn, but let's stick to plan)
// Plan says "stop before dawn". Let's say it fades out during pre-dawn.
glowPulseFrequency: 1.0,
glowPulseAmplitude: 0.5,
glowIntensityMax: 2.0,
glowColorMap: {
'mushroom': 0xFFDDDD,
'tree': 0xAAFFCC,
'flower': 0xFFCCFF,
'global': 0xFFFFFF
}
},

// --- NOTE COLOR MAPPING ---
Expand Down
20 changes: 17 additions & 3 deletions src/foliage/mushroom-batcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { uTwilight } from './sky.ts';
import { foliageGroup } from '../world/state.ts'; // Assuming state.ts exports foliageGroup
import { spawnImpact } from './impacts.ts';
import { uChromaticIntensity } from './chromatic.ts';
import { CONFIG } from '../core/config.ts';

const MAX_MUSHROOMS = 1000; // Reduced from 4000 for WebGPU uniform buffer limits

Expand Down Expand Up @@ -562,8 +563,19 @@ export class MushroomBatcher {

// Emissive Logic for Cap (Bioluminescence + Flash)
const flashIntensity = smoothstep(0.2, 0.0, noteAge).mul(velocity).mul(2.0);
// 🎨 PALETTE: Let the cap breathe with the bass even when not directly triggered
const idlePulse = sin(uTime.mul(2.0)).mul(0.5).add(0.5).mul(uAudioLow.mul(0.5));

// 🎨 PALETTE: Twilight Glow System Support
// Apply phase offset based on instance index to prevent unison pulsing
const glowPhaseOffset = float(instanceIndex).mul(0.1);
const glowPulseFreq = float(CONFIG.glow.glowPulseFrequency);
const glowPulseAmp = float(CONFIG.glow.glowPulseAmplitude);

// Use a base idle pulse that responds to audio and time with the phase offset
const idlePulse = sin(uTime.mul(glowPulseFreq).add(glowPhaseOffset)).mul(glowPulseAmp).add(1.0).mul(float(0.5)).mul(uAudioLow.mul(0.5));

// Get the specific twilight glow color from config and multiply by twilight window
const targetGlowColor = color(CONFIG.glow.glowColorMap['mushroom']);
const twilightGlowTint = targetGlowColor.mul(uTwilight).mul(float(CONFIG.glow.glowIntensityMax));
const baseGlow = uTwilight.mul(float(0.5).add(idlePulse));

// Combine Glow + Flash + Sparkle
Expand All @@ -573,7 +585,9 @@ export class MushroomBatcher {
// Yes, let's add a fraction of inner glow to emissive for night visibility.
const totalGlow = baseGlow.add(flashIntensity).add(sugarSparkle).add(innerGlowFactor.mul(0.3));

capMat.emissiveIntensityNode = totalGlow;
// Add twilight glow directly to emissive node output
capMat.emissiveNode = twilightGlowTint.mul(totalGlow);
capMat.emissiveIntensityNode = float(1.0); // Resetting multiplier since we multiply inside node

// 2. Gills
const gillMat = (foliageMaterials.mushroomGills as MeshStandardNodeMaterial).clone();
Expand Down
19 changes: 17 additions & 2 deletions src/foliage/tree-batcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
import { applyGlitch } from './glitch.ts';
import { getCylinderGeometry, getTorusKnotGeometry } from '../utils/geometry-dedup.ts';
import { createSugarSparkle } from './index.ts';
import { uTwilight } from './sky.ts';
import { CONFIG } from '../core/config.ts';

const _defaultColorWhite = new THREE.Color(0xFFFFFF);
const _defaultColorOrange = new THREE.Color(0xFF4500);
Expand Down Expand Up @@ -130,6 +132,19 @@ export class TreeBatcher {
// Base Emissive logic based on High Freq Audio
const sphereEmissive = sphereColor.mul(uAudioHigh.mul(1.5).add(0.2));

// 🎨 PALETTE: Twilight Glow System Support
const instanceIndex = attribute('instanceIndex', 'uint');
const glowPhaseOffset = float(instanceIndex).mul(0.1);
const glowPulseFreq = float(CONFIG.glow.glowPulseFrequency);
const glowPulseAmp = float(CONFIG.glow.glowPulseAmplitude);

// Idle pulse responding to audio and time, with phase offset
const idlePulse = sin(uTime.mul(glowPulseFreq).add(glowPhaseOffset)).mul(glowPulseAmp).add(1.0).mul(float(0.5)).mul(uAudioLow.mul(0.5));

// Target glow color from config mapped to twilight
const targetGlowColor = color(CONFIG.glow.glowColorMap['tree']);
const twilightGlowTint = targetGlowColor.mul(uTwilight).mul(float(CONFIG.glow.glowIntensityMax)).mul(float(0.5).add(idlePulse));

// Add Sugar Sparkle! (Palette Polish)
// Scale 15.0 for fine grain, Density 0.3 for sparse twinkle, Intensity 2.0
const sugarSparkle = createSugarSparkle(normalWorld, float(15.0), float(0.3), float(2.0));
Expand All @@ -145,8 +160,8 @@ export class TreeBatcher {
audioReactStrength: 0.5 // Inner glow pulse
});

// 🎨 PALETTE: Make tree leaves pop with sparkly glow and base audio emissive
sphereMat.emissiveNode = sphereEmissive.add(sugarSparkle);
// 🎨 PALETTE: Make tree leaves pop with sparkly glow, base audio emissive, and twilight glow
sphereMat.emissiveNode = sphereEmissive.add(sugarSparkle).add(twilightGlowTint);

this.spheres = new THREE.InstancedMesh(sharedGeometries.unitSphere, sphereMat, this.sphereCapacity);
this.spheres.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(this.sphereCapacity * 3), 3);
Expand Down
Loading