Navigate
Search topics across all sections
Basic Materials
Think of materials as the "skin" of your 3D objects. Basic materials are the simplest ones Three.js offers — they are fast, predictable, and some of them do not need lights at all to show up on screen.
You add a beautiful mesh to your scene with MeshStandardMaterial, but it shows up completely black. You try changing the color — still black. You spend 20 minutes debugging before realizing there are no lights in your scene. If you had used MeshBasicMaterial, the color would have shown up immediately.
Mesh renders but appears completely black despite having a color set.
Real-world
Imagine you are standing in a paint store with four types of paint in front of you.
Basic is like spray paint — flat, solid color, no light interaction at all. What you spray is what you see.
Normal is like a mood ring — it changes color based on the angle you look at it, showing you which direction each part of the surface faces.
Lambert is like chalk paint — matte and soft, it reacts to light but never looks shiny.
Phong is like nail polish — it has that glossy, reflective highlight that shifts as you move around it.
Which Material Should I Pick?
Here is a quick decision flow. Start at the left and follow the arrows.
Need lights?
Does your object need to react to scene lighting?
No lights needed
Basic or Normal
Matte surface?
Lambert (cheap, soft)
Shiny surface?
Phong (specular highlight)
Guided Walkthrough
Let us build up from the simplest material to a shiny one, step by step.
Step 1 — A flat-colored sphere (no lights needed)
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshBasicMaterial color="#4488ff" />
</mesh>This creates a blue sphere that shows up instantly. No lights, no setup — just color. Think of it like spray painting a ball.
Step 2 — A matte surface that reacts to light
<ambientLight intensity={0.3} />
<directionalLight position={[5, 5, 5]} />
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshLambertMaterial color="#44ccaa" />
</mesh>Now we added lights and switched to Lambert. The sphere looks soft and matte, like a chalk-painted ball. The side facing the light is brighter, giving it a 3D feel.
Step 3 — Adding a shiny highlight
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshPhongMaterial
color="#88ff44"
specular="#ffffff"
shininess={200}
/>
</mesh>Phong adds a bright spot where the light hits — like a glossy nail polish reflection. The shininess value controls how tight that highlight is. Higher numbers mean a smaller, sharper spot.
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshBasicMaterial color="#4488ff" />
</mesh>
{/* No lights needed — always visible */}MeshBasicMaterial shows flat color with no shading — always visible, even without lights.
What you just learned
MeshBasicMaterial ignores all lights — what you set is what you see
MeshNormalMaterial maps surface angles to colors, perfect for debugging geometry
MeshLambertMaterial gives you a cheap matte look but needs lights in the scene
MeshPhongMaterial adds a specular highlight for shiny, glossy surfaces
Question
If MeshBasicMaterial does not respond to lights, why would you ever use it in a serious project? Hint: think about UI elements floating in 3D space, always-visible markers, or a skybox that should not get darker when the sun sets.
Think about it...
You have a scene with no lights at all. Which materials will still show their color on screen?
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 lightIntensity to 0 — which spheres are still visible?
Try This!
Beginner
Toggle wireframe on all materials
Try This!
Intermediate
Move the light behind the objects
These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.
// You just want to see a red cube for debugging
<mesh>
<boxGeometry />
<meshStandardMaterial color="red" />
</mesh>
// No lights in scene = completely black cube// Swap texture at runtime
material.map = newTexture;
// Nothing changes — the shader is still compiled
// for the old configurationBest Practices
Use Basic for debug visuals
When you just need to see a shape, wireframe, or bounding box, reach for MeshBasicMaterial. It works without lights and is the cheapest material to render.
Prefer Lambert over Phong for matte
If a surface has no visible shiny spot, Lambert is faster than Phong. It skips the specular calculation entirely, saving GPU work on every pixel.
Normal material for geometry checks
Swap in MeshNormalMaterial to instantly check if your geometry normals look correct. Unexpected colors mean the normals are flipped or missing.
Dispose materials you no longer need
Call material.dispose() when a material is no longer used. This frees the GPU shader program and prevents memory leaks in long-running apps.