Begin Threejs
Examples & Codes
example site: https://docs.pmnd.rs/react-three-fiber/getting-started/examples
vantajs: https://www.vantajs.com/
samples
- 3d model city: https://codesandbox.io/p/sandbox/lulaby-city-gkfhr?file=%2Fsrc%2FApp.js%3A21%2C28
- a typical scene: https://codesandbox.io/p/sandbox/threejs-journey-portal-ni6v4?file=%2Fpackage.json
Keywords & Tooling
keywords
- gltf (GL Transmission Format)
- glb: The GLB format is a version of the GLTF file
The difference is that the GLB format is a binary file format while the GLTF format is based on JSON (JavaScript Object Notation). The GLB locates all of the elements part of a 3D scene, including materials, node hierarchy and cameras, in one single compressed file.
- GLSL (The OpenGL Shading Language)
- threejs ShaderMaterial
- vertexShader
- fragmentShader
- threejs ShaderMaterial
3D model editor: blender
online glb preview
solidworks -> export to gltf -> convert to glb file
3dsmax -> export to fbx -> import in blender -> export to glb file
Libraries
- react-three-fiber - main lib
- three
- @types/three
- @react-three/fiber
- @react-three/drei – useful helpers, this is an eco system in itself
- @react-three/gltfjsx – turns GLTFs into JSX components
Quick Start
Basic imports
import { Canvas } from '@react-three/fiber';
import { useGLTF, useTexture } from '@react-three/drei';
const { nodes, materials } = useGLTF('/your-model-file.glb');
const bakedTexture = useTexture('/your-texture-file.jpeg');
<group>
<mesh geometry={nodes.Mesh_0061.geometry} material={materials['Material_0.414']} />
...
</goup>
or
const gltf = useGLTF('/your-model-file.glb');
<primitive object={gltf.scene} scale={0.1} position={[0, 0, 0]} dispose={null} />
Scale & position the group
<group ref={group} scale={0.1} position={[0, 0, 0]} />
Show the texture via adding the light
<Canvas camera={{ position: [0, 20, 40], fov: 40 }} className="aspect-[2/1]">
<ambientLight intensity={5} />
<Model />
</Canvas>
Set origin with pivot point
inside blender
- select model then press Tab
- move pivot point to the position you want
- back to view mode, object > set origin > origin to 3D cursor
ref: https://www.youtube.com/watch?v=qWdt0IMRe_4
Enable camera moves
add OrbitControls
import { OrbitControls } from '@react-three/drei';
<Canvas camera={{ position: [0, 20, 20], fov: 30 }} className="aspect-[2/1]">
<ambientLight intensity={5} />
<Model />
<OrbitControls />
</Canvas>
optionally add restrictions, for example, no under ground
<OrbitControls maxPolarAngle={Math.PI / 2} />
ref: https://stackoverflow.com/a/15827232/11872246
Auto scroll and scroll with page scrolling
const groupRef = useRef<any>();
useFrame(() => {
if (groupRef.current) {
groupRef.current.rotation.x += 0.0005;
}
});
useEffect(() => {
const handleScroll = () => {
if (groupRef.current) {
groupRef.current.rotation.x += window.scrollY / 1000000;
}
};
window.removeEventListener('scroll', handleScroll);
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
Add dynamic HTML content to goup
add a mesh with HTML and place it INSIDE the model group
ref: https://github.com/pmndrs/drei?tab=readme-ov-file#html
import { Html } from '@react-three/drei';
<group>
<mesh geometry={nodes.Mesh_0061.geometry} material={materials['Material_0.414']} />
...
<mesh position={[0, 0, 0]}>
<Html distanceFactor={10}>
<div>Your HTML content</div>
</Html>
</mesh>
</group>
to make it static, without rotating with camera, add transform
.
<Html distanceFactor={10} transform />
to enable it hidding behind geometry, use occlude
.
<Html distanceFactor={10} transform occlude />