First of all, I'm sorry I'm not good at English.
i use react and I made a 3d rendering component by loading the obj file
(My source is attached below.)
my problem is below
3D object is rendered in 3 seconds.
However, for about 8 seconds after rendering, it stutters even when dragging, and other screens stutter.
After 8 seconds, dragging does not stumble and the buttons on the screen are clicked well.
What can I do to shorten the stuttering time like this?
Hope you share the wisdom of the teachers, thank you in advance
import React, {useMemo, useRef, useEffect, useState, Suspense} from 'react';
import * as THREE from 'three';
import {Canvas, useFrame, useGraph, useLoader, useThree, createPortal, ObjectMap} from "@react-three/fiber";
import {OrbitControls, OrthographicCamera, useCamera, Html, useProgress, Stats, Center} from "@react-three/drei";
import styled from "styled-components";
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader'
import {CameraControls, CameraControlsType} from "./cameraControls";
import LightController from "./lightController";
// @ts-ignore
import objectImage from 'assets/images/NT_NO061/NT_NO061.obj';
import aoMapImage from 'assets/images/NT_NO061/Textures/T_NT_NO061_AO.png';
import mapImage from 'assets/images/NT_NO061/Textures/T_NT_NO061_D.png';
import normalMapImage from 'assets/images/NT_NO061/Textures/T_NT_NO061_N.png';
import roughnessMapImage from 'assets/images/NT_NO061/Textures/T_NT_NO061_R.png';
type geometryType = {
attach: string,
vertices: any,
onUpdate: any
}
type flag = {
video: boolean,
minimap: boolean
}
const Wrapper = styled.div`
canvas {
height: 594px
}
`
const ReactThreeFiber = () => {
const cameraControls = useRef<CameraControlsType | null>(null) as any;
const [aoMap, map, normalMap, roughnessMap] = useLoader(THREE.TextureLoader, [
aoMapImage,
mapImage,
normalMapImage,
roughnessMapImage
])
const [progressValue, setProgressValue] = useState<number>(0);
const scene = useLoader(OBJLoader, objectImage, loader => {
loader.manager.onProgress = (url, loaded, total) => {
console.log('url, loaded, total', url, loaded, total)
}
}) as any;
const {nodes} = useGraph(scene) as ObjectMap;
const {geometry} = useMemo(() => nodes[Object.keys(nodes)[0]] as any, []);
const material = useMemo(() => new THREE.MeshStandardMaterial({
aoMap,
map,
normalMap,
roughnessMap,
roughness: 0.5,
metalness: 0.80
}), [])
let startPoint = 3
const lookAtPos = new THREE.Vector3()
const rotate = () => {
cameraControls.current.rotate(Math.PI / 4, 0, true)
}
const reset = () => {
cameraControls.current.reset(true);
}
const startVideo = () => {
cameraControls.current.reset(true);
}
return (
<Wrapper>
<Canvas
camera={{position: [3, 3, 3]}}
onCreated={({scene}) => scene.background = new THREE.Color('#000')}
frameloop={'demand'}
>
<CameraControls
ref={cameraControls}
minDistance={2}
maxDistance={7}
/>
<LightController/>
<OrbitControls/>
<Center>
<mesh
position={[0, -2, 0]}
geometry={geometry}
material={material}
/>
</Center>
<Stats/>
</Canvas>
</Wrapper>
);
}
export default React.memo(ReactThreeFiber);
and "CameraControls" components codes
/* eslint-disable */
import React, { forwardRef, ForwardedRef, MutableRefObject, useEffect, useRef } from 'react';
import {
MOUSE,
Vector2,
Vector3,
Vector4,
Quaternion,
Matrix4,
Spherical,
Box3,
Sphere,
Raycaster,
MathUtils,
} from 'three';
import { ReactThreeFiber, extend, useFrame, useThree } from '@react-three/fiber';
import CameraControlsDefault from 'camera-controls';
declare global {
namespace JSX {
interface IntrinsicElements {
cameraControlsDefault: ReactThreeFiber.Node<CameraControlsDefault, typeof CameraControlsDefault>;
}
}
}
const subsetOfTHREE = {
MOUSE: MOUSE,
Vector2: Vector2,
Vector3: Vector3,
Vector4: Vector4,
Quaternion: Quaternion,
Matrix4: Matrix4,
Spherical: Spherical,
Box3: Box3,
Sphere: Sphere,
Raycaster: Raycaster,
MathUtils: {
DEG2RAD: MathUtils.DEG2RAD,
clamp: MathUtils.clamp,
},
};
CameraControlsDefault.install({ THREE: subsetOfTHREE });
extend({ CameraControlsDefault });
type PropsType = {
minDistance: number,
maxDistance: number
}
export const CameraControls = forwardRef<CameraControlsDefault, PropsType>((props, ref) => {
const { minDistance, maxDistance } = props;
const cameraControls = useRef<CameraControlsDefault | null>(null);
const { camera, gl } = useThree();
useFrame((_, delta) => {
cameraControls.current?.update(delta)
});
useEffect(() => {
if (cameraControls != undefined && cameraControls.current != undefined) {
cameraControls.current.minDistance = minDistance;
cameraControls.current.maxDistance = maxDistance;
}
return () => cameraControls.current?.dispose()
}, []);
return (
<cameraControlsDefault
ref={mergeRefs<CameraControlsDefault>(cameraControls, ref)}
args={[camera, gl.domElement]}
/>
);
});
export type CameraControlsType = CameraControlsDefault;
function mergeRefs<T>(...refs: (MutableRefObject<T> | ForwardedRef<T>)[]) {
return (instance: T): void => {
for (const ref of refs) {
if (typeof ref === 'function') {
ref(instance);
} else if (ref) {
ref.current = instance;
}
}
};
}