An Introduction – 3D on the Web – Hello Canvas (2D)



An Introduction – 3D on the Web – Hello Canvas (2D)

0 0


introduction-to-webgl

Presentation

On Github eoaksnes / introduction-to-webgl

Velkommen til denne introduksjonstalken om WebGL. Me (Thomas og Eirik) og me e konsulenta i Bouvet, som dåkke ser. Grunnen til at me valgte å snakka om WebGL idag er todelt; 1. me var så heldig å jobbe med ein WebGL applikasjon (og andre kule teknologier) på et prosjekt hos ein kunde og 2. Da e kult. Før me fortsette her, så kunne eg tenkt meg å sjå kor mange av dåke som har 1. Hørt om WebGL 2. Jobba med WebGL - Ok, då håpe eg at dåkke blir (enda meir) trigga te å testa og hacke med WebGL etter denne talken her. Da eg syns e litt spesielt e at WebGL ikkje er hypa like mykje som mange andre nye teknologier for web, som f.eks. LocalStorage, WebThreads, WebSockets, WebRTC osv. Det kan jo hende at det har noe med at det har blitt forsøkt med 3D på webben omtrent siden den spede begynnelsen. (VRML 1995/1997), uten aldri å ha slått særlig an (trur eg). 3D er jo kult. Eller, det var kult i hvert fall. Og det som ein ofte kjennetegner med 3D og grafikk på webben før WebGL er jo noe sånt som dette:

An Introduction

24.09.2015

Eirik Ola Aksnes | Thomas Johansen

No er jo dette WebGL i en browser, men ikkje nåkke meir magisk enn "bevegelig WordArt". Og så tar den opp hele browservinduet.

Agenda

  • 3D on the Web
  • Hello Canvas (2D)
  • Hello WebGL (3D)
  • WebGL Basics
  • Draw Something Meaningful
  • Three.js to the rescue!
  • Great Examples
  • References
og det introduserer oss for 3D på webben.

3D on the Web

Obligatorisk xkcd

BEFORE (PLUG-INS)

Tidligere (og litt fortsatt) så finnes det nesten et uttall teknologier som gir oss muligheten til 3D og grafikk i en web browser, MEN 1. De har alle behov for plug-ins 2. Integrasjonen med websida er så som så (fra fraværende til delvis mulig). Ingen av disse har vel slått nok til at de blir værende tilgjengelig så mye lenger (i sin original innpakning). Det er vel dette som er grunnen til at 3D på webben har fått et dårlig rykte. Mye "bells and whistles", men lite sluttprodukt/resultat/utbytte, i hvert fall slik det ofte har blitt brukt. Det som er litt interessant med et par av teknologiene her (O3D, X3DOM og VRML) er at de er gått over til å bruke WebGL til å rendre 3D grafikken som default.
  • Adobe Flash, MS Silverlight
  • Java OpenGL, JOGL, Java 3D
  • O3D
  • VRML, X3D/X3DOM
