Modul I

Podstawy Three.js

Scena, kamera, renderer — trzy filary, na ktorych stoi cala biblioteka. Bez nich nie ma grafiki 3D w przegladarce.

01

Wprowadzenie do Three.js

Czas: 10 min | Poziom: poczatkujacy

Three.js to biblioteka JavaScript do tworzenia grafiki 3D w przegladarce internetowej. Zostala stworzona przez Ricardo Cabello (mr.doob) w 2010 roku i od tego czasu stalaa sie najpopularniejszym narzedziem do WebGL na swiecie.

Co to jest WebGL?

WebGL to API przegladarkowe umozliwiajace renderowanie grafiki 3D przy uzyciu GPU (karty graficznej) bezposrednio w elemencie <canvas>. Three.js jest nakladka na WebGL — upraszcza tworzenie scen, obiektow, materialow i animacji, ktore w czystym WebGL wymagalby setek linii kodu.

Dlaczego Three.js?

  • Abstrakcja — ukrywa zlozonosc WebGL (shadery, bufory, macierze)
  • Gotowe obiekty — geometrie, materialy, swiatla, kontrolery kamery
  • Spolecznosc — tysiace przykladow, addonow, tutoriali
  • Open-source — darmowa, aktywnie rozwijana na GitHub
  • WebGPU ready — obsluga nowej generacji API graficznego
Three.js WebGL API GPU Canvas Three.js abstrahuje WebGL, ktory komunikuje sie z GPU, ktory renderuje na Canvas
Rys. 1.1 — Architektura Three.js

Pierwsza scena

Kazda aplikacja Three.js sklada sie z trzech fundamentalnych elementow: sceny (kontenera obiektow), kamery (punktu widzenia) i renderera (silnika rysujacego). Bez zadnego z nich nie zobaczysz nic.

JavaScripthello-world.html
// 1. Import Three.js przez import map (nowoczesny sposob)
import * as THREE from 'three';

// 2. Scena — kontener na wszystkie obiekty 3D
const scene = new THREE.Scene();

// 3. Kamera — perspektywa widza
const camera = new THREE.PerspectiveCamera(
  75,                                    // FOV (stopnie)
  window.innerWidth / window.innerHeight,  // aspect ratio
  0.1,                                   // near (bliska plaszczyzna)
  100                                    // far (daleka plaszczyzna)
);
camera.position.set(0, 0, 5);

// 4. Renderer — rysuje scene na canvas
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 5. Renderuj jedna klatke
renderer.render(scene, camera);
⚠ Uwaga — antywzorzec

Nie uzywaj starych CDN script tagow: <script src="three.min.js">. To jest przestarzaly wzorzec z czasow r128. Zawsze uzywaj import maps z ES modules.

Import maps — nowoczesny sposob

Three.js od r150+ wymaga ES modules. Import map to standardowy mechanizm przegladarki umozliwiajacy mapowanie nazw modulow na URL.

HTML
<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.184.0/examples/jsm/"
  }
}
</script>
<script type="module">
  import * as THREE from 'three';
  import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
</script>
ℹ Wersjonowanie

Zawsze przypinaj konkretna wersje Three.js (np. three@0.184.0). Nie uzywaj three@latest — API zmienia sie czesto, a kod moze przestac dzialac.

Podsumowanie rozdzialu

  • Three.js to nakladka na WebGL upraszczajaca grafike 3D
  • Trzy filary: Scene, Camera, Renderer
  • Uzywaj import maps, nie starych CDN script tagow
  • Zawsze przypinaj konkretna wersje biblioteki
02

Scena i Kamera

Czas: 15 min | Poziom: poczatkujacy

Scene — korzen drzewa obiektow

Scene to kontener, do ktorego dodajesz wszystkie obiekty 3D: meshe, swiatla, grupy, pomocniki. Dziala jak drzewo — obiekty moga byc dziecmi innych obiektow, dziedziczac transformacje (pozycje, rotacje, skale) rodzica.

JavaScript
const scene = new THREE.Scene();

// Tlo sceny (kolor)
scene.background = new THREE.Color(0x0a0e14);

Fog — obiekty znikaja w oddali
scene.fog = new THREE.Fog(0x0a0e14, 10, 40);
// 0x0a0e14 = kolor mgly, 10 = blisko, 40 = daleko

