import scene3d
scene = scene3d.Scene()
scene.set_sky('#1a1a2e')
scene.set_ground(length=14, width=14)
for x, color in [(-3, '#e94560'), (0, '#f5a623'), (3, '#44cc88')]:
s = scene3d.Shapes.Sphere(diameter=1.2, segments=16)
s.set_color(color)
s.set_position(x, 0.6, 0)
scene.add(s)
# Bird's-eye view — camera directly above, looking straight down
scene.camera.set_position(0, 14, 0).look_at(0, 0, 0)Camera Control
Every scene3d scene gives you a free-roaming camera by default — click and drag to orbit, scroll to zoom. But sometimes you want to place the camera exactly where it should be: a bird’s-eye view, a close-up of one object, or a camera that tracks a moving character.
scene.camera gives you full control over where the camera sits, what it looks at, and whether it should follow a moving mesh.
Placing the Camera — set_position and look_at
By default the camera starts behind and above the scene, pointed at the origin. set_position(x, y, z) teleports it to any world coordinate you choose. look_at() then swivels it to face a mesh or a point in space.
scene.camera.set_position(0, 14, 0) # directly above the scene
scene.camera.look_at(0, 0, 0) # looking straight down at the origin
scene.camera.set_position(8, 4, -8) # high and to the side
scene.camera.look_at(box) # pointing at a specific meshThe cell below uses a bird’s-eye view. Run it, then try orbiting with the mouse — you can still move the camera freely after any set_position call.
Camera Coordinates
The camera lives in the same 3D world as every shape. Its position uses the same axes:
y (up)
|
| z (toward camera, away from scene)
| /
| /
+---------- x (right)
| Position | What you see |
|---|---|
(0, 14, 0) |
Straight down from above |
(0, 5, -15) |
Default-like — behind and slightly above |
(15, 2, 0) |
Side view from the right |
(0, 1, -3) |
Ground level, close up |
Methods can be chained because each one returns scene.camera:
scene.camera.set_position(8, 6, -8).look_at(box){ “question_type”: “multiple_choice”, “question”: “scene.camera.set_position(0, 14, 0).look_at(0, 0, 0) places the camera:”, “options”: [ { “key”: “a”, “text”: “In front of the scene at eye level” }, { “key”: “b”, “text”: “Directly above the scene, looking down” }, { “key”: “c”, “text”: “Behind the scene, looking forward” }, { “key”: “d”, “text”: “To the right of the scene” } ], “answer”: “b”, “submitted_answer”: “” }
set_distance — Zooming In and Out
set_distance() controls how far the camera sits from its target — a fast way to zoom without repositioning the camera entirely.
scene.camera.set_distance(5) # close-up
scene.camera.set_distance(30) # wide establishing shotUse the sliders to explore different heights and distances and see how they change the feel of the scene.
import scene3d
CAMERA_HEIGHT = 6 #@param {type:"slider", min:2, max:16, step:1}
CAMERA_DISTANCE = 12 #@param {type:"slider", min:4, max:30, step:2}
scene = scene3d.Scene()
scene.set_sky('#0f3460')
scene.set_ground(length=14, width=14)
box = scene3d.Shapes.Box(width=1.5, height=1.5, depth=1.5)
box.set_color('#e94560')
box.set_position(-2, 0.75, 0)
scene.add(box)
sphere = scene3d.Shapes.Sphere(diameter=1.4, segments=16)
sphere.set_color('#4488ff')
sphere.set_position(2, 0.7, 0)
scene.add(sphere)
scene.camera.set_position(0, CAMERA_HEIGHT, -CAMERA_DISTANCE).look_at(0, 0, 0){ “question_type”: “true_false”, “question”: “scene.camera.set_distance(5) moves the camera closer to its current target.”, “answer”: “True”, “submitted_answer”: “” }
follow — Tracking a Moving Object
scene.camera.follow(mesh) makes the camera automatically track a mesh every frame. As the mesh moves, the camera moves with it to keep it in view.
scene.camera.follow(ball) # track the ball
scene.camera.follow(ball, distance=12) # track at a specific distance
scene.camera.follow(None) # stop followingThe scene below has a bouncing ball that travels left and right. The camera follows it the whole way. Click Stop (■) when you’re done.
import scene3d
import math
scene = scene3d.Scene()
scene.set_sky('#0f3460')
scene.set_ground(length=30, width=14)
ball = scene3d.Shapes.Sphere(diameter=1, segments=16)
ball.set_color('#e94560')
ball.set_position(0, 0.5, 0)
scene.add(ball)
# Static markers for the ball to pass
for x in [-8, -4, 0, 4, 8]:
b = scene3d.Shapes.Box(width=0.8, height=0.8, depth=0.8)
b.set_color('#4488ff')
b.set_position(x, 0.4, 3)
scene.add(b)
# Camera tracks the ball from behind
scene.camera.follow(ball, distance=10)
t = 0.0
@scene.on_frame
def animate(dt):
global t
t += dt
x = math.sin(t * 0.8) * 10
y = 0.5 + abs(math.sin(t * 3)) * 2
ball.set_position(x, y, 0)
scene.run(){ “question_type”: “multiple_choice”, “question”: “What does scene.camera.follow(None) do?”, “options”: [ { “key”: “a”, “text”: “Pauses the animation” }, { “key”: “b”, “text”: “Makes the camera look at the origin” }, { “key”: “c”, “text”: “Stops the camera from tracking the mesh it was following” }, { “key”: “d”, “text”: “Removes the camera from the scene” } ], “answer”: “c”, “submitted_answer”: “” }
Method Chaining and reset()
Every camera method returns scene.camera, so you can chain calls on one line:
# Three separate calls:
scene.camera.set_position(8, 6, -8)
scene.camera.set_distance(14)
scene.camera.look_at(box)
# Equivalent chain:
scene.camera.set_position(8, 6, -8).set_distance(14).look_at(box)scene.camera.reset() returns the camera to the default start position and angle — useful when you want a clean slate or need to undo experimental positioning.
The demo below uses a chain to set a dramatic low-angle view of a single object.
import scene3d
scene = scene3d.Scene()
scene.set_sky('#1a1a2e')
scene.set_ground(length=14, width=14)
box = scene3d.Shapes.Box(width=2, height=2, depth=2)
box.set_material(scene3d.Material.Marble.Gray)
box.set_position(0, 1, 0)
scene.add(box)
# Low angle, close in, pointing at the box — all in one chain
scene.camera.set_position(6, 1.5, -6).set_distance(10).look_at(box)
# Uncomment the line below and re-run to jump back to the default view:
# scene.camera.reset(){ “question_type”: “multiple_choice”, “question”: “What does scene.camera.reset() do?”, “options”: [ { “key”: “a”, “text”: “Deletes all camera settings permanently” }, { “key”: “b”, “text”: “Returns the camera to the default start position and angle” }, { “key”: “c”, “text”: “Freezes the camera so the mouse no longer works” }, { “key”: “d”, “text”: “Resets the entire scene, including all shapes” } ], “answer”: “b”, “submitted_answer”: “” }
Try It Yourself
Use the sliders to adjust the camera height and distance, and toggle Follow Ball to switch between a fixed viewpoint and a tracking camera. Watch how dramatically the same scene feels different from different angles.
import scene3d
import math
CAMERA_HEIGHT = 8 #@param {type:"slider", min:2, max:20, step:1}
CAMERA_DISTANCE = 14 #@param {type:"slider", min:5, max:30, step:1}
FOLLOW_BALL = True #@param {type:"boolean"}
scene = scene3d.Scene()
scene.set_sky('#0f3460')
scene.set_ground(length=30, width=14)
ball = scene3d.Shapes.Sphere(diameter=1, segments=16)
ball.set_color('#e94560')
ball.set_position(0, 0.5, 0)
scene.add(ball)
for x, color in [(-8, '#44cc88'), (-4, '#f5a623'), (4, '#f5a623'), (8, '#44cc88')]:
b = scene3d.Shapes.Box(width=1, height=1, depth=1)
b.set_color(color)
b.set_position(x, 0.5, 3)
scene.add(b)
if FOLLOW_BALL:
scene.camera.follow(ball, distance=CAMERA_DISTANCE)
else:
scene.camera.set_position(0, CAMERA_HEIGHT, -CAMERA_DISTANCE).look_at(0, 0, 0)
t = 0.0
@scene.on_frame
def animate(dt):
global t
t += dt
x = math.sin(t * 0.8) * 10
y = 0.5 + abs(math.sin(t * 3)) * 2
ball.set_position(x, y, 0)
scene.run()Think about a 3D scene or game you’d like to build — a race, a platformer, a tour of a building.
How would the camera position change the feel of the experience? Would a fixed overhead view, a close follow-cam, or a wide establishing shot work best? Describe how you’d use set_position, look_at, and follow to create that effect.