perf: ảnh mờ blur-up (LQIP) khi tải cảnh
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|||||||
import Lottie, { type LottieRefCurrentProps } from "lottie-react";
|
import Lottie, { type LottieRefCurrentProps } from "lottie-react";
|
||||||
import letterAnimation from "@/letter.json";
|
import letterAnimation from "@/letter.json";
|
||||||
import { chuaThaiLacTour } from "@/app/tours/chua-thai-lac";
|
import { chuaThaiLacTour } from "@/app/tours/chua-thai-lac";
|
||||||
|
import { lqip } from "@/app/tours/chua-thai-lac.lqip";
|
||||||
|
|
||||||
type SceneId = string;
|
type SceneId = string;
|
||||||
|
|
||||||
@@ -193,6 +194,23 @@ const defaultTourConfig = chuaThaiLacTourConfig;
|
|||||||
|
|
||||||
const getTourConfig = (tourId?: string) => toursById[tourId ?? ""] ?? defaultTourConfig;
|
const getTourConfig = (tourId?: string) => toursById[tourId ?? ""] ?? defaultTourConfig;
|
||||||
|
|
||||||
|
// Texture ảnh mờ (blur-up) tạo từ data-URI base64 — hiện gần như tức thì khi cảnh đang tải.
|
||||||
|
const lqipTextureCache = new Map<string, THREE.Texture>();
|
||||||
|
function loadLqipTexture(image: string) {
|
||||||
|
const data = lqip[image];
|
||||||
|
if (!data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const cached = lqipTextureCache.get(image);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
const texture = new THREE.TextureLoader().load(data);
|
||||||
|
texture.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
lqipTextureCache.set(image, texture);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
const panoramaTextureCache = new Map<string, THREE.Texture>();
|
const panoramaTextureCache = new Map<string, THREE.Texture>();
|
||||||
const panoramaTexturePromises = new Map<string, Promise<THREE.Texture>>();
|
const panoramaTexturePromises = new Map<string, Promise<THREE.Texture>>();
|
||||||
const panoramaTextureProgress = new Map<string, number>();
|
const panoramaTextureProgress = new Map<string, number>();
|
||||||
@@ -1635,6 +1653,11 @@ function TourExperience({
|
|||||||
if (cachedTexture) {
|
if (cachedTexture) {
|
||||||
prepareTransitionTexture(cachedTexture);
|
prepareTransitionTexture(cachedTexture);
|
||||||
} else {
|
} else {
|
||||||
|
const lqipTexture = loadLqipTexture(scene.image);
|
||||||
|
if (lqipTexture) {
|
||||||
|
transitionMaterial.map = lqipTexture;
|
||||||
|
transitionMaterial.needsUpdate = true;
|
||||||
|
}
|
||||||
loadPanoramaTexture(scene.image, (progress) => {
|
loadPanoramaTexture(scene.image, (progress) => {
|
||||||
if (transitionTokenRef.current === token) {
|
if (transitionTokenRef.current === token) {
|
||||||
setLoadProgress(progress);
|
setLoadProgress(progress);
|
||||||
@@ -1747,6 +1770,15 @@ function TourExperience({
|
|||||||
|
|
||||||
setIsLoading(!initialCachedTexture);
|
setIsLoading(!initialCachedTexture);
|
||||||
setLoadProgress(initialCachedTexture ? 100 : 0);
|
setLoadProgress(initialCachedTexture ? 100 : 0);
|
||||||
|
if (!initialCachedTexture) {
|
||||||
|
const lqipTexture = loadLqipTexture(scene.image);
|
||||||
|
if (lqipTexture) {
|
||||||
|
material.map = lqipTexture;
|
||||||
|
material.opacity = 1;
|
||||||
|
material.needsUpdate = true;
|
||||||
|
needsRenderRef.current = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
loadTexture
|
loadTexture
|
||||||
.then((texture) => {
|
.then((texture) => {
|
||||||
if (transitionTokenRef.current !== token) return;
|
if (transitionTokenRef.current !== token) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user