// Dodawanie obiektow
scene.add(mesh);
scene.add(light);

PerspectiveCamera — oko widza

PerspectiveCamera imituje ludzkie oko. Obiekty dalej sa mniejsze (perspektywa). Cztery parametry definiuja jej zachowanie:

ParametrOpisTypical
fovField of View (kat widzenia w stopniach)45–75
aspectStosunek szerokosci do wysokosciw/h
nearBliska plaszczyzna obcinania0.1
farDaleka plaszczyzna obcinania100–1000
Kamera near far FOV Obiekty widoczne
Rys. 2.1 — Frustum kamery perspektywicznej. Tylko obiekty miedzy near a far sa renderowane.
⚠ Puapka near/far

Ustawienie near zbyt blisko (np. 0.0001) powoduje z-fighting — migajace, przeswityjace sciany gdy obiekty sa blisko siebie. Ustawienie far zbyt daleko (np. 100000) obniza precyzje bufora glebokosci. Rozsadne wartosci: near: 0.1, far: 100.

OrbitControls — kontrola mysza

Domyslnie kamera jest nieruchoma. OrbitControls (z three/addons/) pozwala obracac kamere mysza, zoomowac kólkiem i przesuwac prawym przyciskiem.

JavaScript
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const controls = new OrbitControls(camera, renderer.domElement);

// Damping — plynnosc ruchu (wymaga controls.update() w petli)
controls.enableDamping = true;
controls.dampingFactor = 0.06;

// Ograniczenia
controls.minDistance = 3;   // najblizej
controls.maxDistance = 25;  // najdalej
controls.maxPolarAngle = Math.PI / 2; // nie schodz pod podloge
⚠ Czesty bld

Gdy wlaczysz enableDamping, MUSISZ wywolywac controls.update() w petli renderowania. Bez tego kamera nie bedzie sie aktualizowac po zwolnieniu myszy.

Cwiczenie 2.1

Stworz scene z niebieskim tlem, kamera perspektywiczna (FOV 45, far 50) i OrbitControls z damping. Dodaj prosty szescian na srodku.

Podsumowanie rozdzialu

  • Scene to kontener-korzen dla wszystkich obiektow
  • PerspectiveCamera: fov, aspect, near, far
  • Unikaj ekstremalnych wartosci near/far (z-fighting, precyzja)
  • OrbitControls wymaga controls.update() przy damping
03

Renderer

Czas: 10 min | Poziom: poczatkujacy

WebGLRenderer to silnik rysujacy scene na elemencie <canvas>. Przetwarza drzewo sceny, swiatla, materialy i shadery, nastepnie wysyla instrukcje do GPU.

Konfiguracja

JavaScript
const renderer = new THREE.WebGLRenderer({
  antialias: true,          // wygładza krawedzie
  alpha: true,               // przezroczyste tlo
  powerPreference: 'high-performance'
});

// Rozmiar canvas = rozmiar okna
renderer.setSize(window.innerWidth, window.innerHeight);

// Pixel ratio — ostrosc na ekranach Retina/HiDPI
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

// Tone mapping — realistyczne kolory
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;

document.body.appendChild(renderer.domElement);
Savjet

setPixelRatio(Math.min(devicePixelRatio, 2)) — ograniczenie do 2 zapobiega spadkom wydajnosci na ekranach 3x/4x Retina, gdzie renderowanie 4x wiecej pikseli nic nie daje wzrokowo.

Petla renderowania

Aby animacja byla plynnna, scene renderuje sie ~60 razy na sekunde. setAnimationLoop to nowoczesny sposob (zastepuje requestAnimationFrame).

JavaScript
const clock = new THREE.Clock();

function animate() {
  const delta = clock.getDelta();     // czas od ostatniej klatki
  const elapsed = clock.getElapsedTime(); // calkowity czas

  controls.update();
  renderer.render(scene, camera);
}

renderer.setAnimationLoop(animate);
⚠ Frame-rate independence

Nigdy nie pisz rotation += 0.01. Na monitorze 144Hz animacja bedzie 2.4x szybsza niz na 60Hz. Zawsze uzywaj: rotation += delta * speed.

