Navigate
Search topics across all sections
Mesh Component
A mesh is the most fundamental visible thing in 3D. If you can see it in a 3D scene, it is probably a mesh. But a mesh by itself is nothing -- it needs two ingredients: a shape (the geometry) and a surface look (the material). Think of it as a mannequin wearing an outfit. The mannequin is the geometry. The outfit is the material. Together, they make something you can actually see.
You create a beautiful sphere with meshStandardMaterial in a nice coral color. But when you run the app, the sphere is completely black. The shape is there -- you can see the silhouette against the background -- but the color is gone. It looks like a black hole.
Scene renders but all objects appear black. meshStandardMaterial requires light sources to calculate color. No <ambientLight> or <directionalLight> found in scene.
Real-world
Picture a mannequin in a clothing store. The mannequin has a body shape -- arms, torso, legs. That is the geometry. Now dress it in a red silk shirt. The shirt has color, texture, and shininess. That is the material.
A naked mannequin is invisible in 3D (no material = nothing to render). A shirt floating in mid-air has no form (no geometry = nothing to shape). You need both. The mesh is the combination: body plus clothing equals something you can see and interact with.
Geometry
The shape (box, sphere, torus)
+
Material
The look (color, texture, shine)
=
Mesh
A visible 3D object
Dressing a Mannequin
Let us build a mesh step by step. First the body, then the outfit, then we will bring it to life with animation.
Geometry defines the form. R3F gives you all of Three.js's built-in shapes: boxes, spheres, cylinders, torus knots, and more. The args array controls the dimensions.
{/* A box: width, height, depth */}
<boxGeometry args={[1, 1, 1]} />
{/* A sphere: radius, widthSegments, heightSegments */}
<sphereGeometry args={[0.6, 32, 32]} />More segments means a smoother shape, but also more work for your GPU. A sphere with 32 segments looks smooth. One with 8 looks like a gem.
Material controls how the surface looks. Different materials have different capabilities and performance costs.
{/* Basic: always visible, ignores light */}
<meshBasicMaterial color="hotpink" />
{/* Standard: realistic, needs lights */}
<meshStandardMaterial color="coral" />
{/* Physical: most realistic, most expensive */}
<meshPhysicalMaterial
color="gold"
metalness={1}
roughness={0.2}
/>Think of materials on a spectrum: Basic is a t-shirt (cheap, simple), Standard is a nice jacket (good looking, reasonable cost), Physical is a tailored suit (stunning, expensive).
Wrap the geometry and material inside a <mesh> tag. Add position, rotation, or scale to place it in your scene.
<mesh position={[0, 1, 0]}>
<sphereGeometry args={[0.6, 32, 32]} />
<meshStandardMaterial color="coral" />
</mesh>That is a coral-colored sphere floating 1 unit above the origin. The mannequin (sphere shape) is dressed (coral standard material) and placed in the scene.
What you just learned
A mesh is geometry (shape) + material (appearance)
Geometry defines vertices, faces, and the form of the object
Material defines color, roughness, metalness, and how light interacts
meshBasicMaterial ignores lights; meshStandardMaterial needs them
Use args for geometry dimensions; use props for material properties
Animate meshes with useFrame and refs, never with useState
Question
Can two meshes share the same geometry or material? Why would you want to do that?
Yes, and you should whenever possible. If you have 100 trees that all use the same trunk shape, sharing one geometry means one set of vertices in GPU memory instead of 100. Same for materials. Shared resources = less memory, better performance. In R3F, you can share by passing a ref or by using useMemo.
Think about it...
You place a mesh with meshStandardMaterial in your scene but forget to add lights. What do you see?
Hint: Think about what happens in a completely dark room. Can you see the shape of an object?
Try These Challenges
Put what you learned into practice. Try each challenge in the demo above using the Leva controls, then check the solution.
Try This!
Beginner
Set wireframe={true} on all materials -- what do you see?
Try This!
Beginner
Change metalness to 1 and roughness to 0 -- mirror effect!
Try This!
Intermediate
Remove all lights from the scene -- which shapes are still visible?
These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.
function MyMesh() {
// Recreated on EVERY render!
const geo = new THREE.BoxGeometry(1, 1, 1)
const mat = new THREE.MeshStandardMaterial()
return <mesh geometry={geo} material={mat} />
}// Renders completely black
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial color="coral" />
</mesh><mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial
transparent opacity={0.3}
color="skyblue"
/>
</mesh>Best Practices
Share geometry and material
Reuse the same instances across identical meshes. Use module-level constants or useMemo to avoid creating duplicates.
Use the simplest material
Do not default to MeshPhysicalMaterial. If you do not need realistic lighting, MeshBasicMaterial is much cheaper and always visible without lights.
Lower segments for distant objects
A sphere with 64 segments and one with 16 look the same when far away. Fewer segments means less GPU work. Start low and increase only if you notice facets.
Animate with refs, not state
For 60fps animations, mutate through a ref inside useFrame. Using useState triggers React re-renders which is far too slow for smooth animation.