Коротка відповідь
Ваш GPU — графічний процесор — це масово паралельний комп'ютер, до якого браузер має прямий доступ через стандартизований API під назвою WebGL. Симуляції на цьому сайті передають фізичні розрахунки та малювання пікселів на GPU, який у сотні разів швидший за таку роботу, ніж CPU, що виконує ваш JavaScript.
Ви не помічаєте цей перехід. Ви відкриваєте вкладку, симуляція запускається. Але за лаштунками ваш браузер скомпілював невеликі програми, що звуться шейдерами, завантажив тисячі чисел у виділену пам'ять GPU і увійшов у цикл, що спрацьовує 60 разів на секунду.
Без встановлення, без плагінів, без застосунку. WebGL вбудований у кожен основний браузер з 2011 року. Кожна симуляція на цьому сайті працює повністю в браузері, використовуючи апаратне забезпечення, яке вже є на вашому комп'ютері, планшеті чи телефоні.
CPU проти GPU — у чому різниця?
CPU («основний процесор») оптимізований для швидких послідовних завдань — виконання однієї складної інструкції за іншою. Сучасний CPU має 8–24 ядра.
GPU оптимізований для виконання багатьох простих завдань паралельно. Типовий GPU ноутбука має 1 000–4 000 ядер. Кожне ядро повільніше за ядро CPU, але коли треба виконати однакове обчислення для тисяч частинок одночасно — оновити їхні позиції, перевірити зіткнення, обчислити кольори — GPU перемагає з величезним відривом.
| Властивість | CPU | GPU |
|---|---|---|
| Кількість ядер | 8–24 (споживчий) | 1 000–10 000+ |
| Тактова частота | 3–5 ГГц | 1–2 ГГц |
| Найкращий для | Послідовної логіки | Паралельних даних |
| Тип пам'яті | RAM (спільна) | VRAM (виділена) |
| Використання в симуляціях? | Фізична логіка, ШІ | Рендеринг, обчислення |
Конвеєр WebGL
Кожен кадр 3D-симуляції проходить однакову послідовність кроків. Ось що відбувається між моментом, коли «JavaScript оновлює фізику», і моментом, коли «фотони покидають ваш екран»:
-
1
JavaScript завантажує даніПозиції частинок, кольори та розміри пакуються в типізовані масиви (Float32Array) і надсилаються в пам'ять GPU (VRAM) через виклики буферів WebGL.
-
2
Вершинний шейдер виконується — по одному разу на точкуНевелика програма (код GLSL) виконується для кожної частинки одночасно. Вона перетворює 3D-координати світу на 2D-координати екрана за допомогою матричної математики.
-
3
Растеризація — з 3D у пікселіGPU визначає, які пікселі екрана покриває кожен трикутник чи точка. Цей крок повністю автоматичний і відбувається у виділеному апаратному блоці з фіксованою функцією.
-
4
Фрагментний шейдер виконується — по одному разу на піксельІнша програма GLSL визначає кінцевий колір кожного пікселя — освітлення, текстуру, прозорість, ефекти світіння. Усе відбувається одночасно для тисяч пікселів.
-
5
Кадр виводиться на екранГотовий кадр відображається. requestAnimationFrame знову викликає цикл — в ідеалі 60 разів на секунду, синхронізовано з частотою оновлення монітора.
Що таке шейдер?
Шейдер — це невелика програма, написана мовою GLSL (Graphics
Library Shading Language), яка виконується безпосередньо на GPU.
Шейдери не мають console.log, не мають циклів по
масивах і не мають способу спілкуватися між паралельними
екземплярами — кожен з них обробляє свою власну точку даних у
повній ізоляції.
Саме це обмеження робить їх швидкими. GPU може одночасно виконувати 4 000 екземплярів фрагментного шейдера, тому що вони не мають спільного стану між собою.
Three.js — WebGL без складнощів
Чистий WebGL вимагає написання всього конвеєра вручну. Більшість симуляцій на цьому сайті використовують Three.js — бібліотеку JavaScript, яка бере на себе шаблонний код — камеру, граф сцени, допоміжні засоби геометрії, вбудовані матеріали — при цьому дозволяючи писати власні шейдери, коли це потрібно.
Простіші 2D-симуляції (клітинні автомати, дифузія, деякі хвильові симуляції) натомість використовують Canvas 2D API — повільніший, але простіший API для малювання для випадків, які не потребують повного конвеєра GPU.
Спробуйте: симуляції, що демонструють роботу GPU
- Галактика — 80 000 зірок, відрендерених за допомогою InstancedMesh: один виклик малювання
- Реакція-дифузія — пінг-понг фреймбуферів; GPU обчислює наступний стан сітки з мільйона пікселів
- Трасування променів (Ray Marching) — кожен піксель обчислюється повністю у фрагментному шейдері, жодної геометрії
- Boids (зграї птахів) — 5 000 агентів-птахів, просторове хешування на CPU, інстансований рендеринг на GPU