Stage WebGL scene loading
This commit is contained in:
@@ -4,7 +4,7 @@ import { RenderPass } from 'https://esm.sh/three@0.165.0/examples/jsm/postproces
|
||||
import { SSAOPass } from 'https://esm.sh/three@0.165.0/examples/jsm/postprocessing/SSAOPass.js';
|
||||
import { SMAAPass } from 'https://esm.sh/three@0.165.0/examples/jsm/postprocessing/SMAAPass.js';
|
||||
import { OutputPass } from 'https://esm.sh/three@0.165.0/examples/jsm/postprocessing/OutputPass.js';
|
||||
import { PROCEDURAL_BOOK, createProceduralBookModel, snapProceduralPageCount } from './procedural-book-model.js?v=20260607-webgl-physical-stack-quality';
|
||||
import { PROCEDURAL_BOOK, createProceduralBookModel, snapProceduralPageCount } from './procedural-book-model.js?v=20260607-webgl-loader-quality-fix';
|
||||
|
||||
const canvas = document.getElementById('scene');
|
||||
canvas.style.cursor = 'grab';
|
||||
@@ -25,7 +25,7 @@ const appInitialState = window.WebGLBookInitialState || {};
|
||||
const tableDebugName = urlParams.get('tableDebug') || 'none';
|
||||
const tableDebugMode = tableDebugModes[tableDebugName] ?? tableDebugModes.none;
|
||||
const isAppIntegrationMode = appInitialState.appMode === true;
|
||||
const appRenderPixelRatio = Math.min(window.devicePixelRatio || 1, 2);
|
||||
const appRenderPixelRatio = 2;
|
||||
const labStatus = document.getElementById('lab_status');
|
||||
if (labStatus && tableDebugMode !== tableDebugModes.none) {
|
||||
labStatus.textContent = tableDebugName === 'ao' ? 'scene debug: SSAO' : `table debug: ${tableDebugName}`;
|
||||
@@ -40,7 +40,7 @@ renderer.shadowMap.type = THREE.VSMShadowMap;
|
||||
|
||||
const generatedTextureCanvases = {};
|
||||
const maxTextureAnisotropy = renderer.capabilities.getMaxAnisotropy();
|
||||
const reflectionPixelRatio = Math.min(window.devicePixelRatio || 1, 2);
|
||||
const reflectionPixelRatio = 2;
|
||||
const pageTextureWidth = 3072;
|
||||
const reflectionTargetSize = new THREE.Vector2();
|
||||
const pageRaycaster = new THREE.Raycaster();
|
||||
@@ -56,6 +56,17 @@ let renderedFrameCount = 0;
|
||||
let staticSceneBuffersDirty = true;
|
||||
let lastStaticCameraSignature = '';
|
||||
|
||||
function reportLabProgress(percent, message) {
|
||||
if (typeof appInitialState.reportProgress === 'function') {
|
||||
appInitialState.reportProgress(percent, message);
|
||||
}
|
||||
}
|
||||
|
||||
async function reportLabStep(percent, message) {
|
||||
reportLabProgress(percent, message);
|
||||
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||
}
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x080604);
|
||||
scene.fog = new THREE.FogExp2(0x080604, 0.035);
|
||||
@@ -174,6 +185,7 @@ let pendingPageFlips = 0;
|
||||
const paperColor = new THREE.Color(0xf1ead2);
|
||||
const inkColor = '#1a1009';
|
||||
|
||||
await reportLabStep(48, 'Preparing high-resolution page textures');
|
||||
const leftCanvas = createPageCanvas('left');
|
||||
const rightCanvas = createPageCanvas('right');
|
||||
const leftTexture = new THREE.CanvasTexture(leftCanvas);
|
||||
@@ -185,10 +197,15 @@ const rightTexture = new THREE.CanvasTexture(rightCanvas);
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.generateMipmaps = true;
|
||||
});
|
||||
await reportLabStep(52, 'Generating leather texture set');
|
||||
const leatherTextures = createLeatherTextures();
|
||||
await reportLabStep(56, 'Generating spine cloth texture set');
|
||||
const spineClothTextures = createSpineClothTextures();
|
||||
await reportLabStep(60, 'Generating headband texture set');
|
||||
const headbandTextures = createHeadbandTextures();
|
||||
await reportLabStep(64, 'Generating paper texture set');
|
||||
const paperTextures = createHardcoverPaperTextures();
|
||||
await reportLabStep(68, 'Creating WebGL book materials');
|
||||
|
||||
const materials = {
|
||||
leather: new THREE.MeshStandardMaterial({
|
||||
@@ -344,11 +361,18 @@ configureBookShadowReceiver(materials.rightPage, 0.18);
|
||||
configureBookShadowReceiver(materials.spineCloth, 0.48);
|
||||
configureBookShadowReceiver(materials.headband, 0.62);
|
||||
|
||||
await reportLabStep(70, 'Building reflective table');
|
||||
buildTable();
|
||||
await reportLabStep(74, 'Building candle lighting');
|
||||
buildLighting();
|
||||
await reportLabStep(78, 'Building physical book stack');
|
||||
buildBook();
|
||||
notifyBookPageCountChanged();
|
||||
await reportLabStep(82, 'Loading room reflection texture');
|
||||
loadAiRoomReflection();
|
||||
await reportLabStep(86, 'Preparing static shadow and mirror maps');
|
||||
primeSceneForLoader();
|
||||
await reportLabStep(90, 'Compiled WebGL scene passes');
|
||||
window.BookLabDebug = {
|
||||
textures: generatedTextureCanvases,
|
||||
ready: false,
|
||||
@@ -1534,6 +1558,7 @@ function handlePageCanvases(event) {
|
||||
drawCanvasPageTexture(rightCanvas, detail.right, 'right');
|
||||
rightTexture.needsUpdate = true;
|
||||
}
|
||||
markStaticSceneBuffersDirty();
|
||||
document.documentElement.dataset.webglPageTextureMetrics = JSON.stringify({
|
||||
width: leftCanvas.width,
|
||||
height: leftCanvas.height,
|
||||
@@ -2586,6 +2611,7 @@ function loadAiRoomReflection() {
|
||||
if (tableShader) {
|
||||
tableShader.uniforms.roomReflectionMap.value = texture;
|
||||
}
|
||||
markStaticSceneBuffersDirty();
|
||||
|
||||
const image = texture.image;
|
||||
if (!image) return;
|
||||
@@ -2596,11 +2622,22 @@ function loadAiRoomReflection() {
|
||||
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
||||
generatedTextureCanvases.aiRoomReflection = canvas;
|
||||
tintAmbientFromCanvas(canvas);
|
||||
markStaticSceneBuffersDirty();
|
||||
}, undefined, () => {
|
||||
tintAmbientFromCanvas(generatedTextureCanvases.roomReflection);
|
||||
markStaticSceneBuffersDirty();
|
||||
});
|
||||
}
|
||||
|
||||
function primeSceneForLoader() {
|
||||
updateCameraRig(0);
|
||||
updateCandleShadowUniforms();
|
||||
updateBookShadowMaps();
|
||||
updateTableReflection();
|
||||
renderer.compile(scene, camera);
|
||||
staticSceneBuffersDirty = false;
|
||||
}
|
||||
|
||||
function tintAmbientFromCanvas(canvas) {
|
||||
if (!canvas || !candleBounceLight) return;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
Reference in New Issue
Block a user