Podsumowanie rozdzialu

  • WebGLRenderer rysuje scene na canvas
  • Antialias + ACESFilmic toneMapping = lepsza jakosc
  • setPixelRatio max 2 — wiecej nie ma sensu
  • setAnimationLoop + Clock.getDelta() = stabilna animacja
Modul II

Obiekty 3D

Geometrie, materialy i oswietlenie — elementy z ktorych budujesz wirtualny swiat.

04

Geometrie

Czas: 20 min | Poziom: sredniozaawansowany

Geometria definiuje ksztalt obiektu — zbior wierzcholkow (vertices), krawedzi i scian. Three.js oferuje wiele gotowych geometrii bazujacych na BufferGeometry.

Geometrie podstawowe

KlasaParametryOpis
BoxGeometryw, h, dProstopadloscian
SphereGeometryr, widthSeg, heightSegKula
TorusGeometryr, tube, radialSeg, tubularSegPierscien (donut)
ConeGeometryr, h, radialSegStozek
CylinderGeometryrTop, rBot, h, radialSegWalec
PlaneGeometryw, hPlaszczyzna
IcosahedronGeometryr, detail20-scian (kontrukcyjna)
DodecahedronGeometryr, detail12-scian
TorusKnotGeometryr, tube, tubularSeg, radialSeg, p, qWezel torusowy
JavaScript
// Prostopadloscian 1x1x1
const box = new THREE.BoxGeometry(1, 1, 1);

// Kula — promien 0.7, 32 segmentow w szerokosci i wysokosci
const sphere = new THREE.SphereGeometry(0.7, 32, 32);

// Pierscien — promien 0.5, grubosc 0.2
const torus = new THREE.TorusGeometry(0.5, 0.2, 16, 64);

// Stozek — promien 0.6, wysokosc 1.2, 32 segmenty
const cone = new THREE.ConeGeometry(0.6, 1.2, 32);

Segmenty — kompromis jakosci vs wydajnosc

Kazda geometria parametryczna przyjmuje liczbe segmentow. Wiecej segmentow = gladzsza krzywna, ale wiecej wierzcholkow = wolniejsze renderowanie.

8 segmentow 16 segmentow 64 segmentow 128 segmentow
Rys. 4.1 — Wplyw liczby segmentow na gladkosc kuli
ℹ Regula kciuka

SphereGeometry: (32, 32) wystarczy dla wiekszosci przypadkow. TorusGeometry: (16, 64). Nie uzywaj 128+ segmentow bez wyraznej potrzeby.

BufferGeometry — geometrie niestandardowe

Mozesz tworzyc geometrie z wlasnych danych wierzcholkow:

JavaScript
// Trojkat z 3 wierzcholkow
const vertices = new Float32Array([
  0,  1,  0,   // wierzchotek 1 (gora)
  -1, -1, 0,   // wierzchotek 2 (dol lewo)
  1,  -1, 0    // wierzchotek 3 (dol prawo)
]);

const geom = new THREE.BufferGeometry();
geom.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
⚠ Przestarzale API

THREE.Geometry zostalo usuniete w r125. Nie uzywaj geometry.vertices, geometry.faces. Wszystko jest teraz BufferGeometry z atrybutami (position, normal, uv).

Mesh — geometria + material

Mesh laczy geometrie z materiaem. To obiekt, ktory dodajesz do sceny.

JavaScript
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

Podsumowanie rozdzialu

  • Geometrie definiuja ksztalt (wierzcholki, sciany)
  • Wiecej segmentow = gladziej ale wolniej
  • BufferGeometry dla geometrii niestandardowych
  • THREE.Geometry usuniete w r125 — nie uzywaj
  • Mesh = geometry + material
05

Materialy

Czas: 25 min | Poziom: sredniozaawansowany

Material okresla wyglad powierzchni obiektu: kolor, polysk, chropowatosc, teksture, przezroczystosc. Three.js oferuje kilka materialow o roznym stopniu zlozonosci.

Typy materialow

MaterialOswietlenieZastosowanie
MeshBasicMaterialNieNajprostszy, tylko kolor/tekstura
MeshLambertMaterialTak (diffuse)Matowe powierzchnie, wydajny
MeshPhongMaterialTak (specular)Blyszczace, plastikowe
MeshStandardMaterialTak (PBR)Najpopularniejszy, realistyczny
MeshPhysicalMaterialTak (PBR+)Szklo, clearcoat, transmission
MeshNormalMaterialNieKolory z wektorow normalnych (debug)

