我正在使用Nextjs和3D库(如Three和React-Three)开发一个组合应用程序。
我使用Vercel部署应用程序。
我遇到了一个问题,即部署的应用程序中的3D模型在Android手机上显示为空白的白色正方形:
- 小米红米note7/ MI浏览器
- 三星s10 / chrome浏览器。
这个问题有解决办法吗?
展开部位:https://portfolio2-nu-ruddy.vercel.app/
Git Repo:https://github.com/ItayTur/Portfolio
三维模型组件:
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { useLoader, Canvas } from "@react-three/fiber";
import { Suspense, useEffect, useState } from "react";
import { OrbitControls, Preload } from "@react-three/drei";
import Loader from "./Loader";
const Computers = ({ isMobile = false }) => {
const gltf = useLoader(GLTFLoader, "/desktop_pc/scene.gltf");
return (
<mesh>
<hemisphereLight intensity={0.15} groundColor="black" />
<pointLight intensity={1} />
<spotLight
position={[-20, 50, 10]}
angle={0.12}
penumbra={1}
intensity={1}
castShadow
shadow-mapSize={1024}
/>
<primitive
scale={isMobile ? 0.7 : 0.75}
position={isMobile ? [0, -3, -2.2] : [0, -3.25, -1.5]}
rotation={[-0.01, -0.2, -0.1]}
object={gltf.scene}
/>
</mesh>
);
};
const ComputersCanvas = () => {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const mediaQuery = window.matchMedia("(max-width: 500px)");
setIsMobile(mediaQuery.matches);
const onMediaQueryChange = (event: MediaQueryListEvent) => {
setIsMobile(event.matches);
};
mediaQuery.addEventListener("change", onMediaQueryChange);
return () => {
mediaQuery.removeEventListener("change", onMediaQueryChange);
};
}, []);
return (
<Canvas
frameloop="demand"
shadows
camera={{ position: [20, 3, 5], fov: 25 }}
gl={{ preserveDrawingBuffer: true }}
>
<Suspense fallback={<Loader />}>
<OrbitControls
enableZoom={false}
maxPolarAngle={Math.PI / 2}
minPolarAngle={Math.PI / 2}
/>
<Computers isMobile={isMobile} />
</Suspense>
<Preload all />
</Canvas>
);
};
export default ComputersCanvas;
2条答案
按热度按时间5w9g7ksd1#
这个问题已经在我的三星Galaxy A32上重现。
解决方案
问题出在
Hero.tsx
;将alpha: true
添加到webGL配置中。说明
原因目前还不是很清楚。我只能猜测,因为控制台消息显示r3f示例没有被正确销毁。消息是从
chrome://inspect
获取的。WARNING: Too many active WebGL contexts. Oldest context will be lost., THREE.WebGLRenderer: Context Lost.
这些消息意味着每次挂载3D画布时,都会创建另一个不必要的webGL示例。多画布的正确实现应该只包含一个webGL示例,并在画布manually之间共享或使用门户。
我假设webGL缓冲区以某种方式被损坏,因此通过更改配置强制后台透明。
该错误在桌面浏览器中不可重现;这可能需要进一步深入调查。
0pizxfdo2#
我试着调试你的代码。有些东西阻止在Android的Chrome浏览器中渲染您的Canvas组件。我试图解决它,它似乎起作用了。你能尝试用下面的代码更新Computers.txs文件吗?
其余代码应该相同。
这是可行的,因为最初我们是在渲染div元素。
在第一次渲染之后,我们强制它使用Canvas元素重新渲染。
希望这能解决你的问题。
Thanks:)
更新:
很抱歉,我无法解决您的问题,因为它需要尝试不同的方法。但是,我可以给予你一些建议和想法,可以简化你的过程。主要问题在于android/移动的浏览器上的canvas行为。浏览器限制画布上下文的数量。我看到它一般是八,但它们可以是任何数字。
您可能已经注意到控制台消息
THREE.WebGLRenderer: Context Lost.