perf(nexus): implement performance tier optimization for low-end devices
This commit is contained in:
43
app.js
43
app.js
@@ -644,19 +644,31 @@ async function init() {
|
||||
playerPos = new THREE.Vector3(0, 2, 12);
|
||||
playerRot = new THREE.Euler(0, 0, 0, 'YXZ');
|
||||
|
||||
// Detect performance tier BEFORE creating renderer (antialias cannot be changed after)
|
||||
performanceTier = detectPerformanceTier();
|
||||
|
||||
const canvas = document.getElementById('nexus-canvas');
|
||||
renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
||||
const antialias = performanceTier !== 'low';
|
||||
renderer = new THREE.WebGLRenderer({ canvas, antialias });
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
||||
renderer.toneMappingExposure = 1.2;
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||
renderer.shadowMap.enabled = performanceTier !== 'low';
|
||||
renderer.shadowMap.type = performanceTier === 'high' ? THREE.PCFSoftShadowMap : THREE.BasicShadowMap;
|
||||
|
||||
performanceTier = detectPerformanceTier();
|
||||
updateLoad(10);
|
||||
|
||||
scene = new THREE.Scene();
|
||||
|
||||
// Fog density based on performance tier
|
||||
if (performanceTier === 'low') {
|
||||
// No fog for low tier
|
||||
scene.fog = null;
|
||||
} else if (performanceTier === 'medium') {
|
||||
scene.fog = new THREE.FogExp2(0x050510, 0.008);
|
||||
} else {
|
||||
scene.fog = new THREE.FogExp2(0x050510, 0.012);
|
||||
}
|
||||
|
||||
setupGOFAI();
|
||||
camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||
@@ -710,6 +722,20 @@ async function init() {
|
||||
fetchGiteaData();
|
||||
setInterval(fetchGiteaData, 30000); // Refresh every 30s
|
||||
|
||||
// Initialize post-processing based on performance tier
|
||||
// Low tier: No post-processing (avoids GPU stalls from readPixels)
|
||||
// Medium tier: RenderPass + SMAA only (no bloom)
|
||||
// High tier: Full post-processing with bloom
|
||||
if (performanceTier === 'low') {
|
||||
// No composer for low tier - use direct renderer.render()
|
||||
composer = null;
|
||||
} else if (performanceTier === 'medium') {
|
||||
composer = new EffectComposer(renderer);
|
||||
composer.addPass(new RenderPass(scene, camera));
|
||||
// Skip UnrealBloomPass to avoid GPU stalls from readPixels
|
||||
composer.addPass(new SMAAPass(window.innerWidth, window.innerHeight));
|
||||
} else {
|
||||
// High tier: Full post-processing with bloom
|
||||
composer = new EffectComposer(renderer);
|
||||
composer.addPass(new RenderPass(scene, camera));
|
||||
const bloom = new UnrealBloomPass(
|
||||
@@ -718,6 +744,7 @@ async function init() {
|
||||
);
|
||||
composer.addPass(bloom);
|
||||
composer.addPass(new SMAAPass(window.innerWidth, window.innerHeight));
|
||||
}
|
||||
|
||||
updateLoad(95);
|
||||
|
||||
@@ -2495,7 +2522,12 @@ function gameLoop() {
|
||||
core.material.emissiveIntensity = 1.5 + Math.sin(elapsed * 2) * 0.5;
|
||||
}
|
||||
|
||||
// Render based on performance tier (low tier bypasses composer to avoid GPU stalls)
|
||||
if (composer) {
|
||||
composer.render();
|
||||
} else {
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
updateAshStorm(delta, elapsed);
|
||||
updatePortalTunnel(delta, elapsed);
|
||||
@@ -2528,8 +2560,11 @@ function onResize() {
|
||||
camera.aspect = w / h;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(w, h);
|
||||
// Only resize composer if it exists (low tier has no composer)
|
||||
if (composer) {
|
||||
composer.setSize(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══ AGENT SIMULATION ═══
|
||||
function simulateAgentThought() {
|
||||
|
||||
Reference in New Issue
Block a user