MeshStandardMaterial — PBR

PBR (Physically Based Rendering) to model oswietlenia, ktory imituje fizyke swiatla. Dwa kluczowe parametry:

JavaScript
const material = new THREE.MeshStandardMaterial({
  color: 0xa78bfa,       // kolor bazowy
  roughness: 0.3,      // 0 = lustro, 1 = matowy
  metalness: 0.7,      // 0 = dielektryk, 1 = metal
  flatShading: false,  // true = plaszczyznowy shading
  wireframe: false     // true = tryb siatki
});
roughness 0.0 lustro 0.3 0.6 1.0 mat metalness 0.0 drewno 0.5 1.0 metal
Rys. 5.1 — Wplyw roughness i metalness na wyglad materialu
⚠ Najczestszy bld AI

AI czesto generuje rough zamiast roughness, metal zamiast metalness. Three.js cicho ignoruje nieznane wlasciwosci — obiekt wyglada zle, ale nie ma bledu.

MeshPhysicalMaterial — rozszerzenie PBR

JavaScript
const glass = new THREE.MeshPhysicalMaterial({
  color: 0xffffff,
  roughness: 0.1,
  metalness: 0,
  transmission: 0.9,       // przezroczystosc (szklo)
  thickness: 0.5,
  clearcoat: 1,            // polysk lakieru
  clearcoatRoughness: 0.1,
  ior: 1.5                 // wspolczynnik zalamania
});
⚠ Puste ekran

MeshStandardMaterial bez swiatel = czarny ekran. Zawsze dodawaj co najmniej AmbientLight i DirectionalLight przed uzyciem materialow PBR.

Podsumowanie rozdzialu

  • MeshStandardMaterial — domyslny PBR (roughness, metalness)
  • MeshPhysicalMaterial — szklo, clearcoat, transmission
  • roughness: 0=lustro, 1=mat | metalness: 0=dielektryk, 1=metal
  • Nie myl rough/metal z roughness/metalness
  • Materialy PBR wymagaja swiatel
06

Oswietlenie

Czas: 20 min | Poziom: sredniozaawansowany

Bez swiatla materialy PBR sa czarne. Three.js oferuje kilka typow swiatel, ktore mozna laczyc dla osiagniecia realistycznego oswietlenia.

Typy swiatel

SwiatloOpisParametry
AmbientLightRownomierne oswietlenie wszystkich obiektowcolor, intensity
DirectionalLightRownolegle promienie (jak slonce)color, intensity, position
PointLightSwiatlo punktowe we wszystkie stronycolor, intensity, distance, decay
SpotLightStozek swiatla z kierunkiemcolor, intensity, angle, penumbra
HemisphereLightSwiatlo z nieba i z ziemiskyColor, groundColor, intensity
JavaScript
// Ambient — wypelnia cienie
const ambient = new THREE.AmbientLight(0x404040, 0.4);
scene.add(ambient);

// Directional — glowne zrodlo (slonce)
const dir = new THREE.DirectionalLight(0xffffff, 1.5);
dir.position.set(5, 8, 5);
dir.castShadow = true;
scene.add(dir);

// Point — swiatlo punktowe
const point = new THREE.PointLight(0x22d3ee, 2, 10);
point.position.set(-3, 2, 2);
scene.add(point);

// Spot — reflektor
const spot = new THREE.SpotLight(0xa78bfa, 3, 15, Math.PI / 6, 0.3);
spot.position.set(0, 6, 0);
scene.add(spot);
Ambient Directional Point Spot
Rys. 6.1 — Typy swiatel w Three.js
Savjet — Three-point lighting

Klasyczny setup: key light (glowne, 45 stopni z lewej), fill light (slabsze z prawej, wypelnia cienie), rim/back light (z tylu, rozdziela obiekt od tla). Daje profesjonalny wyglad w kilka linii kodu.

Cwiczenie 6.1

Stworz scene z sphere (MeshStandardMaterial) i trzema swiatlami: AmbientLight (intensity 0.3), DirectionalLight (bialy, intensity 1.5, pozycja 5,8,5) i PointLight (cyan, intensity 2, pozycja -3,2,2). Zobacz jak kazde swiatlo wplywa na kule.