Mens det har vært litt kamp på webben om 3D og grafikk, så har (2D/3D APIet OpenGL) OpenGL utvikla seg i det stille siden 1992. Fra å være rigid og fastlåst til å bli mye mer dynamisk, med hovedvekt på programmerbar pipeline (dynamisk prosessering av piksler, med "vertex shader" (posisjonskalkulator) og "fragment shader" (fargevelger) for prosessering av piksler. Dette kommer vi mye nærmere innpå senere i talken. Fra dette så ble det også utviklet en OpenGL ES standard for mobile enheter med mindre maskinkraft/ytelse, et subset av OpenGL. WebGL 1.0 er basert på OpenGL ES 2.0 standarden, og det er den vi skal snakke om i dag. Det som er også viktig å merke seg er jo at APIen vanligvis (det er en wrapper som også kan brukes for programvareakselrering på CPUen...) interagerer med GPUen for å få maskinvareakselrasjon rendering av 3D (og ikke programvareakselrering som man sier om man bruker CPUen til det samme. Som kjent er GPUen mye mer anvendelig for grafikk og flyttallsoperasjoner enn CPUen. OpenGL 2.0: Som dere ser tok det lang tid fra versjon 1.0 til neste store versjon 2.0. Hovednyheten var muligheten for programmereren å erstatte den faste og uskiftbare vertex/fragment pipelinen med "shadere".

OpenGL

  • 1992 - OpenGL 1.0
    • Direct-mode rendering
    • Fixed pipeline
  • 2004 - OpenGL 2.0
    • Programmable pipeline: vertex (position calculator) and fragment (color chooser) shading stages of the pipeline
    • OpenGL Shading Language
  • 2007 - OpenGL ES 2.0
    • Designed for mobile phones, embedded devices and video game systems
  • 2010 - OpenGL 4.0
  • 2011 - WebGL 1.0
  • 2012 - OpenGL ES 3.0
  • 2014 - OpenGL 4.5
  • 201? - WebGL 2.0

NOW

Så det som har skjedd er at vi i prinsippet har kombinert OpenGL ES 2.0 med JavaScript og HTML 5 canvas elementet for å få WebGL. Og det er kult. Men det som hovedsaklig skiller seg ut er jo direkte støtte i nettleseren, med toveis tilgang til JavaScript og DOMen, som en hvilket som helst annen HTML-komponent (del av HTMLen). Og kan derfor manipuleres, - og manipulere HTMLen (DOMen) fra JavaScript.
OpenGL ES 2.0 + JavaScript + HTML5 canvas
=

WebGL

(+ data)
WebGL krever INGEN plug-ins, det kjører direkte i browseren. Det er lett å komme i gang, ingen installasjoner kreves og man kan skrive koden i VIM og Emacs. JavaScript APIen finnes altså i browseren, og man skriver HTML og JavaScript. WebGL elementet(ene) blir rett og slett en del av websiden, og ikke som en ekstern applikasjon. Den er sømløst integrert/en del av koden, på samme måte som LocalStorage, WebSockets og 2D canvas, som gjør at man kan bruke WebGL der man ser at det er mest logisk å bruke det; isf. f.eks. statisk bilde, vise statistikk eller data visuelt eller at man kanskje trenger ytelsen til GPUen for en gitt type beregninger (WebCL). Ein har direkte tilgang til GPUen (ytelse og lavnivå) som gir oss enorme muligheter, men det finnes også et godt utvalg av høynivå biblioteker for å effektivt bruke teknologien. Det er selvsagt også noen potensielle ulemper. Med JavaScript så får vi ikke like høy ytelse som vi kunne hatt, f.eks. pga. tid til å parse data og flytte data over på GPUen for prosessering. Ulik Hardware har også tilsvarende effekt, ved at noe som fungerer utmerket på en desktop PC ikke kjører, eller hakker mye en mobiltelefon. Dette er logisk, men kanskje noe man glemmer av mtp. portabiliteten. Sist, så har det også vært litt sikkerhetsbekymringer, men kritikerne (Microsoft og Apple) ser ut til å ha stilnet nå, ettersom de begge har implementert WebGL i sine respektive browsere. Helt til slutt, hvilke browsere støttes da? asm.js. Og, når koden er shippa til GPUen så kjører vi jo på nativ hastighet, det er logikken mellom stegene som er javascript-hastighet...javascript er mer eller mindre ikke i stand til å få GPUen til å kjøre 100%, fordi den ikke klarer å sende/prosessere data raskt nok. Hva skjer f.eks. om du overgår videominnet? Det er implementasjonsavhengig, og kan variere fra plattform til plattform. På samme måte som at videominnet varierer mye...her handler det selvsagt å kunne teste på mange forksjellige plattformer. Og forressten, du kan IKKE finne ut hvor mye minne du har til rådighet, det er en sikkerhetsissue....så det blir jo krasj da..evnt. at operativsystemet flytter videominne til RAM...som gjør at det blir sirup... WebGL har extensions fra OpenGL, som gjør at "nye" features kan være tilgjengelig i "gamle" APIer, men dette varierer fra enhet til enhet. Selvom det kan være fristende, eller lett å glemme, bør man passe på å ikke bruke noe som ikke er støttet av en enhet som skal være støttet... Å ha denne muligheten å bruke features før de er spikra i neste versjon kan jo selvsagt også være fint... Forskjellige plattformer, med forskjellige underliggende APIer (Direct3D) etc. yter forskjellig, spesielt når spennet av hardware skal være såpass stort; PCer til mobiler. Det er i så tilfelle viktig å lage noe som fungerer bra "overalt". Dette har med portabilitet å gjøre...som ofte er en av grunnene til å velge WebGL... Du kan manipulere DOMen fra WebGL scripts, og du kan interaktivt manipulere grafikken vha. JavaScript. Det som gjør det så spennende med WebGL er at det blir mulig og mye enklere å lage nye brukergrensesnitt som inntil nå har vært umulig uten eksterne plug-ins og tredjeparts programvare. Skillet mellom desktop-applikasjoner og webapplikasjoner viskes enda mer ut, og man får "gratis" portabilitet mellom mange plattformer man ikke trenger ta hensyn til som utvikler.

YAY!

  • + NO Plugins!
  • + Easy to use
  • + Integrates nicely in website
  • + Two-way interaction
  • + GPU access
  • + Low-level API
  • + High-level Libraries
  • + Browser support
  • - Performance limitations (JS)
  • - HW limitations
  • - Security conserns
Maaaaange. De aller fleste av de som brukes, dvs 80% av brukermassen på web har hel eller delvis støtte for WebGL 1.0. Det er mao. ingen grunn til å holde tilbake.

Supported browsers*

  • Desktop - Opera > 12
  • Desktop - Chrome > 9
  • Desktop - Firefox > 4
  • Desktop - Safari > 5.1
  • Desktop - Internet Explorer >= 11 (Partially)
  • Desktop - Edge
  • Mobile - Firefox > 4
  • Mobile - Chrome > 25
  • Mobile - Opera > 12
  • Mobile - iOS > 8
  • Mobile - IE > 8.1
  • Mobile Others : Maemo, Sailfish, Tizen, Ubuntu Touch, WebOS...
  • ~80% of web users

*As of 01.09.2015

Då e det tid for hands-on. Først ut så ser vi på Canvas-elementet.

Hello Canvas (2D)

Dette elementet har eksistert i lang tid (2004/2005) og benyttes til å manipulere/rendre en bitmap. Dvs. hele canvasen består av piksler som vi kan endre på. Her er lerretet uten noen form for behandling, men med sort bakgrunn.

1. Create a canvas element

<canvas id="myCanvas" width="400" height="400" style="background-color: black;">
  Your browser doesn't appear to support the HTML5 <canvas> element.
</canvas>
						
Your browser doesn't appear to support the HTML5 <canvas> element.
For å manipulere/endre på lerreret må vi først hente konteksten/handleren for 2D manipulering.

2. Obtain a drawing context

var canvas = document.getElementById("myCanvas");
var drawingContext = canvas.getContext("2d");
						

Som i Java og mange andre språk så kan vi bruke primitive instruksjoner som flytt, tegnlinje, velge malerkost for å tegne i ett "koordinatsystem".

3. Draw something

drawingContext.strokeStyle = "#0000FF";
drawingContext.fillStyle = "#00FF00";
drawingContext.lineWidth = 4;

drawingContext.beginPath();

drawingContext.moveTo(250,0);
drawingContext.lineTo(500,500);
drawingContext.lineTo(0,500);
drawingContext.lineTo(250,0);

drawingContext.fill();
drawingContext.stroke();
drawingContext.closePath();
						
Resultatet blir f.eks. dette. Og så over til en ekstra dimensjon.

3. The result

Your browser doesn't appear to support the HTML5 <canvas> element.

Hello WebGL (3D)

  • I de to neste to seksjonene vil jeg si noe om;
    • Hvordan WebGL fungerer
    • Hva som trengs for å lage WebGL applikasjoner
  • Tenkte å starte å introdusere WebGL med et veldig enkelt eksempel

Draw a blue background

  • As simple as it gets (with raw WebGL)
  • Så enkelt som det kan bli

1. Create a canvas element

<html>
  <head>          
    <script type="text/javascript">
      function draw() {
        ...
      }
    </script>
  </head>
  <body onload="draw()">
    <canvas id="canvas" width="500" height="500"></canvas>
  </body>
</html>
						

2. Obtain a WebGL context

<html>
  <head>          
    <script type="text/javascript">
      function draw() {
        var canvas = document.getElementById('canvas');
        var gl = canvas.getContext("webgl");
        ...
      }
    </script>
  </head>
  <body onload="draw()">
    <canvas id="canvas" width="500" height="500"></canvas>
  </body>
</html>
						
  • Get a reference to the canvas element
  • Obtain a WebGL context
    • Through gl (JavaScript object) we can access all WebGL functionality

3. Set background color

<html>
  <head>          
    <script type="text/javascript">
      function draw() {
        var canvas = document.getElementById('canvas');
        var gl = canvas.getContext("webgl");
        gl.clearColor(0, 0, 0.5, 1);
        gl.clear(gl.COLOR_BUFFER_BIT); // Call the clear function to set the color
      }
    </script>
  </head>
  <body onload="draw()">
    <canvas id="canvas" width="500" height="500"></canvas>
  </body>
</html>
						
  • Det er enkelt og raskt å komme i gang med WebGL:
    • Ingen installasjon
    • Ingen byggeskript (makefiles, scons), som du har med C++ applikasjoner og OpenGL
    • Nettleseren gjør arbeidet for deg

WebGL Basics

Low Level API

  • WebGL is designed
    • To work directly with your GPU
    • So that you can build higher level libraries upon it
  • Siden WebGL er et lav nivå API;
    • Så må man gjøre mye selv
    • Man får forholdsvis lite hjelp av WebGL APIet
    • F.eks så har man ikke en funksjon som heter "tegn trekant"
  • Vi har desverre ikke tid til å gå inpå alle detaljene , men håper gi nok informasjon til at dere får en slags ide om hvordan WebGL fungerer
  • Det blir litt teori først nå, før vi vil vise noe kode

Already know WebGL?

  • If you know OpenGL, you may already know WebGL
    • WebGL is quite different from OpenGL <= 3.0 and OpenGL ES 1.x
  • Eldre OpenGL funksjonalitet er droppet i WebGL:
    • Ting som ikke er effektivt
    • Man må bruke shadere
    • Removes seldom-used or legacy features

We have to use shaders

  • OpenGL ES 1.0 uses a fixed function pipeline
    • Built-in functions to set lights, fog, colors, vertices, cameras, and more
    • Easy to use
  • OpenGL ES 2.0 (and WebGL) uses a programmable pipeline
    • Built-in functions are removed and replaced by programmable shaders
  • Jeg har tenkt å si noen få ord om forskjellen mellom en "fixed function" og programmerbar pipeline
  • I den "fixed function pipeline" har du ferdige funksjoner for å aktivere lys, tåke, kamera

Graphical Pipeline

Programmable pipeline

  • I WebGL er pipelinen programmerbar, gjennom noe som kalles shadere.
  • Så hva er en shader?

What Are Shaders?

  • Small "programs" that runs on the GPU
  • Have a well-defined set of input/output values, some built-in and some user-defined
  • Written in OpenGL Shading Language (GLSL)
  • GLSL syntax is kinda like C
  • Generally regarded as fairly advanced, but it is actually much simpler than it looks
  • For de som er kjent med Nvidia CUDA kan shaders sammenlignes med Kernels, men forskjellen er at Shaders har et veldefinert sett av input og output verdier, siden de er en del av en pipeline

Shader Effect Examples

  • Shaders can be used to create cool effects like lightning, shadowing, refraction, and more

Reference

Med shadere kan implementere egne metoder/algoritmer for å oppnå ønskede effekter (lys, skyggelegging, refleksjoner) I disse to eksemplene er det samme datagrunnlag, men vet å anvende forskjellige shader, så får man forskjellige effekter!

Shaders In WebGL

  • There are two shader types (two stages of the pipeline are programmable):
    • A vertex shader (process vertices)
    • A fragment shader (process fragments/pixels)
  • You will need both shaders in order to draw anything on the screen
  • For standard usage these shaders are quite simple
  • No default shaders
  • You need to write your own shaders or use one provided by a WebGL library (copy and paste)

Draw Something Meaningful

  • I denne seksjone skal vi se på ett litt mer meningsfylt eksempel, vi skal tegne en trekant
  • Det er fortsatt et enkelt eksempel, men som vi skal se, så kreves det litt arbeid for å faktisk kunne tegne en trekant

Draw A Triangle

  • Reusing the code from the previous example (blue background)

How To Draw A Triangle?

  • The basic idea is to send a list of vertices to the GPU for drawing
  • A triangle is defined by three vertices (corner points)
  • Det man gjør er å:
  • Lage en list over hjørnepunktene til trekanten
  • Disse hjørnepunktene blir så matet til GPUen
  • GPUen kjører så disse hjørnepunktene gjennom en pipeline (rørledning som det heter på norsk)

Simplified WebGL Pipeline

Reference

  • Det som skjer er at;
    • Først blir hjørnepunktene lastet opp til GPU minnet
    • Så blir hjørnepunktene kjørt gjennom en vertex shader, som har i oppgave å posisjonere ut hjørnepunktene
    • Så blir resultatet fra vertex shaderen sendt videre til en fragment shader som har i oppgave å fargelege mellom hjørnepunktene
    • Til slutt så blir det generert et bilde
  • Nå er vi ferdig med grunnlegende teori og skal se på noe kode på hvordan vi kan tegne trekanten!

Create A Buffer

  • That contains the three vertices (corners) of the triangle

function createBuffer(gl) {
  // Create buffer
  var vertexPositionBuffer = gl.createBuffer();
  // Activate buffer
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
  var triangleVertices = [
    -0.5, -0.5,
     0.5, -0.5,
     0.0, 0.5
  ];
  // Copy vertices to buffer (on the GPU)
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
  return vertexPositionBuffer;
}
						
Vi må lage oss et buffer som inneholder de tre hjørnepunktene til trekanten. Det vi gjør:
  • Lager ett nytt buffer
  • Aktiverer bufferet
  • Lager en liste over hjørnepunktene med JavaScript
  • Til slutt så kopiere vi listen med hjørnepunkt over til det allokerte GPU minnet

A Simple Vertex Shader

  • Executed 3 times, once for every vertex of the triangle
  • Its job is to set something called gl_Position, the final position of a vertex on the viewport (i.e. screen)
<script id="vertex" type="x-shader">
  attribute vec2 vertexPosition;
  void main() {
    gl_Position = vec4(vertexPosition, 0, 1); //xyzw
  }
</script>
						
  • For å få posisjonert ut disse hjørnepuntkene må man lage seg en vertex shader.
  • Dette er en veldig enkel vertex shader som har i oppgave å posisjonere ut hjørnepunktene
  • Den tar bare verdiene direkte ifra bufferet og sett det som endelig posisjon
  • gl_Position - Bygd inn variabel

Vertex shaders typically:

  • Rotate, translate and scale each vertex of the 3D model to place it correctly relative to the virtual camera (which is always at the origin).
  • Perform perspective calculations.
  • Perform some of the lighting math.
  • Handle complex animation tasks.

A Simple Fragment Shader

  • Executed once for every pixel covered by the triangle
  • The GPU figures out which pixels on the screen that are covered by the triangle
  • Its job is to set something called gl_FragColor, the final colour of a pixel
<script id="fragment" type="x-shader">
  void main() {
    // Just apply the same color (rgba) to every pixel covered by the triangle
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
  }
</script>
						
  • For å få fargelagt trekanten må man lage seg en fragment shader.
  • Dette er en veldig enkel "fragment shader" som vil fargelege alle pikselene grønn mellom hjørnepuntene til trekanten

Fragment shaders typically:

  • Apply texture.
  • Perform lighting calculations.
  • Add in 'atmospheric' effects: fog, etc.

Create And Compile Shaders

function createShader(str, type) {
  var shader = gl.createShader(type);
  gl.shaderSource(shader, str);
  gl.compileShader(shader);
  return shader;
}
var vertexShader = createShader(document.getElementById("vertex").innerHTML, gl.VERTEX_SHADER);
var fragmentShader = createShader(document.getElementById("fragment").innerHTML, gl.FRAGMENT_SHADER);
    					

Create A Shader Program

  • The vertex shader and fragment shader are linked together into a shader program (or just program)
function createShaderProgram(vertexShader, fragmentShader) {
  // A program consists of a vertex and fragment shader
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  // Set the specified program as the currently active program
  gl.useProgram(program);
  return program;
}
    					

Vertex Shader Attributes

  • Attributes is input to vertex shader (not fragment shader)
  • Each vertex normally has a set of attributes associated with it
    • Position
    • Color
    • Normal
function vertexShaderAttributes(gl, shaderProgram, vertexPositionBuffer) {
  // Make the vertices available to the vertex shaders
  shaderProgram.vertexPositionAttrb = gl.getAttribLocation(shaderProgram, 'vertexPosition');
  gl.enableVertexAttribArray(shaderProgram.vertexPositionAttrb);
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
  gl.vertexAttribPointer(shaderProgram.vertexPositionAttrb, 2, gl.FLOAT, false, 0, 0);
}
    					
  • Vertex shaderen får altså data fra bufferet, så hva vi gjør her er å fortelle hvordan vertex shaderen skal lese data fra bufferet. F.eks at trekant hjørnepuntene skal leses som "vertexPosition"

Draw The Triangle

gl.drawArrays(gl.GL_TRIANGLES, 0, 3);
						
  • Vi har nå alt som trengs for å tegne vår trekant

The Result

The bottom line

  • A lot of work (low level API)
  • Any WebGL program will have similar structure
    • Obtain a WebGL context from the canvas element
    • Upload drawing data into buffers
    • Create and compile shaders
    • Create a shader program
    • Draw
  • Higher level libraries will be a big help!
  • Som vi ser, må man gjøre en del selv. Man får forholdsvis lite hjelp av WebGL APIet
  • Dette gjør at man i mange sammenhenger velger å bruke høyerenivå APIer bygd på WebGL
  • Vi skal ta en titt på ett høyerenivå API nå i neste seksjon

THREE.js TO THE RESCUE!

  • Three.js til unnsetning

Three.js

  • Three.js skjuler mange av detaljene i 3D grafikk:
    • Man trenger ikke vite hva en Shader er
    • Man har enkle datastrukturer å jobbe med

The HTML

<html>
  <head>
    <title>Three.js Visualization</title>
    <script src="three.js"></script>
    <script>
      // Your JavaScript will go here
    </script>
  </head>
  </body><body>
</html>
						

Need three things

Scene Camera Renderer
  • Du trenger tre ting:
    • En renderer som har som ansvar å tegne en scene.
    • En scene, som inneholder hva man skal tegne.
    • Ett kamera, f.eks perspektiv kamera, som vil tegne ting som er mindre lengre unna.

1. Scene

Contains what to draw

var scene = new THREE.Scene();
						

2. Camera

Perspective camera

var fieldOfView = 45;
var aspectRatio = window.innerWidth / window.innerHeight;
var zNear = 0.1;
var zFar = 10000;
var camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, zNear, zFar);
						
  • Ett kamera, f.eks perspektiv kamera, som vil tegne ting som er mindre lengre unna.

3. Renderer

Create

var renderer = new THREE.WebGLRenderer({ clearColor: 0x0000FF });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
						

Render the scene with selected camera

renderer.render(scene, camera);
						

Now we can start draw things...

Triangle

var geometry = new THREE.Geometry();
var vertex1 = new THREE.Vector3(-0.5 ,-0.5, 0);
var vertex2 = new THREE.Vector3(0.5, -0.5, 0);
var vertex3 = new THREE.Vector3(0.0, 0.5, 0);
geometry.vertices.push(vertex1);
geometry.vertices.push(vertex2);
geometry.vertices.push(vertex3);
geometry.faces.push(new THREE.Face3(0, 1, 2 ));
var material = new THREE.MeshBasicMaterial({
  color: 0x00FF00
});
var triangle = new THREE.Mesh(geometry, material);
scene.add(triangle);
						
  • For å tengne en trekant med three.js så lager vi oss en mesh som består av:
    • Geometri - formen til et object
    • Material - utseende på flatene
  • THREE.Face3 - Her kobler man sammen de 3 hjørnepunktene til en triangle overflate
  • 0x00FF00 == Grønn trekant

Torus

Torus

var radius = 40;
var tube = 10;
var radialSegments = 50;
var tubularSegments = 50;
var geometry = new THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments);
var material = new THREE.MeshBasicMaterial({
  color: 0x0000FF
});
var torus = new THREE.Mesh(geometry, material);
scene.add(torus);
						
  • Bytte ut geometrien med en smultring. Definerer radius osv...

