SHADERS. Alexandre Blondin Massé Département d'informatique Université du Québec à Montréal 4 novembre 2015 INF5071 - Infographie

Documents pareils
M2-Images. Rendu Temps Réel - OpenGL 4 et compute shaders. J.C. Iehl. December 18, 2013

TPs Architecture des ordinateurs DUT Informatique - M4104c SUJETS. R. Raffin Aix-Marseille Université romain.raffin-at-univ-amu.fr

GPGPU. Cours de MII 2

Modélisation de la vision humaine

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

GMIN 330 Nancy Rodriguez

Chapitre 3 : Repères et positionnement 3D

Rendu temps réel de mer et de nuages

Synthèse d'images I. Venceslas BIRI IGM Université de Marne La

Canvas 3D et WebGL. Louis Giraud et Laetitia Montagny. 9 Avril Université Lyon 1

IFT3355: Infographie Sujet 6: shading 7 (illumination globale 4)

Introduction à MATLAB R

Application 1- VBA : Test de comportements d'investissements

TD : Codage des images

Rendu HDR et illumination par image

Faire de la 3D dans un navigateur web avec three.js. v Brouillon

TP : Gestion d une image au format PGM

PROJET DE MODELISATION CASERNE SERGEANT BLANDAN

Programmation en Java IUT GEII (MC-II1) 1

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

JPEG, PNG, PDF, CMJN, HTML, Préparez-vous à communiquer!

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Algorithmique et Programmation, IMA

ANICOTTE Guillaume GUFFROY Matthieu LIMA Juliette SALLOUH Chamsseddine CAHIER DES CHARGES SI 28

Les algorithmes de base du graphisme

COMPARAISONDESLANGAGESC, C++, JAVA ET

TP SIN Traitement d image

I. Introduction aux fonctions : les fonctions standards

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

EIP 2012 Projet Livepad. Documentation technique 1.5

Plan du cours Cours théoriques. 29 septembre 2014

Projet ISN - dossier réalisé par Randrianarimanana Stéphanie. Titre du projet : Site de rencontre. le nom de notre site de rencontre : Linkymeet


C est un mouvement plan dont la trajectoire est un cercle ou une portion de cercle. Le module du vecteur position OM est constant et il est égal au

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

RIE LE RENDU THEO. 2 e trim ÉTAPE DE FINITION BOÎTE DE DIALOGUE. remarques

Initiation à la programmation OEF pour Wims (exercices).

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

MATLAB : COMMANDES DE BASE. Note : lorsqu applicable, l équivalent en langage C est indiqué entre les délimiteurs /* */.

Serveur d'application Client HTML/JS. Apache Thrift Bootcamp

ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

INF2015 Développement de logiciels dans un environnement Agile. Examen intra 20 février :30 à 20:30

Cours Informatique Master STEP

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Bases Java - Eclipse / Netbeans

KL5121. Pour activer des sorties en fonction de la position d'un codeur

Hiver 2013 IMN 259. Introduction à l analyse d images. Par Pierre-Marc Jodoin

05/09/2015. M Ponctualité : CM TD TP & Projet Æ En cas d absence : récupérer!!! 3 05/09/2015

Recherche dans un tableau


Sujet. calculatrice: autorisée durée: 4 heures

Notions fondamentales du langage C# Version 1.0

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Projet Matlab/Octave : segmentation d'un ballon de couleur dans une image couleur et insertion d'un logo

Glossaire technique Veditec

Le programme détaillé. Salle A07 Salle A06 Salle A04. Initiation à DirectX. Création de Mods Minecraft

Théorie et codage de l information

Master IAD Module PS. Reconnaissance de la parole (suite) Alignement temporel et Programmation dynamique. Gaël RICHARD Février 2008

Ch.G3 : Distances et tangentes

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

L'instruction if permet d'exécuter des instructions différentes selon qu'une condition est vraie ou fausse. Sa forme de base est la suivante:

IMAGES NUMÉRIQUES MATRICIELLES EN SCILAB