Podsumowanie rozdzialu

  • AmbientLight — wypelnia cienie rownomiernie
  • DirectionalLight — glowne zrodlo (slonce)
  • PointLight — punktowe, we wszystkie strony
  • SpotLight — reflektor z katem i penumbra
  • Materialy PBR wymagaja swiatel — bez nich czarny ekran
Modul III

Zaawansowane techniki

Animacja, tekstury, cienie i systemy czastek — narzedza do tworzenia dynamicznych, realistycznych scen.

07

Animacja

Czas: 15 min | Poziom: sredniozaawansowany

Animacja w Three.js to sekwencja klatek renderowanych w petli. Klucz do plynnosci: delta time — animacja niezalezna od FPS.

Clock i delta time

JavaScript
const clock = new THREE.Clock();

function animate() {
  const delta = clock.getDelta();     // sekundy od ostatniej klatki
  const elapsed = clock.getElapsedTime(); // sekundy od startu

  // ZLE — zalezy od FPS
  // mesh.rotation.x += 0.01;

  // DOBRZE — niezalezne od FPS
  mesh.rotation.x += delta * 0.5;
  mesh.rotation.y += delta * 0.8;

  // Funkcje trygonometryczne dla plynnych ruchow
  mesh.position.y = Math.sin(elapsed * 2) * 0.5;

  controls.update();
  renderer.render(scene, camera);
}
renderer.setAnimationLoop(animate);
⚠ Frame rate dependency

rotation += 0.01 na 60FPS = 0.6 rad/s. Na 144FPS = 1.44 rad/s. 2.4x szybciej. Uzywaj zawsze delta * speed.

Typy animacji

  • Transform — position, rotation, scale (najprostsza)
  • Morph targets — przejscia miedzy ksztaltami (twarze, ekspresje)
  • Skeletal — animacja szkieletowa (postacie, rigging)
  • Shader — animacja w shaderze (falowanie, pulsowanie)
  • Mixer — AnimationMixer dla animacji z plikow (GLTF, FBX)

Podsumowanie rozdzialu

  • Zawsze uzywaj Clock.getDelta() dla animacji
  • rotation += delta * speed, nie rotation += 0.01
  • Math.sin/cos dla plynnych ruchow
  • setAnimationLoop — nowoczesna petla renderowania
08

Tekstury

Czas: 25 min | Poziom: sredniozaawansowany

Tekstury dodaja szczegoly powierzchniom bez zwiekszania geometrii. Naklada sie je na materialy poprzez wlasciwosci takie jak map, normalMap, roughnessMap.

Typy map

MapaWlasciwoscOpis
Color mapmapGlowna tekstura koloru
Normal mapnormalMapSymuluje detale powierzchni (wypuklosci)
Roughness maproughnessMapChropowatosc piksel po pikselu
Metalness mapmetalnessMapPolysk metalu piksel po pikselu
Ambient occlusionaoMapCienie w szczelinach
DisplacementdisplacementMapFizycznie przemieszcza wierzcholki
JavaScript
import { TextureLoader } from 'three';

const loader = new TextureLoader();

// Laduj tekstury (async)
const colorMap = loader.load('textures/brick.jpg');
const normalMap = loader.load('textures/brick_normal.jpg');
const roughnessMap = loader.load('textures/brick_rough.jpg');

const material = new THREE.MeshStandardMaterial({
  map: colorMap,
  normalMap: normalMap,
  roughnessMap: roughnessMap,
  roughness: 0.8,
  metalness: 0.1
});

Tekstury proceduralne (Canvas)

Mozesz generowac tekstury dynamicznie za pomoca elementu Canvas:

JavaScript
// Proceduralna tekstura szachownicy
const canvas = document.createElement('canvas');
canvas.width = 256; canvas.height = 256;
const ctx = canvas.getContext('2d');

for (let y = 0; y < 8; y++) {
  for (let x = 0; x < 8; x++) {
    ctx.fillStyle = (x + y) % 2 === 0 ? '#22d3ee' : '#0d1117';
    ctx.fillRect(x * 32, y * 32, 32, 32);
  }
}

const texture = new THREE.CanvasTexture(canvas);

const material = new THREE.MeshStandardMaterial({ map: texture });
⚠ Memory leaks

