Frontender Úvod do WebGL:Proč WebGL?

S mým designérským kolegou jsme měli za úkol vyvinout novou verzi firemního vizitkového webu. Kolega se půl roku učil pracovat s 3D editory (po hodinách na Maxon Cinema 4D), a tak chtěl své nové dovednosti využít při tvorbě nové verze webu. Jeho představa byla, že na každé stránce na první obrazovce se bude točit nějaká nesrozumitelná postava s nějakým krásným textem. Mělo to vypadat nějak takto:

Ještě nebyly žádné skutečné modely, takže jsem poprvé dostal model jablka.

Hlavním problémem bylo, že jsem neměl žádné zkušenosti s 3D, mé znalosti matematiky a geometrie byly velmi špatné a nikdy jsem neměl žádné zkušenosti s WebGL. Obecně jsem málo věřil ve vlastní sílu. V důsledku toho jsem se s úkolem vyrovnal a chci o této zkušenosti mluvit v malé sérii článků.

Proč WebGL vůbec?

Slovo WebGL je spojeno s 3D. Myslím, že už neexistují žádné normální způsoby, jak něco vykreslit ve 3D bez WebGL. Kromě toho, že slovo WebGL samo o sobě zní velmi cool, existovaly i další důvody, proč zvolit tuto technologii:

  • Chtěli jsme interaktivitu. Například proto, aby model reagoval na pohyb kurzoru myši po dvou osách. S videem to nemůžete udělat.
  • Responzivita. Mohli jsme nakreslit jeden model pro jakékoli obrazovky a zařízení (podpora WebGL byla ohromující). Nemusíme předem vykreslovat hromadu videí pro různé obrazovky a obávat se, že se na některé obrazovce objeví pixelace.
  • Problémy se systémem iOS. Každá verze měla své vlastní vtipy s videi na pozadí v telefonu. Na jedné z verzí se video kvůli zásadám Applu nemuselo vůbec spustit a někdy bylo nutné provést speciální ceremonii, aby video na pozadí fungovalo. S WebGL zatím žádné takové problémy nejsou a doufám, že ani nebudou.
  • IE11 také podporuje WebGL. Ano, existuje nuance, ale nestojí ani za pozornost.
  • V SVG není možné vytvořit plné 3D, pouze pseudo. Prohlížeče se také cítí špatně, když je prvků SVG v DOM více než 10 000. To ukázaly mé pokusy vykreslit model ve formátu SVG.

Myslím, že první bod stačí k rozhodnutí ve prospěch webGL.

Kde jste začali?

Model jablka byl ve formátu OBJ, rozhodl jsem se neuvažovat o jiných formátech. Toto je textový formát a to mi dodalo jistoty, že by pro něj mělo být na internetu mnoho řešení.

Věděl jsem o existenci knihoven three.js , Babylon.js a PixiJS (obecně se jedná o 2D render). Hmotnost 3D knihoven je obrovská, bez ohledu na to, jak jsou komprimované. Taková monstra jsem na svůj web pouštět nechtěl, už jsem měl 100kb reag-dom, kde ještě víc? A abyste porozuměli 3D knihovnám, museli jste ještě trochu rozumět 3D grafice.
Vygooglil jsem "webgl obj model render" a našel jsem pouze online prohlížeče nebo některá vysoce specifická řešení, která jsem nemohl spustit.
Hledal jsem i dema na CodePen, ale nic vhodného jsem nenašel. A pokud jsem něco našel, nemohl jsem vůbec pochopit, co se děje a co mám dělat.
Uvědomil jsem si, že musím začít se základy, bez základních znalostí webGL nelze úkol dokončit.

Ponořte se do WebGL

Nevím, jak se to stalo, ale na internetu jsem neviděl zdroje WebGL, tak jsem šel na chat @webgl_ru Telegram (bylo snadné ho najít) a zeptal jsem se:
— jak začít s WebGL?

Zdá se, že kluci jako já neustále chodili do chatu s podobnými otázkami, takže kluci z chatu už měli připravený seznam zdrojů, který mi vyhodili. Následně mi účastníci tohoto chatu nejednou pomohli, za což jim patří velký dík.

Ze seznamu, který mi byl zaslán, jsem vybral zdroj WebGL Fundamentals, který měl poměrně výmluvný název, stejně jako překlad do ruštiny. Obvykle v anglické dokumentaci nevidím nic hrozného, ​​ale WebGL mi připadalo něco cizího a děsivého a navíc sestávajícího z přístupů, které jsem předtím neznal. Skutečnost, že WebGL vše vykresluje prostřednictvím Canvas, byla jediná věc, kterou jsem o této technologii věděl.

Co je to vlastně WebGL

První věc, která vás upoutá, je neobvyklé API. Rozhraní API prohlížeče, na které jsme zvyklí, pouze volá metody na některých vestavěných objektech/třídách, zatímco rozhraní API WebGL je jako když programově nakonfigurujete repl node.js a pak do tohoto repl předáte řádky kódu javascript a získáte z toho nějaký výsledek. .
V případě webgl nastavíte v prohlížeči oříznutou verzi OpenGL (knihovna, díky které naše grafické karty něco vykreslují) a předáte do ní kód GLSL. GLSL je okleštěný jazyk podobný C, snadno se do něj ponoříte. Je to jako psát es3 javascript.

