Що таке WebGL? Як 3D-симуляції працюють у вашому браузері

Як вебсторінка малює 80 000 зірок, що обертаються, з частотою 60 кадрів за секунду — або симулює рідину з 10 000 частинок, що взаємодіють між собою, — без встановлення чого-небудь? Просте пояснення для допитливих учнів і вчителів.

Коротка відповідь

Ваш 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. 1
    JavaScript завантажує дані
    Позиції частинок, кольори та розміри пакуються в типізовані масиви (Float32Array) і надсилаються в пам'ять GPU (VRAM) через виклики буферів WebGL.
  2. 2
    Вершинний шейдер виконується — по одному разу на точку
    Невелика програма (код GLSL) виконується для кожної частинки одночасно. Вона перетворює 3D-координати світу на 2D-координати екрана за допомогою матричної математики.
  3. 3
    Растеризація — з 3D у пікселі
    GPU визначає, які пікселі екрана покриває кожен трикутник чи точка. Цей крок повністю автоматичний і відбувається у виділеному апаратному блоці з фіксованою функцією.
  4. 4
    Фрагментний шейдер виконується — по одному разу на піксель
    Інша програма GLSL визначає кінцевий колір кожного пікселя — освітлення, текстуру, прозорість, ефекти світіння. Усе відбувається одночасно для тисяч пікселів.
  5. 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