Materials and Constants

In 3D graphics, a material describes how a surface looks — its texture, color, and shine. The scene3d library comes with a built-in material collection: bricks, marble, grass, planets, and more.

But before you start using them, you’ll learn a powerful coding habit: constants — named values that make your code easier to read, update, and reuse.

Open In Jupyter K-12

The Problem with Repeated Values

Run the code below. It creates two shapes using the same slate-grey color '#708090'.

Now look closely — that hex code appears twice. What if you wanted to repaint both shapes red? You’d need to find and change every occurrence. In a longer program, it’s easy to miss one and end up with a broken-looking scene.

import scene3d

scene = scene3d.Scene()
scene.set_sky('#1a1a2e')
scene.set_ground(length=10, width=10)

sphere = scene3d.Shapes.Sphere(diameter=1, segments=16)
sphere.set_color('#708090')
sphere.set_position(-2, 0.5, 0)
scene.add(sphere)

box = scene3d.Shapes.Box(width=1, height=1, depth=1)
box.set_color('#708090')
box.set_position(2, 0.5, 0)
scene.add(box)

Constants to the Rescue

A constant is a name you give to a value so you only have to write the value once. By convention, constant names are written in ALL_CAPS — this signals to any programmer reading the code:

“This is a fixed setting. Define it once at the top, then use the name everywhere.”

STONE = '#708090'

Now instead of writing '#708090' twice, you write STONE twice. To repaint both shapes, you change one line at the top — and everything updates.

Name What it signals
STONE A constant — a fixed, named value
sphere A regular variable
set_color A function call
'#708090' A magic value — no name, easy to mistype or miss

Try it: change STONE = '#708090' to STONE = '#e94560' on the first line of the code below and run again — both shapes change at once.

import scene3d

STONE = '#708090'

scene = scene3d.Scene()
scene.set_sky('#1a1a2e')
scene.set_ground(length=10, width=10)

sphere = scene3d.Shapes.Sphere(diameter=1, segments=16)
sphere.set_color(STONE)
sphere.set_position(-2, 0.5, 0)
scene.add(sphere)

box = scene3d.Shapes.Box(width=1, height=1, depth=1)
box.set_color(STONE)
box.set_position(2, 0.5, 0)
scene.add(box)

{ “question_type”: “multiple_choice”, “question”: “Which variable name follows the Python convention for a constant?”, “options”: [ { “key”: “a”, “text”: “nightSky” }, { “key”: “b”, “text”: “Night_Sky” }, { “key”: “c”, “text”: “nightsky” }, { “key”: “d”, “text”: “NIGHT_SKY” } ], “answer”: “d”, “submitted_answer”: “” }

{ “question_type”: “true_false”, “question”: “Python automatically prevents you from changing the value of a constant.”, “answer”: “False”, “submitted_answer”: “” }

Sky Constants — The Library Already Named Them

You’ve set the sky with hex colors like '#87ceeb'. But scene3d also includes pre-built sky environments, each with its own constant name:

Constant What it looks like
scene3d.Sky.CLOUDS Fluffy white clouds
scene3d.Sky.DEEP_SPACE Dark sky filled with stars
scene3d.Sky.PURE_SKY Clear blue sky
scene3d.Sky.MODERN_BUILDINGS City skyline reflections
scene3d.Sky.ORLANDO_STADIUM Stadium lighting

These are constants the library defined for you — you use them exactly the same way as any constant you’d write yourself.

Try swapping Sky.CLOUDS for another option in the code below.

import scene3d

scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.CLOUDS)
scene.set_ground(length=10, width=10)

sphere = scene3d.Shapes.Sphere(diameter=1.5, segments=24)
sphere.set_color('#e94560')
sphere.set_position(0, 0.75, 0)
scene.add(sphere)

Giving the Ground a Material

set_ground returns a mesh — the same kind of object as a sphere or box. That means you can call set_material on it to apply a texture:

ground = scene.set_ground(length=20, width=20)
ground.set_material(scene3d.Material.Grass.Bright)
ground.set_tiling(8)

set_tiling(8) repeats the texture 8 times across the surface. Without tiling, a single tile would stretch to cover the entire ground and look blurry.

import scene3d

scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)

ground = scene.set_ground(length=20, width=20)
ground.set_material(scene3d.Material.Grass.Bright)
ground.set_tiling(8)

sphere = scene3d.Shapes.Sphere(diameter=1.5, segments=24)
sphere.set_color('#e94560')
sphere.set_position(0, 0.75, 0)
scene.add(sphere)

