Datamaskingrafikk og WebGL

Introduksjon

Denne bloggen benyttes som støtte i faget "Datamaskingrafikk" ved Uit, IVT campus Narvik. Bloggen omhandler grunnleggende OpenGL ES og WebGL. All eksempelkode er derfor basert på Javascript. 

Bloggen består av følgende moduler:

Modul 1:
Modul 2:
Modul 3:
Modul 4:
Modul 5:
Modul 6:
  • Introduksjon til three.js 
Modul 7:
  • Introduksjon til ammo.js
Modul 8:
  • ShaderMaterial, effekter m.m.
Modul 9:
  • 3D-modeller
Kan du Javascript?

Siden alle eksempler og gjennomganger er basert på Javascript kan det være greit å gjennomgå følgende før du går i gang:

Modul 1.1: Innledning til datamaskingrafikk

Fagområdet omfatter både to- og tredimensjonal grafikk i form av bilder og animasjoner. I vår sammenheng er vi interessert i den tekniske prosessen. Det vil si, hvordan fremstiller man 3D grafikk vha. datamaskinen og tilhørende programvare?

Fagområdet kan deles inn flere underemner som f.eks. Geometri (hvordan representere 3D modeller), animasjon (bevegelse over tid) og rendring (2D fremvisning/gjengivelse av 3D modeller). Også bildebehandling kan ses på som et underemne av fagområdet (New World Encyclopedia, ComputerGraphics).

I denne sammenheng er det geometri, animasjon og rendring som står i fokus. Bildebehandling er ikke tema i disse notatene.

Anvendelser

Det finnes mange og varierte anvendelser av datamaskingrafikk og man kan stort sett plassere disse i en av følgende fire hovedkategorier (Angel et al, 2015):
  • Visning av informasjon - visualisering
    • Kart og Geografiske Informasjonssystemer (GIS), statistikk
    • Medisin: CT (Computed Tomography), MRI (Magnetic Resonance Imaging), ultralyd m.m.
    • Visualisering av matematiske modeller
  • Design
    • CAD (Computer Aided Design) for arkitekter og ingeniører
    • Verktøy for å utvikle integrerte kretser
  • Simuleringer og animasjoner
    • Simuleringer: Sanntidsfremstilling. Eks. Fly- og bilsimulatorer
    • Datamaskinspill
    • Opplæringsprogramvare 
    • Animasjoner
    • Film og TV-industrien
    • Reklame
    • Fotorealistiske bilder, med lys- og skyggelegging 
    • VR – Virtual Reality, og AR - Augmented Reality
  • Brukergrensesnitt
    • Windows, Linux, Mac osv. Alle er basert på samme prinsipp – vinduer, menyer, ikoner m.m. dvs. grafiske elementer på skjermen.
3D datamaskingrafikk bruker geometriske data til å rendre (fremstille) 2D bilder. Spørsmålet er dermed: Hvordan fremstiller man 3D modeller/objekter[1] på en 2D flate (skjermen)?

Før vi går videre med dette er det en del andre begreper og bakgrunnsteori som må på plass. Vi starter med å se på hva et ”grafikksystem” er, litt om grafikkortet og Graphics Processing Unit (GPU) samt en introduksjon til begrepene scene, virtuelt kamera, shadere, graphics pipeline og litt om ulike 3D APIer.

[1] Her brukes begrepet objekt og modell om hverandre men i samme betydning – en 3D modell beskrevet av et sett 3D punkter/koordinater.

Grafikksystem