Spin The Camera

function animate(time) {
  // Spin the camera in a circle
  camera.position.x = Math.sin(time/1000) * 150;
  camera.position.y = 50;
  camera.position.z = Math.cos(time/1000) * 150;
  // You need to update lookAt every frame (0,0,0)
  camera.lookAt(scene.position);
  renderer.render(scene, camera);
  window.requestAnimationFrame(animate);
}
animate(new Date().getTime());
						

Reference

Color Picker

Because WebGL is programmed in JavaScript, this makes it easier to integrate WebGL applications with other JavaScript libraries such as JQuery UI and with other HTML5 technologies

<link rel="stylesheet" href="jquery-ui-1.10.2.custom/css/smoothness/jquery-ui-1.10.2.custom.css" />
<script src="jquery-ui-1.10.2.custom/js/jquery-1.9.1.js"></script>
<script src="jquery-ui-1.10.2.custom/js/jquery-ui-1.10.2.custom.js"></script>
						

Color Picker - HTML

<div id="colorPicker">
  <div id="red"></div>
  <div id="green"></div>
  <div id="blue"></div>
</div>
                        

Color Picker - CSS

#colorPicker {
  position: absolute;
  left: 10px;
  top: 10px;
}
#red, #green, #blue {
  float: left;
  clear: left;
  width: 300px;
  margin: 15px;
}
...
                        