Abych to shrnul, práce na webgl vypadá takto:

  • Získáte přístup k webgl (v podstatě openGL, ale verze je zkrácená, a proto se nazývá webgl).
  • Nastavíte některé speciální příznaky, které mohou změnit způsob vykreslování.
  • Napište program v GLSL. Samotný program je jen funkce, která bere data a chrlí nějaký výsledek. Data jsou body v souřadnicovém systému a barva tohoto bodu. Zadejte, jak určit polohu prvku div 1x1 pomocí absolutního a vycentrujte jej ve výšce 300 pixelů tak, že jej vybarvíte červeně.
  • V případě 3D je také potřeba určit hloubku bodu, to zatím není důležité.
  • Prostor ve webgl má souřadnice od -1 do 1, takže potřebujeme převést souřadnice různých tvarů na souřadnice od -1 do 1, pokud jsou mimo. TOTO JE MATEMATIKA.
  • Předávejte souřadnice, barvy a další parametry prostřednictvím rozhraní API.
  • ZISK! Získáme 2D/3D obraz.

Shaders

Výše jsem mluvil o programech GLSL, program se vždy skládá ze 2 shaderů. Shader je funkce.
Každý program se skládá z Vertex Shader a Fragment Shader.

Vrcholový shader – umožňuje označit prostor a fragmentový shader – tento prostor vybarvuje. Tak fungují grafické karty.
Nejprve potřebují nastavit body v prostoru, pak tyto body spojit neviditelnými čarami a pak překreslit každý pixel uvnitř výsledného tvaru.
Abych uvedl skutečný příklad, máte zeď 1 m x 1 m a máte umělce jménem Videocard. Takže mu řeknete:

Samotné shadery vypadají takto:

Vertex Shader

// атрибут, который будет получать данные которые мы передали. атрибут === переменная/пропс
attribute vec4 a_position;

// все шейдеры имеют функцию main
// стандартная тема для компилируемых языков
void main() {

  // gl_Position - специальная переменная вершинного шейдера,
  // которая отвечает за установку положения
  gl_Position = a_position;
}

Fragment Shader

// фрагментные шейдеры не имеют точности по умолчанию, поэтому нам необходимо её
// указать. mediump подойдет для большинства случаев. Он означает "средняя точность"
precision mediump float;

void main() {
  // gl_FragColor - специальная переменная фрагментного шейдера.
  // Она отвечает за установку цвета.
  gl_FragColor = vec4(1, 0, 0, 1); // вернёт красный
}

Ve vertex shaderu jste viděli attribute . Shader má několik typů proměnných (další copy-paste z webglfundamentals.org):

Vrcholový shader se provádí pro každou část souřadnic x,y,z (z nemusí být specifikováno při kreslení ve 2D). Každá taková souřadnice vytváří vrchol. A pak jsou tyto vrcholy již spojeny do trojúhelníků (polygonů) a tyto trojúhelníky jsou pak přemalovány stínovačem fragmentů.

Ptáte se, proč trojúhelníky?

V procesu učení jsem tomu nevěnoval pozornost, ale když jsem se začal pokoušet nakreslit model, byl jsem také překvapen, ale ukázalo se, že pomocí TROJÚHELNÍKŮ (MNOHOÚHELŮ) lze nakreslit jakoukoli postavu, a proto nemá smysl přidávat další čísla.

Trojúhelník je absolutní .

Ve webgl můžete kreslit pouze pomocí trojúhelníků, čar a teček.

  • Pokud kreslíte přes čáry, vykreslí se pouze okraje mezi vrcholy, ale vše uvnitř tvaru nebude překresleno.
  • Pokud budete kreslit body, budou se kreslit pouze body! Úžasné!

Matice

Dozvěděl jsem se i o matrice. Pochází z matematiky a pro vývojáře js to vypadá jako pole 9 nebo 12 čísel (12 pro 3D).
Matice řeší otázky, jak transformovat model (nebo spíše vrcholy), aby se model umístil na správné místo v prostoru, zvětšil se nebo zkroutil.
Matrice také umožňují vytvářet kamery, tedy měnit pohled a další. Mohli byste se s nimi setkat, pokud byste pracovali transform: matrix(...n) v css.

Matice jsou jedním ze základů 2D/3D grafiky . Pravděpodobně jedna z mála věcí, které můžete použít, aniž byste pochopili, jak to funguje.

Stačí si pamatovat, že pro aplikaci několika transformací stačí matice vynásobit mezi sebou a výsledek přenést do shaderu.
Matice 3x3 pro 2D transformace a 4x4 pro 3D transformace.

Dobří lidé nám již napsali gl-matrix. Musíme volat pouze známé názvy metod a získat požadovaný výsledek.
Více o matricích se můžete dozvědět na webgl fundumentals.

Ahoj světe na webgl

Jak tedy vypadá hello world code na webgl? Co je vůbec potřeba ke spuštění tohoto a nakreslení trojúhelníku?

  • Potřebujeme získat odkaz na prvek canvas.
  • Získejte z ní kontext webgl, tedy něco, co nám umožní komunikovat s webgl a kreslit přes něj.
  • Vytvořte program z vertex shaderu a fragment shaderu.
  • Získejte odkazy na proměnné z shaderů.
  • Přiřaďte data k proměnným.
  • Spusťte funkci drawArrays webgl.
  • Voila, máme náš trojúhelník.

A po tolika kódu (po odkazu) dostaneme trojúhelník.

Abych byl upřímný, toto šílené množství kódu kvůli jednomu trojúhelníku trochu zchladilo touhu, ale autor tutoriálu vysvětlil, že toto vše lze odstranit pomocí pomocníků.
Když se podíváte na tento příklad, můžete pochopit šílené rozměry 3D lib.

Pokračování zde.