Responsive Design. Technologies du web. Stéphane Bouvry, 2014

Fonctions de plusieurs variables

GL BE FLYER. Chef de projet de l équipe : SCIONICO Pierre

- un Sigma DP1 Quattro (

Livre Blanc WebSphere Transcoding Publisher

Par Daniel FAIVRE WebMapper ... Publication de cartes pour Internet avec ArcGis

Initiation à linfographie

TP Blender n 3 : Luxrender : Rendu d une scène d extérieur

Unity. Moteur de jeu 3D et 2D. Cross platform: Windows, Mac, Linux, ios, Android, Blackberry, Xbox, Playstation, Wii

Plus courts chemins, programmation dynamique

1. Structure d'un programme FORTRAN 95

Ecran : Processeur : OS : Caméra : Communication : Mémoire : Connectique : Audio : Batterie : Autonomie : Dimensions : Poids : DAS :

TP JAVASCRIPT OMI4 TP5 SRC

Compte-rendu de projet de Système de gestion de base de données

1/ Présentation de SQL Server :

Développement d un moteur de jeu vidéo pour la console Nintendo Wii U et portage d un jeu

3. SPÉCIFICATIONS DU LOGICIEL. de l'expression des besoins à la conception. Spécifications fonctionnelles Analyse fonctionnelle et méthodes

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Opérations de base sur ImageJ

INF6304 Interfaces Intelligentes

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Optimisation Discrète

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

NFA016 : Introduction. Pour naviguer sur le Web, il faut : Naviguer: dialoguer avec un serveur web

Chapitre 2 Devine mon nombre!

Freeway 7. Nouvelles fonctionnalités

Compléments de documentation Scilab : affichage de texte et formatage de nombres

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Chap III : Les tableaux

Analyse de la vidéo. Chapitre La modélisation pour le suivi d objet. 10 mars Chapitre La modélisation d objet 1 / 57

Algorithmique et programmation : les bases (VBA) Corrigé

6.4. Les Ombres Raytracées (Raytraced Shadows) Shading Lamp Shadow and Spot Hemi Spot Sun Sun Scene F10 Shadow Render Ray Ray Shadow Shadow and Spot

Transcription:

CHAPITRE 8 SHADERS Alexandre Blondin Massé Département d'informatique Université du Québec à Montréal 4 novembre 2015 INF5071 - Infographie

INTRODUCTION Les shaders sont des programmes qui indiquent à votre carte graphique comment dessiner chacun des pixels On distingue deux types de shaders : Les shaders de sommets (vertex shader); Les shaders de pixels (fragment shader ou pixel shader).

ORDRE DE TRAITEMENT 1. On traite d'abord les sommets (vertex shader); 2. Puis ensuite, on traite les autres pixels (fragment shader).

LES SHADERS DE SOMMETS Minimalement, un shader de sommet (vertex shader) a les caractéristiques suivantes : Entrée : la position du sommet courant; Sortie : la position finale du sommet. On peut également ajouter des informations à chaque sommet qui seront utilisées par le shader de pixels (couleur, coordonnée de texture, etc.)

LES SHADERS DE PIXELS Minimalement, un shader de pixels (fragment shader) a les caractéristiques suivantes : Entrée : la position du pixel courant; Sortie : la couleur du pixel courant. On peut utiliser certaines informations propres à chaque sommet qui auront été ajoutées par le shader de sommet.

LES VARIABLES DE SHADERS Lorsqu'on conçoit des shaders, il faut considérer les trois éléments suivants : Quelle information doit être contenue dans chaque sommet? Quelle information est constante, peu importe le sommet? Quelle information doit être ajoutées pour chaque sommet? Les shaders communiquent entre eux et avec l'application en utilisant trois types de variables : uniform; attribute et varying.

LE TYPE UNIFORM Les variables de type uniform sont celles qui sont constantes pour le shader de sommets et le shader de pixels. Quelques exemples : La position d'une ou plusieurs sources lumineuses; Une couleur uniforme pour un objet; L'intensité lumineuse ambiante; Une position importante (celle du joueur, du centre de la scène), etc.

LE TYPE ATTRIBUTE Les variables de type attribute sont des variables qui concernent les sommets seulement; Plusieurs sont fournis par défaut : La position du sommet; Sa couleur; Son vecteur normal; Des coordonnées de texture, etc. Il est également possible d'ajouter des attributs personnalisés, mais ce n'est pas toujours supporté.

LE TYPE VARYING C'est à l'aide de ces variables que les shaders de sommets et de pixels interagissent; On les déclare dans les deux shaders; Dans le shader de sommets, on écrit une certaine valeur; Dans le shader de pixels, cette valeur est interpolée à partir des sommets qui constituent le fragment. Quelques exemples : La couleur du pixel courant; La coordonnée de texture du pixel courant; L'intensité lumineuse, etc.

LE LANGAGE GLSL Le langage GLSL est celui qui doit être utilisé pour écrire des shaders; GLSL : OpenGL Shading Language; Il s'agit d'un langage similaire à C; Il fournit certains types par défaut ainsi que de nombreuses fonctions.

SHADER DE VERTEX uniform mat4 gl_modelviewmatrix; // Matrice vue-modèle uniform mat4 gl_projectionmatrix; // Matrice de projection // Variables prédéfinies : // gl_vertex (entrée) : position du sommet courant // gl_position (sortie) : position finale du sommet void main() { gl_position = gl_projectionmatrix * gl_modelviewmatrix * gl_vertex; } Chaque sommet est transformé selon les matrices modèle-vue et projective; Le nom des matrices varie selon le contexte (OpenGL, three.js, etc.). On peut remplacer la ligne par gl_position = gl_projectionmatrix * gl_modelviewmatrix * gl_vertex; gl_position = gl_modelviewprojectionmatrix * gl_vertex;

SHADER DE PIXELS // Variables prédéfinies : // gl_fragcoord (entrée) : position du fragment courant // gl_fragcolor (sortie) : couleur du fragment void main() { gl_fragcolor = vec4(0.4, 0.4, 0.8, 1.0); // On n'utilise pas la position } On précise la couleur dans le système RGBA.

TYPES DE DONNÉES Scalaires bool, int, float, double; Vecteurs bvec2, ivec2, vec2, dvec2, bvec3, ivec3, vec3, dvec3, bvec4, ivec4, vec4, dvec4 Matrices mat2, mat3, mat4, mat2x3, mat2x4, mat3x4 On peut également définir des tableaux, des structures, etc. comme en C.

CONVERSIONS ET CONSTRUCTIONS Il est possible de passer d'un type à l'autre de façon flexible; Les composantes des vecteurs sont accessibles via les attributs xyzw, rgba (couleurs) ou stpq (textures); On peut même construire des vecteurs! Par exemple, si v est de type vec4, alors v.xyx est de type vec3 avec composantes. (x, y, x) On peut passer d'une dimension vectorielle à une autre facilement : vec3 v1 = vec3(1.0); // Crée le vecteur (1, 1, 1) vec4 v2 = vec3(vec2(1.0, 2.0), 3.0); // Crée le vecteur (1, 2, 3) mat4 m1 = mat4(v1, v2, v3, v4); // Si v1, v2, v3, v4 sont de type vec4

FONCTIONS STANDARDS Le langage GLSL offre de nombreuses fonctions mathématiques par défaut; Les fonctions min et max; Les fonctions trigonométriques; Des fonctions logiques any et all; Une fonction d'interpolation mix; Les fonctions ceil et floor; Les produits scalaire et vectoriel; Les fonctions modulo (mod) et partie fractionnaire (frac); La normalisation de vecteurs (normalize); Des fonctions de bruit (noise), etc.

SHADERS 2D Familiarisons-nous d'abord avec les shaders de pixels en 2D; Dans ce cas, on s'intéresse principalement aux fragment shaders; Un outil est intéressant pour effectuer différents tests se trouve à https://www.shadertoy.com

GRILLE Comment peut-on dessiner une grille de ligne et de colonnes; L'arrière-plan sera blanc et les lignes de la grille seront noires; Nous allons utiliser les coordonnées d'écran normalisées (c'est-àdire entre et ); 1 1 On doit se fixer une certaine épaisseur de ligne et l'épaisseur après normalisation; Alors un pixel dans le système normalisé sera dessiné en (x, y) x mod C L = 1.0/l noir si ou, où et. blanc sinon. E. x y mod L. y l c E E E C = 1.0/c

CODE float NUM_COLS = 25.0; float NUM_ROWS = 18.0; float LINE_WIDTH = 1.0; void mainimage(out vec4 fragcolor, in vec2 fragcoord) { vec2 uvwidth = LINE_WIDTH / iresolution.xy; vec2 uv = fragcoord.xy / iresolution.xy; if (mod(uv.x + 0.5 * uvwidth.x, 1.0 / NUM_COLS) <= uvwidth.x mod(uv.y + 0.5 * uvwidth.y, 1.0 / NUM_ROWS) <= uvwidth.y) { fragcolor = vec4(0.0, 0.0, 0.0, 1.0); } else { fragcolor = vec4(1.0, 1.0, 1.0, 1.0); } }

CALCUL VECTORIEL De nombreux bouts de code peuvent être compactés si on utilise le calcul vectoriel Par exemple, les lignes float NUM_COLS = 25.0; float NUM_ROWS = 18.0; if (mod(uv.x + 0.5 * uvwidth.x, 1.0 / numcols) <= uvwidth.x mod(uv.y + 0.5 * uvwidth.y, 1.0 / numrows) <= uvwidth.y) peuvent être remplacées par vec2 DIMENSIONS = vec2(25.0, 18.0); if (any(lessthan(mod(uv + 0.5 * uvwidth, 1.0 / dimensions), uvwidth)))

DÉGRADÉ RADIAL Étudions la façon de réaliser un dégradé radial; Les paramètres à considérer sont les suivants : Le centre du cercle (type vec2); Le rayon du cercle (type float); La couleur intérieure (type vec4); La couleur extérieure (type vec4). Il suffit ensuite de calculer la distance entre le pixel courant et le centre du cercle (fonction distance de GLSL);

CODE vec2 CENTER = vec2(0.5, 0.5); float RADIUS = 0.4; vec4 COLOR_IN = vec4(1.0, 1.0, 0.0, 1.0); vec4 COLOR_OUT = vec4(0.0, 1.0, 1.0, 1.0); void mainimage(out vec4 fragcolor, in vec2 fragcoord) { vec2 uv = fragcoord.xy / iresolution.xy; float level = 1.0 - min(distance(uv, CENTER) / RADIUS, 1.0); fragcolor = COLOR_IN * level + COLOR_OUT * (1.0 - level); }

LA FONCTION MIX L'interpolation linéaire est tellement fréquente qu'il existe une fonction de GLSL qui la calcule; On peut donc remplacer la ligne par fragcolor = COLOR_IN * level + COLOR_OUT * (1.0 - level); fragcolor = mix(color_out, COLOR_IN, level);

EXERCICE Écrivez un petit programme GLSL qui anime le déplacement d'un point noir sur un cercle bleu. Vous devez laisser la possibilité de paramétrer les quantités suivantes : Le centre et le rayon du cercle; La vitesse angulaire (en pixel par seconde); La taille du point. Je vous rappelle que la variable iglobaltime contient le temps présent en secondes.

THREE.JS Dans three.js, il est possible de définir ses propres shaders :

CRÉATION D'UNE SPHÈRE // Variables globales var scene; var camera; var distance = 15; // Initialisation de la scène initializescene(); // Animation de la scène animatescene(); function initializescene(){ // Initialisation du canvas renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setclearcolor(0x000000, 1); canvaswidth = 800; canvasheight = 600; renderer.setsize(canvaswidth, canvasheight); document.getelementbyid("canvas").appendchild(renderer.domelement); // Initialisation de la scène et de la caméra scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, canvaswidth / canvasheight, 1, 1000); camera.position.set(0, distance Voir / 2, le distance); résultat camera.lookat(scene.position); scene.add(camera); // De la lumière var ambientlight = new THREE.AmbientLight(0x888888); scene.add(ambientlight); var directionallight = new THREE.DirectionalLight(0xcccccc, 1); directionallight.position.set(5, 3, 5); scene.add(directionallight);

APPLICATION DE TEXTURES // Variables globales var scene; var camera; var distance = 15; // Initialisation de la scène initializescene(); // Animation de la scène animatescene(); function initializescene(){ // Initialisation du canvas renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setclearcolor(0x000000, 1); canvaswidth = 800; canvasheight = 600; renderer.setsize(canvaswidth, canvasheight); document.getelementbyid("canvas").appendchild(renderer.domelement); // Initialisation de la scène et de la caméra scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, canvaswidth / canvasheight, 1, 1000); camera.position.set(0, distance Voir / 2, le distance); résultat camera.lookat(scene.position); scene.add(camera); // De la lumière var ambientlight = new THREE.AmbientLight(0x888888); scene.add(ambientlight); var directionallight = new THREE.DirectionalLight(0xcccccc, 1); directionallight.position.set(5, 3, 5); scene.add(directionallight);

APPLICATION D'UN SHADER (HTML) <!DOCTYPE html> <html> <head> <title>application d'une texture sur une sphère</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/style.css"> <script src="js/three.js"></script> <script id="shader-fs" type="x-shader/x-fragment"> void main() { gl_fragcolor = vec4(0.0, 1.0, 1.0, 1.0); } </script> <script id="shader-vs" type="x-shader/x-vertex"> void main() { gl_position = projectionmatrix * modelviewmatrix * vec4(position, 1.0); } </script> </head> <body> <div id="canvas"></div> <script src="js/main.js"></script> </body> </html>

APPLICATION D'UN SHADER (JAVASCRIPT) // Variables globales var scene; var camera; var distance = 15; // Initialisation de la scène initializescene(); // Animation de la scène animatescene(); function initializescene(){ // Initialisation du canvas renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setclearcolor(0x000000, 1); canvaswidth = 800; canvasheight = 600; renderer.setsize(canvaswidth, canvasheight); document.getelementbyid("canvas").appendchild(renderer.domelement); // Initialisation de la scène et de la caméra scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, canvaswidth / canvasheight, 1, 1000); camera.position.set(0, distance Voir / 2, le distance); résultat camera.lookat(scene.position); scene.add(camera); // De la lumière var ambientlight = new THREE.AmbientLight(0x888888); scene.add(ambientlight);

LUMIÈRE (HTML) <!DOCTYPE html> <html> <head> <title>application d'une texture sur une sphère</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/style.css"> <script src="js/three.js"></script> <script id="shader-fs" type="x-shader/x-fragment"> varying vec3 vnormal; vec3 light = normalize(vec3(0.5, 0.2, 1.0)); void main() { float dprod = max(0.0, dot(vnormal, light)); gl_fragcolor = vec4(0.0, dprod, dprod, 1.0); } </script> <script id="shader-vs" type="x-shader/x-vertex"> varying vec3 vnormal; void main() { vnormal = normal; gl_position = projectionmatrix * modelviewmatrix * vec4(position, 1.0); } </script> </head> <body> <div id="canvas"></div> <script src="js/main.js"></script> </body> </html>

LUMIÈRE (JAVASCRIPT) // Variables globales var scene; var camera; var distance = 15; // Initialisation de la scène initializescene(); // Animation de la scène animatescene(); function initializescene(){ // Initialisation du canvas renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setclearcolor(0x000000, 1); canvaswidth = 800; canvasheight = 600; renderer.setsize(canvaswidth, canvasheight); document.getelementbyid("canvas").appendchild(renderer.domelement); // Initialisation de la scène et de la caméra scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, canvaswidth / canvasheight, 1, 1000); camera.position.set(0, distance Voir / 2, le distance); résultat camera.lookat(scene.position); scene.add(camera); // De la lumière var ambientlight = new THREE.AmbientLight(0x888888); scene.add(ambientlight); var directionallight = new THREE.DirectionalLight(0xcccccc, 1); directionallight.position.set(5, 3, 5); scene.add(directionallight);

DÉPLACEMENT (HTML) <!DOCTYPE html> <html> <head> <title>application d'une texture sur une sphère</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/style.css"> <script src="js/three.js"></script> <script id="shader-fs" type="x-shader/x-fragment"> varying vec3 vnormal; vec3 light = normalize(vec3(0.5, 0.2, 1.0)); void main() { float dprod = max(0.0, dot(vnormal, light)); gl_fragcolor = vec4(0.0, dprod, dprod, 1.0); } </script> <script id="shader-vs" type="x-shader/x-vertex"> attribute float displacement; varying vec3 vnormal; void main() { vnormal = normal; vec3 newposition = position + normal * vec3(displacement); gl_position = projectionmatrix * modelviewmatrix * vec4(newposition, 1.0); } </script> </head> <body> <div id="canvas"></div> <script src="js/main.js"></script> </body> </html>

DÉPLACEMENT (JAVASCRIPT) // Variables globales var scene; var camera; var distance = 15; // Initialisation de la scène initializescene(); // Animation de la scène animatescene(); function initializescene(){ // Initialisation du canvas renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setclearcolor(0x000000, 1); canvaswidth = 800; canvasheight = 600; renderer.setsize(canvaswidth, canvasheight); document.getelementbyid("canvas").appendchild(renderer.domelement); // Initialisation de la scène et de la caméra scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, canvaswidth / canvasheight, 1, 1000); camera.position.set(0, distance Voir / 2, le distance); résultat camera.lookat(scene.position); scene.add(camera); // De la lumière var ambientlight = new THREE.AmbientLight(0x888888); scene.add(ambientlight); var directionallight = new THREE.DirectionalLight(0xcccccc, 1); directionallight.position.set(5, 3, 5); scene.add(directionallight);

ANIMATION (HTML) <!DOCTYPE html> <html> <head> <title>application d'une texture sur une sphère</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/style.css"> <script src="js/three.js"></script> <script id="shader-fs" type="x-shader/x-fragment"> varying vec3 vnormal; vec3 light = normalize(vec3(0.5, 0.2, 1.0)); void main() { float dprod = max(0.0, dot(vnormal, light)); gl_fragcolor = vec4(0.0, dprod, dprod, 1.0); } </script> <script id="shader-vs" type="x-shader/x-vertex"> uniform float amplitude; attribute float displacement; varying vec3 vnormal; void main() { vnormal = normal; vec3 newposition = position + normal * vec3(amplitude * displacement); gl_position = projectionmatrix * modelviewmatrix * vec4(newposition, 1.0); } </script> </head> <body> <div id="canvas"></div> <script src="js/main.js"></script> </body> </html>

ANIMATION (JAVASCRIPT) // Variables globales var scene; var camera; var distance = 15; var uniforms; // Initialisation de la scène initializescene(); // Animation de la scène animatescene(); function initializescene(){ // Initialisation du canvas renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setclearcolor(0x000000, 1); canvaswidth = 800; canvasheight = 600; renderer.setsize(canvaswidth, canvasheight); document.getelementbyid("canvas").appendchild(renderer.domelement); // Initialisation de la scène et de la caméra scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, Voir le résultat canvaswidth / canvasheight, 1, 1000); camera.position.set(0, distance / 2, distance); camera.lookat(scene.position); scene.add(camera); // De la lumière var ambientlight = new THREE.AmbientLight(0x888888); scene.add(ambientlight); var directionallight = new THREE.DirectionalLight(0xcccccc, 1); directionallight.position.set(5, 3, 5);