Case study · Commissioned student project

How 3D Worlds Work in Games

An interactive textbook for a student’s project defence: seven short lessons on how games store and draw a three-dimensional world. Every lesson has a live 3D scene you can play with, and on the first screen a robot walks wherever you click. The site itself is in Russian.

Type
Commissioned project for a student, defended with the top grade
Date
September 27, 2026, 2 commits
Stack
HTML, CSS, JavaScript and three.js, no bundler · 2,034 lines
Links
live page ↗
code on GitHub ↗

First screen: the robot walks to the clicked point, 1440px wide.

Phone, 393px.

Lesson 1 on a phone.

01

Who it’s for and why

Commissioned by a student who needed a website for a project defence on how three-dimensional space works in games. The topic is abstract — coordinates, matrices, cameras — and easy to lose in words. The goal was to show every idea in a way you can touch: move a slider, turn the camera, click the floor.

So every lesson follows the same pattern: a short plain-language text on the left, a live scene on the right and a panel with numbers that change along with it. The site itself is laid out as a project paper: relevance, goal and tasks at the start, a conclusion and sources at the end, with every task linking to its lesson. The student defended the project with the top grade.

02

What was built

  1. First screena “Project work” label and a robot on a grid with axes: click the floor and it walks there, while a panel shows the coordinates under the cursor
  2. About the projectrelevance, the goal, eight tasks linking to the lessons and a project passport styled as a drawing title block
  3. Coordinatesa crystal on X, Y and Z sliders, dashed projections onto the axes and a table of which axis points up in Unity, Unreal, Godot and Blender
  4. Transforma gizmo like in game engine editors: move, rotate and scale with the W, E and R keys, plus a table of numbers
  5. Mesha sphere, a torus and a rock at six levels of detail: wireframe, vertices, normals and a triangle counter
  6. Hierarchya sun, a planet and a moon: the moon’s local coordinates never change, while its world position draws a loop
  7. Camerathe view frustum from the side and a “player view” window, perspective and orthographic modes, a counter of what gets drawn
  8. Light and materialroughness, metalness, colour, the sun’s position and shadows
  9. Game loopa WASD mini game with crystals, frames per second, deltaTime and slow motion
  10. Conclusion and sourcesthe project’s summary and nine sources: three.js, Unity, Unreal and Godot docs, LearnOpenGL, MDN and Game Programming Patterns
  • Filesindex.html — 369 lines, style.css — 364, ten JS modules — 1,301: a shared scene module and one file per lesson.
  • Librariesthree.js 0.170 via an importmap from jsDelivr, no bundler. The robot is RobotExpressive from the three.js examples, CC0 licence.
  • SpeedA scene is created 400px before it scrolls into view and drawn only while it is visible. Pixel density is capped at 2.
  • ResponsiveOne breakpoint at 900px. On touch screens arrow buttons replace the keyboard hint. With “reduce motion” the decorations stop spinning on their own.

03

Decisions worth a look

  • Clicking the floor is a raycast

    The mouse position is mapped to the −1…1 range, a ray is cast from the camera through that point, and the site finds where it hits the floor. A click is told apart from a camera drag by distance: if the pointer moved more than 6px between press and release, it was a drag and the robot stays put.

  • Colour means axis

    X is red #e5484d, Y green #2f9e57, Z blue #2f6feb — as in every 3D editor. These are the only accent colours on the page: they label the axes in the scenes and colour the sliders, the numbers on the panels and the letters in the lesson text. The colour alone tells you which coordinate is meant.

  • Eight scenes, one loop

    The page has eight 3D views but a single render loop. A scene is created when it is 400px away and drawn only while it is on screen, so the page stays smooth even on a laptop with integrated graphics. Frame time is capped at 0.1 s, so the robot does not “teleport” after you switch tabs.

  • The camera shows itself

    The camera lesson draws two views on one canvas: from the side and through the player’s eyes. The second one is drawn with a scissor exactly under a frame laid out in CSS. Every frame the frustum is rebuilt and each object is tested: whatever falls outside turns grey, and the panel counts how many objects get drawn. The camera body and frustum lines live on a separate layer, so the player never sees them.

  • One robot for every scene

    The model is downloaded once, and each scene gets its own copy with its own skeleton. Height is measured on the rigid body parts only: the hands’ raw sizes are in “skeleton units”, a hundred times larger, and with them the robot shrank to a dot. If the first model address fails, the second is used, and without a network a block figure takes the robot’s place.

What’s worth improving

  • three.js and the robot model load from third-party servers, jsDelivr and threejs.org. Without internet the 3D does not start at all.
  • On a phone, touching a 3D view turns the camera instead of scrolling the page, so you scroll by the text.
  • You cannot zoom into a scene: the mouse wheel belongs to page scrolling, and pinch zoom is switched off with it.
  • The rock in the mesh lesson shows a bundle of normals at each vertex — one per flat face. The lesson text does not explain why.

04

How to check

  • Click the floor on the first screen — the robot walks to that point first screen ↗
  • Narrow the camera’s field of view and watch objects turn grey camera ↗
  • Collect five crystals with WASD and slow time down with the slider mini game ↗

Get in touch

Got a project?
Drop me a line.