Color Picker - Sliders

$("#red, #green, #blue").slider({
  orientation: "horizontal",
  range: "min",
  max: 255,
  value: 127,
  slide: setMaterialColor,
  change: setMaterialColor
});
$("#red").slider("value", 0);
$("#green").slider("value", 0);
$("#blue").slider("value", 255);
                        

Color Picker - Set material color

function setMaterialColor() {
  var red = $("#red").slider("value");
  var green = $("#green").slider("value");
  var blue = $("#blue").slider("value");
  material.color.r = red / 255;
  material.color.g = green / 255;
  material.color.b = blue / 255;
}
                        

Lightning

Spot light (green)

var light = new THREE.SpotLight(0x00DD00);
light.position.set(200, 0, 0);
scene.add(light);
						

Ambient light (red)

var light = new THREE.AmbientLight(0xDD0000);
scene.add(light);
						

http://japhr.blogspot.no/2012/07/lights-and-materials-in-threejs.html

Texture

Load textures

var chromeTexture = THREE.ImageUtils.loadTexture("chrome.png");
var catTexture = THREE.ImageUtils.loadTexture("cat.jpg");
						

Apply textures

var materialArray = [];
materialArray.push(new THREE.MeshLambertMaterial({map: catTexture}));
materialArray.push(new THREE.MeshLambertMaterial({map: chromeTexture}));
materialArray.push(new THREE.MeshLambertMaterial({map: chromeTexture}));
materialArray.push(new THREE.MeshLambertMaterial({map: chromeTexture}));
materialArray.push(new THREE.MeshLambertMaterial({map: chromeTexture}));
materialArray.push(new THREE.MeshLambertMaterial({map: chromeTexture}));
var cubeGeometry = new THREE.CubeGeometry(50, 50, 50, 1, 1, 1);
var cubeMesh = new THREE.Mesh(cubeGeometry, new THREE.MeshFaceMaterial(materialArray));
scene.add(cubeMesh);
						