Zawsze wywolywaj texture.dispose() gdy tekstura nie jest juz potrzebna. Three.js nie garbage-collectuje tekstur automatycznie — zostaja w pamieci GPU.

Podsumowanie rozdzialu

  • map — kolor, normalMap — detale, roughnessMap — chropowatosc
  • TextureLoader — ladowanie z plikow
  • CanvasTexture — tekstury proceduralne
  • Zawsze dispose() nieuzywanych tekstur
09

Cienie

Czas: 20 min | Poziom: sredniozaawansowany

Cienie dodaja glebia i realizm — bez nich obiekty wydaja sie uniesione w powietrzu. Three.js uzywa shadow maps — tekstur glebokosci renderowanych z perspektywy swiatla.

Konfiguracja cieni — 4 kroki

JavaScript
// 1. Wlacz cienie w rendererze
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

// 2. Swiatlo rzuca cienie
const light = new THREE.DirectionalLight(0xffffff, 1.5);
light.castShadow = true;
light.shadow.mapSize.set(2048, 2048);
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 30;
light.shadow.camera.left = -10;
light.shadow.camera.right = 10;
light.shadow.camera.top = 10;
light.shadow.camera.bottom = -10;
light.shadow.bias = -0.0005; // koryguje acne

// 3. Obiekty rzucaja cienie
cube.castShadow = true;

// 4. Obiekty odbieraja cienie
floor.receiveShadow = true;
⚠ Shadow acne

Jesli widzisz paskowane artefakty na cieniach, ustaw light.shadow.bias = -0.0005. Peter panning (cien odlepiony od obiektu) oznacza ze bias jest zbyt duzy — zmniejsz.

Typy cieni

TypJakoscWydajnosc
BasicShadowMapNiska (twarde)Najlepsza
PCFShadowMapSredniaDobra
PCFSoftShadowMapWysoka (miekkie)Srednia
VSMShadowMapBardzo wysokaNajgorsza

Podsumowanie rozdzialu

  • 4 kroki: renderer, light.castShadow, mesh.castShadow, mesh.receiveShadow
  • PCFSoftShadowMap — domyslne nowoczesne miekkie cienie
  • shadow.mapSize 2048 — balans jakosci i wydajnosci
  • shadow.bias koryguje acne
10

Systemy Czastek

Czas: 25 min | Poziom: zaawansowany

Points (czastki) pozwalaja renderowanie tysiecy malych obiektow wydajnie — jedna geometria, jeden draw call. Idealne do deszczu, sniegu, iskier, dymu, galaktyk.

JavaScript
const count = 5000;
const positions = new Float32Array(count * 3);
const colors = new Float32Array(count * 3);

for (let i = 0; i < count; i++) {
  // Pozycja w sferze
  const r = Math.random() * 8;
  const theta = Math.random() * Math.PI * 2;
  const phi = Math.acos(2 * Math.random() - 1);

  positions[i * 3] = r * Math.sin(phi) * Math.cos(theta);
  positions[i * 3 + 1] = r * Math.sin(phi) * Math.sin(theta);
  positions[i * 3 + 2] = r * Math.cos(phi);

  // Kolor per-czastka
  const c = new THREE.Color().setHSL(Math.random(), 0.7, 0.5);
  colors[i * 3] = c.r;
  colors[i * 3 + 1] = c.g;
  colors[i * 3 + 2] = c.b;
}

const geom = new THREE.BufferGeometry();
geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geom.setAttribute('color', new THREE.BufferAttribute(colors, 3));

const material = new THREE.PointsMaterial({
  size: 0.08,
  vertexColors: true,
  transparent: true,
  opacity: 0.8,
  sizeAttenuation: true,  // mniejsze w oddali
  blending: THREE.AdditiveBlending,
  depthWrite: false
});

const particles = new THREE.Points(geom, material);
scene.add(particles);
Savjet — AdditiveBlending

AdditiveBlending + depthWrite: false daje efekt swiecacych czastek (iskry, galaktyka). Kolory sie dodaja, czastki nie zaslonia siebie nawzajem.

Podsumowanie rozdzialu

  • Points — tysiace czastek w jednym draw call
  • BufferGeometry z atrybutami position i color
  • PointsMaterial — size, vertexColors, sizeAttenuation
  • AdditiveBlending dla efektu swiecacego
Modul IV

Przyszlosc