Et grunnleggende datamaskingrafikksystem består i prinsippet av følgende deler (Angel et al, 2015):
  1. Inn-enheter (mus, tastatur, skjerm, joystick/controller m.m.)
  2. Central Processing Unit (CPU)
  3. Graphics Processing Unit (GPU)
  4. Minne/RAM
  5. Et skjermbuffer (framebuffer
  6. Ut-enhet (skjerm)
Figuren under viser et slikt system

Grafikksystem (Angel et al, 2015)

Grafikksystemet i dagens datamaskiner er stort sett rasterbasert. Rastergrafikk innebærer at bildet er sammensatt av bildepunkter ordnet i rader og kolonner. Et bildepunkt eller picture element kalles piksel (pixel). 

Skjermbufret (framebuffer) er et minneområde som inneholder pikseldata tilsvarende et komplett bilde (en frame) klar til visning på skjermen.

Skjermbufret er essensielt og presisjonen avgjør detaljgraden i bildene som fremvises. Presisjonen er definert av antall bits per piksel. En bit per piksel gir tilgang på to farger, 8 bits gir 256 farger. 24 bits dybde er i dag vanlig og kalles gjerne true color eller RGB systemer.

Såkalte HDR (High Dynamic Range) systemer bruker 12 (eller flere) bits per fargekomponent. Tidligere ble fargekomponentene lagret som heltall (integer) men i det siste lagres disse som flyttall (float) i frame bufret slik at også HDR støttes.

Framebufret inneholder mer informasjon enn bare fargen til hver piksel. Her ligger også informasjon om dybde m.m. Oppgaven til grafikksystemet er i prinsippet å omgjøre grafiske primitiver (gitt fra et program) til piksler i skjermbufret. Denne prosessen kalles rasterisering eller scan conversion. Et grafisk primitiv kan være en linje, et polygon (mangekant) eller lignende. Et polygon er en flate beskrevet av et sett rette linjer – en trekant er dermed en type polygon.

Noen polygoner og tilhørende vertekser

Rasterisering gjør at vi kan gå fra linjer og trådmodeller (wireframes) til fylte polygoner. Primitiver er definert av et sett vertekser. En verteks (vertex) er i prinsippet et punkt i det tredimensjonale rom. Figuren under viser en kule oppbygd av polygoner (trekanter).
En kule oppbygd av trekanter

Fra et program kan man for eksempel angi tre punkter i rommet for å tegne en trekant. I tillegg angis for eksempel farge og/eller en teksturkoordinat for hver verteks. Vha. rasterisering vil nødvendige piksler genereres, med korrekt farge, slik at trekanten kan vises på skjermen.

Mer om skjermbufret

Skjermbufret består normalt av minst tre «delbuffer»:
  • Fargebuffer
  • Z-buffer (dybde
  • Stensilbuffer
Fargebufret inneholder fargeverdiene, typisk RGB (evt. RGBA), til alle pikslene. Z-bufret eller dybdebufret inneholder, for hver piksel, en dybdeverdi. Denne brukes for å avgjøre om en piksel ligger foran eller bak andre piksler. Stensilbufret er ikke så aktuelt som farge- og z-bufret men det kan f.eks. brukes til å lage skygger.

Grafikkortet og grafikkprosessoren 

I eldre datamaskiner ble gjerne grafikkprosesseringa utført av CPUen samtidig som skjermbufret var en del av standard minne.
Ingen spesiell støtte for grafikk

Dagens datamaskiner har typisk hovedkort med integrert grafikkprosessor – en Graphics Processing Unit (GPU). Denne kan f.eks. ha en dedikert del av standard minne som den jobber mot (med assosiert skjermbuffer). Poenget med grafikkprosessoren er å avlaste CPUen ved at den tar seg av beregningskrevende grafikkoperasjoner.
Integrert løsning, GPU på hovedkortet.

En GPU er, som en CPU, en mikroprosessor som er spesielt god til å utføre nødvendige matematiske og geometriske beregninger som er nødvendig for å fremstille 3D grafikk på en 2D skjerm.

Alternativt kan man legge til ekstern maskinvare i form av dedikerte grafikkort (/skjermkort) med integrert grafikkprosessor. Slike kort koples direkte til maskinens hovedkort. Skjermbufret er i så fall et minneområde assosiert med grafikkortet og vil typisk inneholde piksler tilsvarende et komplett bilde (en frame) for visning på skjermen.
Ektsternt grafikkort

Mer om grafikkortet

Dagens grafikkort (kalles også grafikkakselerator) har gjerne direkte støtte for 3D API som OpenGL og Direct3D. 3D grafikk fremstilles programmatisk vha. disse APIene. Via Direct3D eller OpenGL / ES APIene sendes kommandoer direkte til kortets driver som igjen sørger for at kommandoene utføres.

Grafikkprosessoren utfører kommandoene og genererer rastergrafikk som legges i skjermbufret. Skjermbufret oppdateres dermed via GPUen. Denne arkitekturen avlaster CPUen betraktelig. Nvidia og ATI/AMD er eksempler på produsenter av grafikkort.
Eksempel på et grafikkort (Tyson J., Wilson Tracy V., 2001)

Forestill deg en bedrift med en ingeniøravdeling og en designavdeling. Dersom ingeniørene konstruerer en bru, dvs. gjør nødvendige beregninger, finner nødvendige materialer og lager en skisse vil industridesignerne (satt litt på spissen) sørge for at brua ser bra ut innafor ingeniørenes rammer. Forenklet oppsummert: Beskrivelsen av brua sendes til designerne som så bestemmer hvordan brua skal se ut. Merk! dette er antakelig en grov forenkling som mange designere vil protestere mot.

Fra vertekser til piksler

Resultatet er at beskrivelsen av brua ender opp som en pen bru.

Dette kan sammenliknes med virkemåten til et grafikkort. Brukerapplikasjoner, som for eksempel et 3D tegneverktøy, en WebGL applikasjon e.l. sender informasjon om bildet til grafikkortet. Grafikkortet bestemmer så hvordan skjermpikslene skal fylles for å skape ønsket bilde. Denne informasjonen sendes så videre til skjermen.

Det er krevende å fremstille et 3D bilde/modell ut fra en geometrisk beskrivelse. Første steg består i å opprette en trådmodell (wireframe) bestående av for eksempel mange trekanter. Deretter utføres rasterisering som innebærer å beregne hvilke piksler som trengs for å fylle trekantene. Deretter får hver piksel en farge. Fargen kan også, eller i tillegg, bestemmes av teksturer og lys/skygge-data. I forbindelse med spill skjer denne prosessen typisk 60 ganger per sekund. Dersom CPUen skulle utført alle disse beregningene ville den fort bli overbelastet.

Grafikkortet består av fire hovedkomponenter:
  • En kontakt for tilknytning til hovedkortet, typisk en av følgende:
    • Peripheral component interconnect (PCI) 
    • Advanced graphics port (AGP) 
    • PCI Express (PCIe)
  • En egen prosessor – GPU – som bestemmer hvordan hver piksel skal se ut
  • Minne som holder på alle pikslene som skal fremvises
    • Inkludert skjermbufret
  • En (eller flere) skjermkontakt(er) DVI, VGA

Hva beskriver et godt skjermkort

Ytelsen til et grafikkort måles gjerne i form av antall komplette bilder per sekund det klarer å generere. På engelsk betegnes dette som frame rate og måles i fps frames per second. Det er imidlertid flere faktorer som innvirker på fps:
  • Hvor raskt det kan bygge opp en trådemodell – måles i antall trekanter eller vertekser per sekund
  • Hvor raskt fylles trådmodeller med piksler – måles i antall piksler GPUen kan prosessere per sekund

3D illusjonen

Teknikker for å vise 3D grafikk med dybde på en 2D flate, for eksempel et papirark, har blitt grundig studert og utviklet av kunstnere i løpet av de siste århundrene. Teknikkene er basert på fenomener som vi observerer i vår fysiske verden. Ser man langs en rett jernbanelinje vil kantene på linja se ut til å møtes i et ”nullpunkt” (vanishing point) langt der fremme. Objekter vil oppfattes som mindre jo lengre unna de er. Et hus som står veldig langt unna betrakteren vil virke lite mens et tre som står nært vil oppfattes som stort.
"Vanishing point" og dybde

Objekter dekker til hverandre enten helt eller delvis avhengig av gjennomsiktighet, plassering og dybdeplassering.
Ugjennomsiktige objekter

Poenget er at dybdeinformasjon er viktig når grafikksystemet gjør om 3D objekter til 2D skjermgrafikk. Bruk av lys, skyggelegging og materialer kan være med på å fremheve 3D illusjonen.

Modellrepresentasjon

Modeller kan for eksempel utformes vha. geometrisk modellering – dvs. ved å angi punkter og grafiske primitiver i en virtuell 3D verden. Et primitiv er i denne sammenheng en enkel «figur» som en linje, en trekant eller andre typer polygoner.

En modell er igjen oppbygd av et sett med primitiver. Det viser seg at en effektiv måte å bygge opp 3D modeller på er vha. et sett trekanter. Kuler kan eksempelvis genereres vha. bare trekanter. Jo mindre trekantene er jo glattere vil kuleflata fremstå. Kombineres dette med lyssetting og tekstur er det mulig å oppnå fotorealistiske kuler med gjenskinn og skyggeeffekter. En tekstur er kort fortalt 2D bilder som knyttes til/legges på primitiver.

Et mesh er en samling med polygoner som til sammen utgjør en 3D modell. Jo flere polygoner (trekanter) jo mer realistisk modell. Dette betyr også høyere prosesseringskrav. Videre er det ønskelig å kunne manipulere dvs. rotere, flytte eller skalere modellene. En annen viktig del av 3D grafikken er å kunne bestemme synsvinkel – dvs. fra hvilken kant skal modellen betraktes - og hvordan modellen skal projiseres på skjermen (perspektiv eller ortografisk projeksjon – mer om dette senere).

Scene

Når man tar bilder i den virkelige verden stilles gjerne modellene og objektene opp i en scene før vi ”knipser” bildet med fotoapparatet. Vi bruker kameraet til å fange opp og generere 2D bilder av vår fysiske 3D verden. Tilsvarende skjer når man programmerer 3D scener vha. for eksempel WebGL. Etter at modellene er laget posisjonerer man disse i en tenkt 3D verden. Deretter plasseres eventuelle lyskilder og et ”kamera” i den tenkte verden. Kameraet posisjoneres slik at det fanger opp den delen av scenen som ønskes vist på skjermen. Det er viktig å skille på objektene og bildet av objektene. Legg merke til at objekter, lyskilder og kamera plasseres uavhengig av hverandre.

Scene og kamera














Objekter spesifiseres ved hjelp av geometriske primitiver. Geometriske primitiver spesifiseres igjen vha. vertekser. Vertekser kan, i tillegg til å inneholde en posisjon, også inneholde informasjon om farge, tekstur og normalvektor (brukes i forbindelse med lys – mer om dette senere). Man kan dermed beskrive modeller vha. et sett vertekser. En trekant spesifiseres av tre vertekser. En kule består av et stort antall trekanter.

Det virtuelle kamera

Kameramodellen som brukes i moderne 3D grafikksystemer simulerer i prinsippet optiske systemer.

Figuren viser hvordan objektet (huset) i scenen projiseres på et bildeplan. Trekker man projeksjonslinjer fra objektet til kameralinsen finner vi ”bildet” av modellen på bildeplanet.

Det virtuelle kamera

Objekter som er langt fra kameraet vil fremstå som mindre på bildeplanet enn objekter som er nærmere kameraet.

Fordeler med denne kameramodellen er blant annet at vi skiller på objekter, betrakter (kameraet) og lyskilder. Alle disse spesifiseres og plasseres uavhengig av hverandre. Dette gjør det mulig å utforme bildet av objektene ved hjelp av geometriske beregninger i form av vektor- og matriseoperasjoner.

Figuren viser essensen av 3D datamaskingrafikk. Modellene beskrives og plasseres i en tenkt 3D verden. Deretter plasseres kamera og lyskilder uavhengig av modellene. Kameraets plassering og synsvidde bestemmer bildet av ”scenen” som så omgjøres til et 2D bilde vha. projeksjon.

3D API

3D APIer gir som regel programmerern følgende muligheter:
  • spesifisere primitiver og objekter.
  • spesifisere betrakteren (eller kameraet). 
  • spesifiserer lyskilder 
  • spesifiserer materialegenskaper (bl.a. farge).
Både OpenGL, OpenGL ES og Direct3D er eksempler på 3D APIer som tilbyr dette. Andre eksempler er  Metal (Apple) og Vulkan (Khronos Group).

Programmereren ser grafikksystemet gjennom APIet. På den ene siden av APIet er vårt program, på den andre implementasjonen av funksjonene i APIet – dette kan være i form av programvare og/eller maskinvare.

Grafikk API (Angel et al, 2015)

Dette fungerer ved at objektene (og verteksene) prosesseres i den rekkefølgen de genereres av applikasjonen. Omforming av vertekser til piksler i skjermbufret utføres i en såkalt graphic pipeline som vil bli nærmere forklart etter hvert.

3D-grafikkteknologier

Det finnes en rekke lavnivås 3D APIer men de mest utbredte er følgende:
  • Direct3D
  • OpenGL
  • OpenGL ES
Andre eksempler er Metal, Vulkan, RenderMan, RenderWare m.fl.

WebGL er et "tynt" Javascript API over OpenGL ES. Vi kommer tilbake til WebGL etter hvert siden dette er gjennomgangstemaet i disse notatene. Det kan også nevnes at Googles Android har et tilsvarende API mot OpenGL ES. Kjenner man WebGL/Javascript/OpenGL ES vil en eventuell overgang til Android/Java/OpenGL ES være relativt enkelt.

I tillegg finnes flere høyere nivås APIer som OGRE, JMonkey, Monogame (tidligere XNA, se www.monogame.net), Java3D.  Java3D er et Java API for 3D grafikk som enten kjører over OpenGL eller Direct3D.

I det siste har det også dukket opp høynivås APIer for nettleseren som f.eks. Three.js (http://threejs.org) og Babylon (http://www.babylonjs.com). Begge disse er igjen basert på WebGL. Three.js vil bli mer omtalt etter hvert.

Direct3D

Direct3D er en del av Microsofts DirectX plattform. DirectX var i utgangspunktet en samling med APIer for utvikling av spill og omfattet APIer som DirectDraw (2D), DirectMusic, DirectPlay m.fl.

Direct3D er i utgangspunktet kun tilgjengelig på Windows-plattformene i tillegg til XBox og XBox 360 konsollene. APIet er optimalisert for 3D grafikk for datamaskinspill. Direct3D bruker tilgjengelig maskinvarestøtte dvs. grafikkort dersom tilgjengelig. Dette betyr at den beregningskrevende koden kjører på grafikkprosessoren (GPU) – i stedet for på maskinens CPU. Vha. Direct3D kan man utvikle både 2- og 3D grafikkapplikasjoner. Direct3D gir programmereren et API mot grafikkortets drivere. Figuren under viser en oversikt over Direct3D sin plassering i forhold til applikasjon, grafikkortdrivere og maskinvare.
Direct3D, lagdeling

Direct3D et lavnivås API som i prinsippet gir tilgang til alle grafikkortets funksjoner.

OpenGL

OpenGL (http://www.opengl.org) er et 3D API for utvikling av portable 2- og 3D applikasjoner. OpenGL ble introdusert i 1992 av Silicon Graphics Inc. (SGI) og er i dag svært utbredt og brukes i forbindelse med Computer Aided Design (CAD), virtuell virkelighet, medisinske applikasjoner, ulike typer simuleringer og datamaskinspill.

Det finnes i dag støtte for OpenGL til de fleste operativsystemplattformer inkludert Mac OS X, de fleste UNIX-varianter, alle aktuelle Windows-varianter, Linux med flere.

Det finnes i dag språkbindinger til C, C++, Java, Fortran og Ada. OpenGL er leverandøruavhengig og ble i utgangspunktet administrert av OpenGL Architecture Review Board med bred støtte fra industrien. I 2006 ble administrasjon av OpenGL flyttet til Khronos Group (Khronos Group, About, 2009). Det kan nevnes at Microsoft var med her inntil 2003.

OpenGL bruker tilgjengelig maskinvare/grafikkort og GPU dersom tilgjengelig på maskinen som kjører OpenGL-applikasjonen.

Fordelen med OpenGL er sin brede støtte, åpne arkitektur samt at det finnes støtte for APIet på de fleste plattformer. Det er også etter hvert kommet flere gode bøker om emnet. Hele APIet består av 250+ parameterstyrte funksjoner. OpenGL er et rent grafikkbibliotek og ikke spesielt rettet mot spillutvikling (selv om det er mye brukt til dette).

OpenGL ES

En variant av OpenGL, OpenGL ES (Khronos Group, OpenGL ES), der ES står for Embedded Systems, har de senere årene blitt mer og mer aktuelt siden det brukes av plattformer som Android, Apple/iOS (og iPhone/pad) og Sony Playstation. I tillegg ble det ved innføring av HTML5-standarden også mulig å lage 3D applikasjoner via WebGL, som også er basert på OpenGL ES. Programmering mot WebGL-APIet gjøres vha. Javascript.

OpenGL ES er et subsett av standard OpenGL og finnes i flere versjoner. Figuren under viser sammenhengen mellom disse. Her ser vi at OpenGL ES 1.1 og OpenGL ES 2.0 er inkompatible versjoner. Versjon 1.1 er/var et subset av OpenGL 1.5. Forskjellen på disse versjonene og etterfølgende versjoner er at fra og med OpenGL 2.0/GL ES 2.0 ble programmerbare shadere innført. Dette gjør at programmereren har mye mer kontroll på hvordan det endelige 3D-bildet fremstår på skjermen. Dette gjøres ved å lage såkalte «shader-programmer» som uføres av GPUen. Tidligere var ikke dette mulig. OpenGL ES versjon 2.0 er et subset av OpenGL 2.0 mens OpenGL ES 3.0 er et subset av OpenGL 3.3.


I neste delkapittel introduseres shaderbegrepet og det vi kaller «graphics pipeline».

Shadere og Graphics Pipeline 

OpenGL & OpenGL ES definerer en prosess for å konvertere vertekser, teksturer m.m. til et bilde som kan vises på skjermen. Prosessen er beskrevet som en graphics/rendering pipeline. Vi kan sammenlikne dette med et slags ”transportbånd” der verteks- og pikseloperasjoner utføres i ulike steg. Dette er vist i figuren under:

Forenklet rendering/graphics pipeline

En shader er et program som kjører av GPUen og som regel består denne av flere del-programmer/funksjoner. Shaderspråket knyttet til OpenGL kalles GLSL ES og har en C-liknende syntaks.

I klientprogrammet, f.eks. WebGL/Javascript, spesifiseres punkter/vertekser. Verteksene definerer igjen primitiver/trekanter som utgjør modellen(e) som skal tegnes på skjermen.

Primitiv og modell


Hver trekant spesifiseres vha. tre vertekser. Hver verteks har en x,y og z-verdi.

Verteksene legges typisk i et array/buffer og leveres til GPUen. Første steg på veien er verteksshaderen. Dette er, som nevnt, et lite program som kjører for hver enkelt verteks til modellen.

Verteksshaderen manipulerer (transformerer) verteksen i henhold til kriterier gitt av klientprogrammet. Dette kan f.eks. bety at alle vertekser flyttes litt langs x-aksen, som betyr at hele modellen flyttes litt langs x-aksen. Et annen mulighet er at modellen skal rotere noen grader om z-aksen – alle verteksene må da roteres om z. Hvor mye modellen skal flyttes eller roteres bestemmes fra klientprogrammet ved å sende en transformasjonsmatrise til shaderen. 

Deretter vil verteksene sammenstilles («primitive assembly») slik at de er klar til å bli fylt med farger (piksler). Dette skjer i neste steg - her beregnes hvilke fragmenter (tenk på et fragment som en piksel) som inngår i hvert primitiv (trekant)

For hvert fragment kjøres deretter fragmentshaderen. Dette er også er et lite program som kjøres av GPUen. Siden denne kjører for hvert fragment kan man som programmerer her påvirke hver enkelt fragment (piksel) før de vises på skjermen. Returverdien fra fragmentshaderen må være en farge for aktuell piksel, som til slutt ender opp i framebufferet og skjermen.

Figuren under illustrerer dette:
Enda mer forenklet rendering/graphics pipeline
Når man bruker OpenGL ES (>v 2.0)  man bruke verteks- og fragmentshadere for i det hele tatt få noe frem på skjermen.

NB! En verteks er ikke det samme som et punkt på skjermen. En verteks er et (virtuelt) punkt i 3D-rommet som brukes til å definere primitiver (f.eks. trekanter). Hittil har vi sagt at primitiver enter er linjer eller trekanter (evt. mangekanter/polygoner som støttes av OpenGL men ikke OpenGL ES).

I WebGL/OpenGL ES finnes det også et punkt-primitiv. Dette betyr at det er mulig å tegne en enkel verteks som et punkt. Man kan også bestemme størrelsen på punktet. Mer om dette etter hvert.

GLSL / GLSL ES

Shaderprogrammene, dvs. verteksshader og fragmentshader, er i praksis to programmer/funksjoner som kjøres av GPUen. Verteksshaderen kjører for hver verteks mens fragmentshaderen kjører for hvert fragment (piksel).

Disse programmeres vha. et eget shader programmeringsspråk som kalles OpenGL Shading language (GLSL). Syntaksen til GLSL er C-liknende og dermed relativt enkelt å lære dersom man har programmeringsbakgrunn. OpenGL ES har sin variant som heter GLSL ES (Khronos Group, GLSL ES, 2009).

Vi kommer tilbake til shadere etter hvert siden dette er en fundamental del av OpenGL ES og dermed også WebGL.

OpenGL eller Direct3D?

Her er det selvfølgelig delte meninger. Fordelen med OpenGL / ES er åpenhet og støtte for mange plattformer. Ulempen er at det kan oppleves som relativt tungt å komme i gang med dette APIet. OpenGL er tiltenkt alle typer 3D applikasjoner og ikke spesielt utviklet med tanke på datamaskinspill.

Direct3D (en del av DirectX) ble i utgangspunktet utviklet med tanke på spill. Direct3D kan programmeres vha. C++. En av ulempene er at DirectX er et proprietært Microsoft API.