Materials on Shapes

set_material works on any shape — sphere, box, or cylinder. The materials are organized into groups. Here are some to explore:

Group Constants Works great on…
Material.Bricks .DarkClay, .RoughStone Boxes
Material.Marble .Gray, .Brown, .Black Spheres, cylinders
Material.Planets .Earth, .Mars, .Jupiter Spheres
Material.Wood .Oak Cylinders, boxes
Material.Snow .Fresh Any surface
Material.Fabric .Denim, .BurgundyRibbed Any surface

You can also control shine with set_glossiness: - 0.0 = completely matte - 1.0 = mirror-like

set_glossiness only works on shapes that use set_material — it has no effect on plain set_color shapes.

import scene3d

scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)
ground = scene.set_ground(length=20, width=20)
ground.set_material(scene3d.Material.Grass.Bright)
ground.set_tiling(8)

box = scene3d.Shapes.Box(width=2, height=2, depth=2)
box.set_material(scene3d.Material.Bricks.DarkClay)
box.set_position(-3, 1, 0)
scene.add(box)

sphere = scene3d.Shapes.Sphere(diameter=2, segments=24)
sphere.set_material(scene3d.Material.Marble.Gray)
sphere.set_glossiness(0.8)
sphere.set_position(3, 1, 0)
scene.add(sphere)

{ “question_type”: “multiple_choice”, “question”: “What does set_material() do?”, “options”: [ { “key”: “a”, “text”: “Changes the shape of an object” }, { “key”: “b”, “text”: “Applies a pre-built texture and lighting material to a surface” }, { “key”: “c”, “text”: “Moves an object to a new position” }, { “key”: “d”, “text”: “Sets the background sky color” } ], “answer”: “b”, “submitted_answer”: “” }

{ “question_type”: “true_false”, “question”: “set_glossiness(0.9) works on a sphere that has only had set_color applied.”, “answer”: “False”, “submitted_answer”: “” }

Your Material Library

When you gather all the material choices into named constants at the top of your code, they form a material library — a single place where the look of the entire scene is defined.

Try swapping any of the three constants below: - SKY — try Sky.CLOUDS, Sky.MODERN_BUILDINGS, Sky.ORLANDO_STADIUM - GROUND — try Material.Snow.Fresh, Material.Gravel.LightGray - PLANET — try Material.Planets.Mars, Material.Planets.Jupiter, Material.Planets.Venus

import scene3d

SKY    = scene3d.Sky.DEEP_SPACE
GROUND = scene3d.Material.Gravel.LightGray
PLANET = scene3d.Material.Planets.Earth

scene = scene3d.Scene()
scene.set_sky(SKY)

ground = scene.set_ground(length=20, width=20)
ground.set_material(GROUND)
ground.set_tiling(8)

planet = scene3d.Shapes.Sphere(diameter=3, segments=32)
planet.set_material(PLANET)
planet.set_position(0, 1.5, 0)
scene.add(planet)

{ “question_type”: “multiple_choice”, “question”: “What is the main advantage of using STONE = ‘#708090’ instead of writing ‘#708090’ each time?”, “options”: [ { “key”: “a”, “text”: “It makes Python run faster” }, { “key”: “b”, “text”: “It prevents the color from ever being changed” }, { “key”: “c”, “text”: “Updating all uses only requires editing one line” }, { “key”: “d”, “text”: “It makes the hex code valid” } ], “answer”: “c”, “submitted_answer”: “” }

{ “question_type”: “multiple_choice”, “question”: “Which is the correct way to define a constant for the Bricks.DarkClay material?”, “options”: [ { “key”: “a”, “text”: “wall = scene3d.Material.Bricks.DarkClay” }, { “key”: “b”, “text”: “Wall = scene3d.Material.Bricks.DarkClay” }, { “key”: “c”, “text”: “WALL = scene3d.Material.Bricks.DarkClay” }, { “key”: “d”, “text”: “wall_Material = scene3d.Material.Bricks.DarkClay” } ], “answer”: “c”, “submitted_answer”: “” }

Think of a scene you’d like to build — a beach, a space station, a snowy forest, or anything you like.

Write out a mini material library for it: at least three constants with ALL_CAPS names, each set to a scene3d.Sky or scene3d.Material value. For example:

SKY = scene3d.Sky.DEEP_SPACE
GROUND = scene3d.Material.Snow.Fresh

Describe what the finished scene would look like.