TSL, WebGPU i najlepsze praktyki — ku nowej generacji grafiki w przegladarce.

11

TSL i WebGPU

Czas: 30 min | Poziom: zaawansowany

TSL (Three.js Shading Language) to rewolucja w tworzeniu shaderow. Zamiast pisac GLSL jako stringi (z onBeforeCompile hacks), piszesz shadery w JavaScript z typowaniem, kompozycja i tree-shaking.

Dlaczego TSL?

  • JS/TS zamiast stringow — shadery jako kod, nie jako tekst
  • Tree-shaking — tylko uzyteczne wezly trafie do shadera
  • Agnostyczny backend — dziala z WebGL i WebGPU
  • Automatyczna optymalizacja — shader graph optymalizowany przez Three.js
  • Modulowosc — funkcje i uniformy dzielone miedzy materialami

WebGPURenderer

JavaScript
import * as THREE from 'three/webgpu';
import { color, sin, time, positionLocal } from 'three/tsl';

const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init(); // asynchroniczna inicjalizacja!

// TSL material
const material = new THREE.MeshStandardNodeMaterial();

// Pulsujacy kolor
material.colorNode = color(0x22d3ee).mul(
  sin(time).mul(0.5).add(0.5)
);

// Falujaca geometria
material.positionNode = positionLocal.add(
  sin(time.add(positionLocal.y)).mul(0.1)
);

Porownanie: GLSL vs TSL

CechaGLSL (onBeforeCompile)TSL
JezykString manipulationJavaScript/TypeScript
TypowanieBrakTak (z TS)
KompozycjaManualnaAutomatyczna (nodes)
Tree-shakingNieTak
BackendWebGL onlyWebGL + WebGPU
ModulowoscTrudnaimport/export
ℹ Kompatybilnosc

WebGPU nie jest jeszcze obslugiwane we wszystkich przegladarkach. Three.js automatycznie fallbackuje do WebGL jesli WebGPU nie jest dostepne.

Podsumowanie rozdzialu

  • TSL zastepuje GLSL string manipulation JS/TS kodem
  • MeshStandardNodeMaterial — TSL wersja standard material
  • WebGPURenderer wymaga await renderer.init()
  • TSL dziala na obu backendach (WebGL fallback)
12

Najlepsze praktyki

Czas: 15 min | Poziom: wszystkie

Checklista pre-commit

  • Import maps, nie CDN <script> tagi
  • Przypiet wersja three.js (np. three@0.184.0)
  • Brak przestarzalych API (sprawdz Migration Guide)
  • dispose() na geometriach, materialach, teksturach
  • Delta time w petli animacji (nie stale przyrosty)
  • OrbitControls z three/addons/, nie three/examples/jsm/
  • ColorManagement.enabled = true (domyslne od r152+)
  • Brak THREE.Geometry, geometry.vertices, faceVertexUvs
  • Jesli WebGPU: await renderer.init() przed renderowaniem

Czeste przestarzale API

AI generujePoprawne (r184+)Usuniete w
THREE.GeometryBufferGeometryr125
geometry.verticesgeometry.attributes.positionr125
ClockTimerr183 (deprecation)
renderer.renderAsync()renderer.render() po await renderer.init()r181
substr()slice()r184

Wydajnosc

  • InstancedMesh dla >100 podobnych obiektow
  • setPixelRatio(min(dpr, 2)) — nie renderuj 4x na Retina 3x
  • Frustum culling — domyslnie wlaczone, nie wylaczaj
  • dispose() wszystkiego — zapobiega memory leakom
  • Mniejsza ilosc segmentow — 32 zamiast 128 gdy wystarczy
ℹ Migration Guide

Oficjalny przewodnik migracji: https://github.com/mrdoob/three.js/wiki/Migration-Guide. Sprawdzaj przed uzyciem jakiegokolwiek API z tutoriali starszych niz rok.

Podsumowanie kursu

  • Trzy filary: Scene, Camera, Renderer
  • Geometrie + Materialy = Mesh
  • Oswietlenie wymagane dla materialow PBR
  • Animacja z delta time — nie stalymi przyrostami
  • TSL i WebGPU — przyszlosc shadingu
  • dispose() wszystko — zapobiegaj leakom
  • Sprawdzaj Migration Guide przed uzywaniem API