Gate WebGL book texture fonts

This commit is contained in:
2026-06-07 14:35:00 +02:00
parent 9434950826
commit 74ddd1de1c
7 changed files with 74 additions and 31 deletions
+35 -12
View File
@@ -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-queued-mask-reveal';
import { PROCEDURAL_BOOK, createProceduralBookModel, snapProceduralPageCount } from './procedural-book-model.js?v=20260607-webgl-forced-font-mask';
const canvas = document.getElementById('scene');
canvas.style.cursor = 'grab';
@@ -184,7 +184,7 @@ let pendingPageFlips = 0;
const paperColor = new THREE.Color(0xece4ca);
const inkColor = '#1a1009';
const maxRevealWords = 128;
const maxRevealWords = 256;
const completedRevealElapsedMs = 1000000000;
await reportLabStep(48, 'Preparing high-resolution page textures');
@@ -570,6 +570,7 @@ function configureBookShadowReceiver(material, strength) {
shader.uniforms.bookRevealPaperColor = { value: paperColor.clone() };
shader.uniforms.bookRevealSoftness = { value: 0.035 };
material.userData.bookRevealShader = shader;
applyPendingPageReveal(pageReveal.side, shader);
}
shader.vertexShader = shader.vertexShader
@@ -607,14 +608,14 @@ function configureBookShadowReceiver(material, strength) {
${pageReveal ? `uniform float bookRevealActive;
uniform float bookRevealElapsedMs;
uniform int bookRevealWordCount;
uniform vec4 bookRevealWordRects[128];
uniform vec4 bookRevealWordTimings[128];
uniform vec4 bookRevealWordRects[256];
uniform vec4 bookRevealWordTimings[256];
uniform vec3 bookRevealPaperColor;
uniform float bookRevealSoftness;
float bookRevealVisibleMask(vec2 uv) {
float hidden = 0.0;
for (int i = 0; i < 128; i++) {
for (int i = 0; i < 256; i++) {
if (i >= bookRevealWordCount) break;
vec4 rect = bookRevealWordRects[i];
vec2 local = (uv - rect.xy) / max(rect.zw, vec2(0.0001));
@@ -1652,22 +1653,44 @@ function beginPageReveal(side, sourceCanvas, revealDetail = {}) {
const canvas = side === 'left' ? leftCanvas : rightCanvas;
const texture = side === 'left' ? leftTexture : rightTexture;
const shader = getPageRevealShader(side);
if (!shader?.uniforms) {
uploadPageTextureDirect(side, sourceCanvas);
return;
}
drawCanvasPageTexture(canvas, sourceCanvas, side);
texture.needsUpdate = true;
applyPageRevealWords(shader, revealDetail.wordRects || []);
shader.uniforms.bookRevealActive.value = 1;
shader.uniforms.bookRevealElapsedMs.value = 0;
pageRevealState[side] = {
startedAt: revealDetail.startNow ? performance.now() : null,
durationMs: Math.max(1, Number(revealDetail.durationMs || 1)),
blockIds: Array.isArray(revealDetail.blockIds) ? revealDetail.blockIds : []
};
const material = side === 'left' ? materials.leftPage : materials.rightPage;
if (material?.userData) material.userData.pendingPageReveal = revealDetail;
if (shader?.uniforms) applyPendingPageReveal(side, shader);
else if (material) material.needsUpdate = true;
document.documentElement.dataset.webglRevealDebug = JSON.stringify({
side,
blockIds: pageRevealState[side].blockIds,
wordCount: Array.isArray(revealDetail.wordRects) ? revealDetail.wordRects.length : 0,
shaderReady: Boolean(shader?.uniforms),
started: pageRevealState[side].startedAt != null
});
}
function applyPendingPageReveal(side, shader = getPageRevealShader(side)) {
const material = side === 'left' ? materials.leftPage : materials.rightPage;
const revealDetail = material?.userData?.pendingPageReveal;
if (!revealDetail || !shader?.uniforms) return false;
applyPageRevealWords(shader, revealDetail.wordRects || []);
shader.uniforms.bookRevealActive.value = 1;
shader.uniforms.bookRevealElapsedMs.value = 0;
document.documentElement.dataset.webglRevealDebug = JSON.stringify({
side,
blockIds: pageRevealState[side]?.blockIds || revealDetail.blockIds || [],
wordCount: Array.isArray(revealDetail.wordRects) ? revealDetail.wordRects.length : 0,
shaderReady: true,
started: pageRevealState[side]?.startedAt != null
});
delete material.userData.pendingPageReveal;
return true;
}
function applyPageRevealWords(shader, words = []) {