Přejít k navigační liště

Zdroják » JavaScript » Elm, WebGL a elm kompilátor

Elm, WebGL a elm kompilátor

Články JavaScript

V minulém díle jsme si ukázali základní použití WebGL v jazyce Elm a porovnali ho s tím, jak se používá WebGL API v JavaScriptu (bez použití knihoven). Nyní vyjdeme z druhého dílu seriálu Ondřeje Žáry WebGL: Milostný RGB trojúhelník a popsaný příklad přepíšeme do jazyka Elm. Pak se podíváme na zajimavou schopnost elm kompilátoru.

Nálepky:

Pojďme hned na věc. V Elmu bude vypadat příklad z článku WebGL: Milostný RGB trojúhelník takto:

 

 

module Main exposing (..)

import Math.Vector3 exposing (..)
import WebGL exposing (..)
import Html exposing (Html)
import Html.App as Html
import Html.Attributes exposing (width, height)


{-
   V Javascriptovém WebGL příkladu definuje Ondra dvě pole
   jedno pro souřadnice vrcholů a jedno pro barvy vrcholů.
   A pak je propojí (binduje) s bufferem.

   V Elmu to uděláme maličko jinak.
   Souřadnice a barvu vložíme do jednoho záznamu.
   Obě hodnoty budou uloženy jako trojrozměrný vektor.

   Zde je definován typ pro vrchol.
-}


type alias Vertex =
    { position : Vec3, color : Vec3 }



{-
   V této funkci si vytvoříme data, vrcholy.
   Každý vrchol je záznamem dle výše uvedené definice a obsahuje souřadnice a barvu.
   Z vrcholů vytvoříme trojici a tu vložíme do pole.
   V poli bude jedna taková trojice, neb máme jen jeden trojuhelník.
   Aha, máme trojuhelník. Ondra ve svém článku vykresluje trojuhelníky jako čáry.
   A řeší a vysvětluje problematiku spojenou s tím, že se jednotlivé vrcholy opakují.
   Pevně doufám, že elm-webgl má tuto věc vyřešenou (zdá se, že má).
   Použijeme tedy výčtový typ (union)  Drawable http://package.elm-lang.org/packages/elm-community/elm-webgl/3.0.3/WebGL#Drawable s tagem Triangle.
   Výčtový typ Drawable obsahuje tagy pro vykreslování trojuhelníků, čar a bodů.
-}


mesh : Drawable Vertex
mesh =
    Triangle
        [ ( Vertex (vec3 0 0 0) (vec3 1 0 0)
          , Vertex (vec3 1 1 0) (vec3 0 1 0)
          , Vertex (vec3 1 -1 0) (vec3 0 0 1)
          )
        ]



{-
   Oproti minulému dílu nebudeme ve funkci main rovnou vykreslovat,
   ale použijeme elm architecture http://guide.elm-lang.org/architecture/ pattern.
-}


main : Program Never
main =
    Html.program
        { init = ( 0, Cmd.none )
        , view = view
        , subscriptions =
            (\model -> Sub.none)
        , update = (\elapsed currentTime -> ( elapsed + currentTime, Cmd.none ))
        }



{-
   Grafiku vykreslíme ve funkci view, kterou jsme předali ve funkci main do Html.program.
   Jinak je to téměř stejný kód jako v minulém díle, kdy jsme vykreslovali jeden bod.
   Rozdíl je pouze v tom, že render dostane jiné shadery a jiná data.
-}


view : Float -> Html msg
view t =
    WebGL.toHtml
        [ width 400, height 400 ]
        [ render vertexShader fragmentShader mesh {} ]



-- Shaders
{-
   Vertex shader je vysvětlený a převzatý z příkladu
   WebGL: Milostný RGB trojúhelník https://www.zdrojak.cz/clanky/webgl-milostny-rgb-trojuhelnik/

   Elm dokáže kontrolovat syntaktické chyby v kódu. O tom si popovídáme za chvíli.
   Jen si všimněte, že v anotaci funkce je ve třetím parametru definována hodnota varyingColor.
   Stejně tak tomu bude i ve fragment shaderu, který tuto hodnotu přebírá.
-}


vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader =
    [glsl|



attribute vec3 position;
attribute vec3 color;
varying vec3 varyingColor;
void main(void) {
  gl_Position = vec4(position, 1.0);
  varyingColor = color;
}

|]