Particles

Create 100 000 particles.

var geometry = new THREE.Geometry();
for (var i = 0; i < 100000; i ++) {
  var vertex = new THREE.Vector3();
  vertex.x = 2000 * Math.random() - 1000;
  vertex.y = 2000 * Math.random() - 1000;
  vertex.z = 2000 * Math.random() - 1000;
  geometry.vertices.push(vertex);
}
material = new THREE.ParticleBasicMaterial({
  size: 3,
  sizeAttenuation: false,
  transparent: true
});
var particles = new THREE.ParticleSystem(geometry, material);
scene.add(particles);
                        

Particles

Change colors of particles

function changeColorParticles(time) {
  var h = (360 * (1.0 + time * 0.00009) % 360 ) / 360;
  material.color.setHSV(h, 1.0, 1.0);
}
                       

Great Examples

WebGL Beginner's Guide

Udacity - Online 3d graphics course!

References

Questions?

Thank you!

Velkommen til denne introduksjonstalken om WebGL. Me (Thomas og Eirik) og me e konsulenta i Bouvet, som dåkke ser. Grunnen til at me valgte å snakka om WebGL idag er todelt; 1. me var så heldig å jobbe med ein WebGL applikasjon (og andre kule teknologier) på et prosjekt hos ein kunde og 2. Da e kult. Før me fortsette her, så kunne eg tenkt meg å sjå kor mange av dåke som har 1. Hørt om WebGL 2. Jobba med WebGL - Ok, då håpe eg at dåkke blir (enda meir) trigga te å testa og hacke med WebGL etter denne talken her. Da eg syns e litt spesielt e at WebGL ikkje er hypa like mykje som mange andre nye teknologier for web, som f.eks. LocalStorage, WebThreads, WebSockets, WebRTC osv. Det kan jo hende at det har noe med at det har blitt forsøkt med 3D på webben omtrent siden den spede begynnelsen. (VRML 1995/1997), uten aldri å ha slått særlig an (trur eg). 3D er jo kult. Eller, det var kult i hvert fall. Og det som ein ofte kjennetegner med 3D og grafikk på webben før WebGL er jo noe sånt som dette: An Introduction 24.09.2015 Eirik Ola Aksnes | Thomas Johansen