I have model:
import { useGLTF } from '@react-three/drei'
import React, { FC } from 'react'
import * as THREE from 'three'
import { GLTF } from 'three-stdlib'
type GLTFResult = GLTF & {
nodes: {
Sphere002: THREE.Mesh
}
materials: {
['Material.004']: THREE.MeshStandardMaterial
}
}
const Circle: FC<{
id?: number
position: THREE.Vector3
rotation: THREE.Euler
scale: THREE.Vector3
}> = ({ id, position, rotation, scale }) => {
const group = React.useRef<THREE.Group>()
const { nodes, materials } = useGLTF(
'/models/circle/circle.glb'
) as GLTFResult
return (
<group
ref={group}
dispose={null}
position={position}
rotation={rotation}
scale={scale}
>
<group name='Scene'>
<mesh
name='Sphere002'
geometry={nodes.Sphere002.geometry}
material={materials['Material.004']}
position={[-0.526, 0.553, 0.005]}
rotation={[0, 0.023, -Math.PI]}
scale={[-0.061, -0.349, -0.348]}
/>
</group>
</group>
)
}
useGLTF.preload('/models/circle/circle.glb')
export default Circle
Lights for model:
import { FC } from 'react'
const CirclesLight: FC = () => {
return (
<>
<directionalLight
intensity={40}
position={[-1.415, 0.917, 0.992]}
rotation={[-1.148, -0.935, -0.61]}
scale={2.532}
color={'#FF5406'}
/>
<directionalLight
intensity={40}
position={[0.15, 2.625, 0.264]}
rotation={[-1.148, -0.935, -0.61]}
scale={2.532}
color={'#FF5406'}
/>
<directionalLight
intensity={40}
position={[2.962, 0.751, -2.707]}
rotation={[3.134, 0.876, -1.583]}
scale={2.532}
color={'#FF5406'}
/>
<directionalLight
intensity={40}
position={[-0.796, 1.842, 2.19]}
rotation={[-0.537, -0.28, -0.233]}
scale={15.413}
color={'#FF5406'}
/>
<directionalLight
intensity={40}
position={[1.568, 2.731, -4.679]}
rotation={[-2.805, 0.128, -1.405]}
scale={15.413}
color='#2300ff'
/>
<pointLight
intensity={40}
decay={2}
color='#2300ff'
position={[0.547, 0.771, -0.857]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#2300ff'
position={[-1.886, 1.811, -0.489]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#fbffeb'
position={[-0.85, 2.098, -1.793]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#2300ff'
position={[2.057, 0.501, 0.403]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#fbffeb'
position={[-0.417, 1.693, -0.986]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#fbffeb'
position={[-0.31, 1.979, -0.487]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#fbffeb'
position={[1.746, -1.157, -1.342]}
rotation={[-Math.PI / 2, 0, 0]}
/>
<pointLight
intensity={40}
decay={2}
color='#2300ff'
position={[1.684, 0.807, -1.973]}
rotation={[-Math.PI / 2, 0, 0]}
/>
</>
)
}
export default CirclesLight
My navbar component:
'use client'
import { DynamicCircleModel } from '@/app/components/Models'
import Circle from '@/app/components/Models/Circles/Circle'
import CirclesLight from '@/app/components/Models/Circles/CirclesLight'
import { View } from '@/shared/components/canvas/View'
import Button from '@/shared/components/ui/Button'
import {
ANIMATION_DURATION,
CLOSED_MENU_ITEM_WIDTH,
} from '@/shared/data/constants'
import { sections } from '@/shared/data/data'
import { IStyle } from '@/shared/types/style.types'
import { useNavStore } from '@/store/navStore'
import { motion } from 'framer-motion'
import { FC, Suspense } from 'react'
import { twMerge } from 'tailwind-merge'
import { Euler, Vector3 } from 'three'
interface IProps {
id: number
text: string
styles: IStyle
href: string
}
const NavItem: FC<IProps> = ({ id, styles, text, href }) => {
const { activeId, setActiveId, stack } = useNavStore()
return (
<motion.li
onClick={() => {
setActiveId(id)
}}
initial={{
width: CLOSED_MENU_ITEM_WIDTH,
right: (sections.length - id) * CLOSED_MENU_ITEM_WIDTH,
top: styles.top === 0 ? '50%' : styles.top,
transform: styles.top === 0 ? 'translateY(-3%)' : 'none',
}}
animate={{
right: styles.right,
top: styles.top === 0 ? '50%' : styles.top,
transform: styles.top === 0 ? 'translateY(-3%)' : 'none',
width: styles.width,
}}
transition={{ duration: ANIMATION_DURATION, type: 'spring' }}
key={text + href + id}
className={twMerge(
'pl-5 absolute top-0 h-[calc(100vh)] before:w-0.5 before:h-[calc(100vh+100px)] before:absolute before:-top-[130px] before:bottom-10 before:left-0 before:bg-grey',
id === 2 && stack.includes(2) && 'before:-left-20',
`right-[${styles.right}px]`,
stack.includes(id) && activeId !== id && ' bg-black'
)}
>
<Button
className={twMerge('text-lg p-3', activeId === id && 'text-blue-300')}
>
{text}
{id === 2 && (
<>
<View
className={twMerge(
'absolute bottom-10 w-full -right-[250px] h-[500px]',
(activeId === id || stack.includes(id)) &&
'left-0 right-0 bottom-36 w-[200px]'
)}
>
<Suspense fallback={null}>
<DynamicCircleModel
rotation={new Euler(0.0, 6.11, 0.0)}
position={new Vector3(2.84, -3.36, 0.0)}
scale={new Vector3(5.57, 5.57, 5.57)}
/>
<CirclesLight />
</Suspense>
</View>
</>
)}
{id === 3 && (
<>
<View
className={twMerge(
'absolute bottom-10 -right-[125px] w-full h-[500px]',
(activeId === id || stack.includes(id)) &&
'-left-[140px] right-0 bottom-36 w-[200px]'
)}
>
<Suspense fallback={null}>
<Circle
rotation={new Euler(0.0, 0, 0.0)}
position={new Vector3(2.81, -3.92, 0.0)}
scale={new Vector3(6.7, 6.7, 6.7)}
/>
<Circle
rotation={new Euler(0.0, 6.13, 0.0)}
position={new Vector3(4.94, -4.86, 0.0)}
scale={new Vector3(8.88, 8.88, 8.88)}
/>
<CirclesLight />
<CirclesLight />
</Suspense>
</View>
</>
)}
{id === 4 && (
<>
<View
className={twMerge(
'absolute bottom-10 w-full h-[500px]',
(activeId === id || stack.includes(id)) &&
'-left-[240px] right-0 w-[200px] bottom-36'
)}
>
<Suspense fallback={null}>
<Circle
rotation={new Euler(0.0, 0, 0.0)}
position={new Vector3(2.81, -3.92, 0.0)}
scale={new Vector3(6.7, 6.7, 6.7)}
/>
<Circle
rotation={new Euler(0.0, 6.11, 0.0)}
position={new Vector3(2.99, -3.36, 0.0)}
scale={new Vector3(5.57, 5.57, 5.57)}
/>
<CirclesLight />
<CirclesLight />
</Suspense>
</View>
</>
)}
</Button>
</motion.li>
)
}
export default NavItem
Result: models image
When I add models to the site, the fps drops from 120 to 30. The weight of the model is 5 MB in compressed form and 50 MB in uncompressed form. I use components from https://github.com/pmndrs/react-three-next . Can you tell me how to optimize this?
Solved. The problem was in the poor quality 3D models. One such disk had over 600,000 polygons.