{-
   Zde vytváříme fragment shader, glsl kód opět kompletně převzatý z příkladu
   WebGL: Milostný RGB trojúhelník
   a i zde nesmíme zapomenout na parametr varyingColor v posledním parametru anotace funkce.
-}


fragmentShader : Shader {} {} { varyingColor : Vec3 }
fragmentShader =
    [glsl|



precision mediump float;
varying vec3 varyingColor;
void main(void) {
  gl_FragColor = vec4(varyingColor, 1.0);
}
|]

Toť vše, přátelé. Takto se to dělá v Elmu. Elm-webgl je poměrně nízkoúrovňová knihovna, musíme psát i shadery v jazyce glsl, ale pojďme se podívat, jak nám pomáhá elm kompilátor.

Nejprve upravíme kód takto:

-- vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader : Shader Vertex {} {  }

a zkompilujeme. Stačí spustit elm reactor a v prohlížeči otevřít url http://localhost:8000/src/Main.elm. Vyskočí na nás nepříjemná, ale přehledná chybová hláška.

screen-01

Výborně. Elm kompilátor pozná, když shaderu nedodáme potřebný parametr použitý v jazyce glsl. Tak to zase vrátíme zpět a uděláme chybu přímo v glsls kódu.

vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader =
    [glsl|



attribute vec3 position;
attribute vec3 color;
-- varying vec3 varyingColor;
void main(void) {
  gl_Position = vec4(position, 1.0);
  varyingColor = color;
}

|]

Ani toto nám neprojde.

screen-02

Nemám chuť se šťourat v javascriptové verzi, ale předpokládám, že pokud tam glsl kód předávám jako textový řetězec, tak asi žádná validace toho kódu není možná a chyba se objeví později, či to prostě nebude fungovat a budeme pátrat, proč. Elm je šikulka.

Ještě jeden pokus na podobné téma. Zkusme v glsl kódu udělat syntaktickou chybu.

vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader =
    [glsl|



attribute vec3 position;
attribute vec3 color;
varying vec3 varyingColor;
void main(void) {
  gl_Position = vec4(position, 1.0);
  varyingColor = color;
}

|]

Místo klíčového slova varying jsem napsal varyingXX. A co na to Elm?

screen-03

Nelíbí se mu to. Jasně říká, že na řádku 7 ve sloupci 15 je něco špatně. Tak to je od kompilátoru moc pěkné a užitečné.

Tato provázanost jazyka glsl a elm kompilátoru mne příjemně překvapila.

Závěr

V totmo díle jsme implementovali do Elmu příklad z článku WebGL: Milostný RGB trojúhelník. Podobný příklad najdeme na githubu elm-webgl. V něm je navíc implementována i animace, trojuhelník se otáčí. Použil jsem tento kód a animaci vymazal, aby příklad korespondoval s článkem Ondřeje Žáry. To obnášelo smazat několik málo řádků kódu a pár drobných úprav.

Animaci v pure javascriptovém WebGL API vysvětluje Ondřej Žára v dalším díle svého seriálu. Jak dělat pokročilejší věci s WebGL v Elmu je zřejmé z příkladů na githubu elm-webgl, a tak bych tě, milý čtenáři, poslal právě tam a své povídání o WebGL v Elmu tímto článkem ukončil.

Komentáře

Odebírat
Upozornit na
guest
1 Komentář
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře

Stav SIMD v Rustu v roce 2025

Různé
Komentáře: 1
SIMD - neboli Single Instruction, Multiple Data - znamená, že procesor může jednou instrukcí zpracovat více datových prvků najednou. Typicky to znamená, že místo sčítání dvou čísel přičtete dvě sady čísel paralelně. To může přinést výrazné zrychlení například při zpracování obrazu, audia nebo numerických výpočtů. Pokud již SIMD znáte, tato tabulka je vše, co budete potřebovat. A pokud s SIMD teprve začínáte, tabulku pochopíte do konce tohoto článku

GPUI Component: moderní Rust GUI komponenty pro cross-platform desktop aplikace

Různé
Komentáře: 0
GPUI Component je open-source Rust knihovna rozšiřující framework GPUI o více než 60 moderních, nativních a multiplatformních UI komponent. Staví na deklarativním přístupu, stateless renderování a jednoduchém API inspirovaném Reactem či Yew. Díky optimalizovanému výkonu, podpoře témat a flexibilním layoutům umožňuje rychlý vývoj desktopových aplikací, jako je například trading nástroj Longbridge Pro. Knihovna je licencována pod Apache 2.0 a dostupná na GitHubu.