Enseignant du Cours:
DJAFER BADDOU (PhD)
Courriel: djafer.baddou@uqo.ca
Programmation 2D/3D
INF 1483
Lumière et formation d’images
2
Programmation 2D/3D:
INF 1483
Introduction à l’Infographie
Formation d’Images
La lumière provenant de la
source frappe certains cotés
d’un objet, et une portion
de la lumière réfléchie entre
dans la caméra à travers sa
lentille.
L’interaction entre l’objet et
la lumière de la source
détermine combien de
lumière réfléchie va entrer
dans la caméra.
Spectre Électromagnétique
3
Programmation 2D/3D:
INF 1483
Introduction à l’Infographie
Formation d’Images
Le spectre électromagnétique
inclue les ondes radio,
infrarouge (chaleur), et une
portion du spectre visible
(ondes perçues par le système
de vision humain).
Le spectre visible comprend les
ondes de longueurs entre 350
et 780 nanomètres (1 nm = 10
-
9
m). Cet intervalle est appelé:
le spectre visible (ou la
lumière).
Spectre des fréquences de couleurs visibles
Spectre Électromagnétique
4
Programmation 2D/3D:
INF 1483
Introduction à l’Infographie
Formation d’Images
Une source lumineuse aura la
couleur déterminée par
l’énergie qu’elle émet dans
les différentes ondes. Par
exemple:
 Les ondes autours de
520 nm sont perçues vert.
 Les ondes autours de
450 nm sont perçues bleu.
 Les ondes autours de
650 nm sont perçues rouge.
Spectre des fréquences de couleurs visibles
Système de formation d’images
5
Programmation 2D/3D:
INF 1483
Introduction à l’Infographie
Formation d’Images
Longueur Focal, Champs (Angle) de
Vision
Similaire au réelle camera, le virtuelle
camera a besoin d’un mécanisme de
controller la scene a partir de different
perspective.
A partir de la camera pinhole qui va être
notre camera modèle, on va étudier ce
mécanisme de contrôle.
Caméra Pinhole
Contenu
Introduction
Mathématiques
de l’infographie
Notions de
Mathématiques
Transformations
Géométriques
Effets Optiques
et Rendu
Effet de Lumière
sur les Objets
Techniques
d'animation et
simulation 2D/3D
Introduction à
l’Infographie
Introduction à
OpenGL
IDE en OpenGL
Programmation 2D/3D: INF 1483
Applications
OpenGL
Applications
OpenGL
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Phong shading
model
Fortunately, human eyes
don't require perfect
physical accuracy,
especially not for fast-
moving animated graphics,
and real-time computer
graphics has come a long
way rendering impressive
graphics on typical
consumer hardware using
cheap tricks that
approximate the behavior
of light without simulating it
perfectly.
Phong shading model
Physically accurate light
simulation requires expensive
algorithms that have only recently
become possible for even high-
end computer clusters to calculate
in real time.
Phong shading model
The most fundamental of these tricks
is the Phong shading model.
 Phong shading model is an
inexpensive approximation of how
light interacts with simple
materials.
 Phong shading model is
developed by computer graphics
pioneer Bui Tuong Phong in the
early 1970s.
 Rentrer dans les détails de la théorie
derrière la simulation de l'éclairage
3D est assez loin du sujet de cet
article mais il vaut mieux en
connaitre un minimum le sujet. Au
lieu de rentrer dans le vif du sujet ici,
jetez un coup d’œil sur l'ombrage de
Simuler l'éclairage et les ombres en 3D
Simuler l'éclairage et les ombres en 3D
Ambient light (Lumière Ambiante) est la lumière qui imprègne, qui
se répand sur la scène. Elle n'a pas de direction et s'applique sur
toutes les faces de la scène de la même façon.
Directional light (Lumière Directionnelle) est une lumière émise
depuis une direction spécifique(pas de position ). Par exemple le
soleil, est une lumière directionnelle.
Point light (Point de lumière) est une lumière émise depuis un
point, émettant une lumière dans toutes les directions,
contrairement à la Lumière Directionnelle. C'est comme ceci que les
lumières fonctionnent principalement dans notre monde, comme
par exemple une ampoule.
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
8
Il y a trois types basiques d'éclairage :
1. Ambient light (Lumière Ambiante)
2. Directional light (Lumière Directionnelle)
3. Point light (Point de lumière)
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Phong shading model
 Because of this, Phong
shading alone cannot
calculate effects that involve
the influence of other
objects in a scene, such as
shadows and mirror
reflections.
 This is why the flag casts no
shadow on the ground or
wall behind it.
Phong shading model
 Phong shading is a local
illumination simulation
—it only considers the
direct interaction
between a light source
and a single point.
The Phong model involves three
different lighting terms:
 ambient reflection, a constant
term that simulates the
background level of light;
 diffuse reflection, which gives the
material what we usually think of
as its color and;
 specular reflection, the shine of
polished or metallic surfaces.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient
reflection
its darkest when it's perpendicular
to the light. Curved surfaces
behave the same way; if you roll
up or crumple the paper, its
surface will be brightest where it
faces the light the most directly.
Overview of
the flag program
However, the setup and
rendering are a bit more
involved than last time.
Let's look at what's new and
changed:
Diffuse and ambient
reflection
If you hold a flat sheet of paper
up to a lamp in a dark room, it
will appear brightest when it
faces the lamp head-on, and
appear dimmer as you rotate it
away from the light, reaching
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient
reflection
Likewise, in the flag demo, if you
drag the view with the mouse, you
can see the flag's shading
remains the same. The surface
reflects light evenly in every
direction, or "diffusely." This basic
lighting effect is thus
called diffuse reflection.
Diffuse and ambient
reflection
The wider the angle between
the surface normal and the
light direction, the darker the
paper appears.
Diffuse and ambient
reflection
If the paper and light remain
stationary but you move your
head, the paper's apparent color
and brightness won't change.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient
reflection
if zero, they're perpendicular; and if
negative one, they face exact
opposite directions.
Positive dot products indicate acute
angles while negative dot products
indicate obtuse angles.
Diffuse and ambient
reflection
There's an inexpensive
operation called the dot
product that produces a
scalar value from two
vectors related to the angle
Diffuse and ambient
reflection
Given two unit vectors u and v, if
their dot product u · v (pronounced
"u dot v") is one, then the vectors
face the exact same direction;
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient
reflection
or in other words, the closer the dot
product of their normal and the
light's direction gets to one.
Perpendicular or back-facing
surfaces reflect no light, and their dot
product will be zero or negative.
Diffuse and ambient
reflection
GLSL provides a
function dot(u,v) to calculate
the dot product of two same-
sized vec values.
Diffuse and ambient
reflection
The dot product's behavior follows
that of diffuse reflection:
surfaces reflect more light the
more parallel to a light source
they become,
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient
reflection
Phong shading uses Lambertian
reflectance to model diffuse
reflection, taking the dot product of
the surface normal and the
direction from the surface to the
light source.
Diffuse and ambient
reflection
This relationship between
the dot product and diffuse
brightness was first
observed by 18th-century
physicist Johann Lambert.
Diffuse and ambient
reflection
This is referred to
as Lambertian reflectance,
and surfaces that exhibit the
behavior are called Lambertian
surfaces.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient
reflection
(Multiplying two color values involves
multiplying their corresponding red,
green, blue, and alpha components
together, which is what
GLSL's * operator does when given
two vec4s.)
Diffuse and ambient
reflection
If the dot product is
greater than zero:
Diffuse and ambient
reflection
 This product is multiplied by the
diffuse color of the light, and
 the result is multiplied with the
surface diffuse color.
 The final is the shaded result.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient reflection
In any enclosed area, there will
be a certain amount of ambient
reflection bouncing around,
dimly illuminating areas that the
light sources don't directly hit.
Diffuse and ambient
reflection
If the dot product is zero or
negative, the diffuse color
will be zero.
Diffuse and ambient
reflection
However, in the real world,
even when a surface isn't
directly lit, it still won't
appear pitch black.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Diffuse and ambient reflection
The sum of ambient and diffuse
effect colors is then multiplied
by the surface's diffuse color to
give the shaded result.
Diffuse and ambient
reflection
The Phong model simulates
the ambient effect by
assigning light sources a
constant ambient color.
Diffuse and ambient
reflection
This ambient color gets
added to the light's diffuse
color after it's been
multiplied by the dot
product.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Specular reflection
You can see this simulated in
the flag demo by looking at the
flagpole: as you drag the view up
and down, the gold sheen moves
along the pole with you.
Specular reflection
Not all surfaces reflect light
uniformly;
many materials, including
metals, glass, hair, and skin,
have a reflective sheen.
Specular reflection
Unlike with diffuse reflection, if the
viewer moves while a light source
and shiny object remain stationary,
the shine will move along the surface
with the viewer.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Specular reflection
The specular effect is caused by
reflection from the light source to the
viewer, so Phong shading simulates
the specular effect by reflecting the
light direction around the surface
normal to give a reflection direction.
Specular reflection
Physically, an object appears
shiny when its surface is
covered in highly
reflective microfacets.
Specular reflection
These facets face every direction,
creating a bright shiny spot where
the light source reflects directly
toward the viewer.
This effect is called specular
reflection.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Specular reflection
The dropoff is sharper
for more polished
surfaces, giving a
smaller, tighter specular
highlight.
Specular reflection
We can then take the dot
product of the reflection
direction and the direction
from the surface to the
viewer.
Specular reflection
Microfacets on a specular surface
follow a normal distribution: a
plurality of facets lie parallel to the
surface, and there is an exponential
dropoff in the number of facets at
steeper angles from the surface.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Specular reflection
 the specular colors of the light:
 source and
 surface,
 and the result added to the
diffuse and ambient colors to
give the final color.
Specular reflection
Phong shading approximates
this distribution by raising the
dot product to an exponent
called the shininess factor,
with:
Specular reflection
 higher shininess giving a
more polished shine and
 lower factors giving a more
diffuse sheen.
 This final specular factor
is then multiplied by:
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Specular reflection
Specular reflection
Non-specular surfaces have
a transparent specular color
with red, green, blue, and
alpha components set to
zero,
Specular reflection
which eliminates the specular
term from the shading equation.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing
Phong shading in
GLSL
La première chose à
comprendre à propos
du Dynamic pipeline
de WebGL et OpenGL
moderne est
contrairement au
pipeline fixe
d’OpenGL, la pipeline
dynamique moderne
d’OpenGL et de
WebGL n'a pas de
support pour
l'éclairage. Vous avez
à le faire par vous
même.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading
in GLSL
 Most objects in the real world, have
smooth curving surfaces, but
graphics cards deal with triangles.
 To render these objects, we have to
approximate their surfaces as a
collection of triangles.
 We do this by filling a vertex array
with vertices placed along its
surface, storing attributes of the
surface with each vertex, and
 connecting the samples into triangles
using the element array
 to give an approximation of the
original surface.
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong shading
in GLSL
stores for each vertex are:
1. its position in world space
and
2. its normal, a vector
perpendicular to the original
surface.
 The normal is fundamental
to shading calculations, as
we'll see shortly.
 Normals should be unit
vectors, that is, vectors
whose length is one.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat texcoord[2];
GLfloat shininess;
GLubyte specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong
shading in GLSL
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong shading
in GLSL
Each vertex also
has material parameters that
indicate how the surface is
shaded.
The material can consist of a:
1. set of per-vertex values,
2. texture coordinates that
sample material information
from a texture, or
3. some combination of both.
the material consists of
a texture coordinate for
sampling
the diffuse color from the mesh
texture,
a specular color, and
Implementing Phong
shading in GLSL
We'll see how these
parameters are used shortly.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat texcoord[2];
GLfloat shininess;
GLubyte specular[4];
};
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong shading
in GLSL
Although the position and
normal are three-dimensional
vectors, we pad them out to
four elements
because most GPUs prefer to
load vector data from 128-bit-
aligned buffers, like SIMD
instruction sets such as SSE.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat texcoord[2];
GLfloat shininess;
GLubyte specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong
shading in GLSL
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
Shading calculations are
usually performed in the
vertex and fragment
shaders, where they can
leverage the GPU's parallel
processing power.
Implementing
Phong
shading in
GLSL
This is where the
term "shader" for
GPU programs
comes from.
Let's bring back
the graphics
pipeline diagram
to get an
overview of the
Phong shading
dataflow:
The pipeline revisited
 Pour notre tutorial,
nous allons
réutiliser notre
précédent exemple
avec le cube en
rotation.
For this chapter,
we'll render the
image on the right
by implementing
the Phong
shading model,
The pipeline revisited
which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Implementing Phong shading in GLSL
with Phong Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
For the best accuracy, we
perform shading at a per-
fragment level.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing
Phong shading
in GLSL
For better
performance,
shading can also
be done in the
vertex shader and
the results
interpolated
between vertices,
but this will lead to
less accurate
shading, especially
for specular effects.
Simuler l'éclairage et les ombres en 3D
Créer les normales pour les sommets
 La première chose
dont nous avons
besoin, est de
générer le tableau
des normales pour
tous les sommets
que constituent
notre cube.
 Comme un cube est
un simple objet,
c'est plutôt simple à
faire,
 évidemment pour
des objets plus
complexe, calculer
les normales sera
plus compliqué.
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
29
 Pour notre tutorial, nous allons simplifier le model d'éclairage, en
considérant seulement une unique lumière directionnelle et une
lumière ambiante. Nous allons réutiliser notre précédent exemple
avec le cube en rotation.
 Une fois que nous avons appréhendé le concept de source et de
réflexion de la lumière, il y a deux choses que nous avons besoin
d'implémenter pour nos lumières directionnelles.
1. Nous avons besoin d'associer la surface normale avec chaque
sommet.
 C'est un vecteur qui est perpendiculaire à la face associé à ce
sommet.
2. Nous avons besoin de connaître la direction dans laquelle la
lumière arrive.
 Ceci est défini par la direction du vecteur.
 Puis nous mettons à jour le vertex shader pour ajuster la couleur
de chaque sommet en prenant en compte la lumière ambiante
ainsi que l'effet de la lumière directionnelle donné par l'angle qui
rencontre la face du cube.
 Nous allons voir comment faire avec les shaders.
// Left
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -
1.0, 0.0, 0.0, -1.0, 0.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER
, new WebGLFloatArray(
vertexNormals),gl.STATIC_DRAW);
cubeVerticesNormalBuffer
= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_B
UFFER,
cubeVerticesNormalBuffer
);
var vertexNormals = [
// Front
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
Ceci doit vous être plutôt
familier maintenant.
Nous créons un nouveau
buffer,
on le lie avec le tableau sur
lequel nous allons travailler,
puis nous allons envoyer
l'ensemble de notre tableau au
buffer en appelant la méthode
bufferData().
The pipeline revisited
Overview of
the cube program
 Pour notre tutorial, nous
allons réutiliser notre
précédent exemple avec
le cube en rotation.
For this chapter, we'll
render the image on the
right by implementing
the Phong
shading model,
which will serve as the
basis for more
advanced effects we'll
look at later on.
Pour notre tutorial, nous
allons simplifier le model
d'éclairage, en
considérant seulement
une unique lumière
directionnelle et une
The pipeline revisited
Overview of the cube program
 Une fois que nous avons appréhendé le
concept de source et de réflexion de la
lumière, il y a deux choses que nous avons
besoin d'implémenter pour nos lumières
directionnelles.
1. Nous avons besoin d'associer la surface
normale avec chaque sommet.
 C'est un vecteur qui est
perpendiculaire à la face associé à
ce sommet.
2. Nous avons besoin de connaître la
direction dans laquelle la lumière arrive.
 Ceci est défini par la direction du
vecteur.
3. pour ajuster la couleur de
chaque sommet en prenant en
compte la lumière ambiante
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Mesh construction
When we render, we
set
up glVertexAttribPoi
nters to pass all of
the flag_vertex attrib
utes to the vertex
shader:
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
static void render_mesh (struct
flag_mesh const *mesh ) {
glBindTexture(GL_TEXTURE_2D
, mesh->texture);
glBindBuffer(GL_ARRAY_BUFFE
R, mesh->vertex_buffer);
glVertexAttribPointer(
g_resources.flag_program.attribu
tes.position, 3, GL_FLOAT,
GL_FALSE, sizeof ( struct
flag_vertex), (void*) offsetof (
struct flag_vertex, position) );
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
The pipeline revisited
Overview of
the cube program
 Pour notre tutorial, nous
allons réutiliser notre
précédent exemple avec
le cube en rotation.
For this chapter, we'll
render the image on the
right by implementing
the Phong
shading model,
which will serve as the
basis for more
advanced effects we'll
look at later on.
Pour notre tutorial, nous
allons simplifier le model
d'éclairage, en
considérant seulement
une unique lumière
directionnelle et une
The pipeline revisited
Overview of the cube program
 Une fois que nous avons appréhendé le
concept de source et de réflexion de la
lumière, il y a deux choses que nous avons
besoin d'implémenter pour nos lumières
directionnelles.
1. Nous avons besoin d'associer la surface
normale avec chaque sommet.
 C'est un vecteur qui est
perpendiculaire à la face associé à
ce sommet.
2. Nous avons besoin de connaître la
direction dans laquelle la lumière arrive.
 Ceci est défini par la direction du
vecteur.
3. pour ajuster la couleur de
chaque sommet en prenant en
compte la lumière ambiante
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Mesh construction
When we render, we
set
up glVertexAttribPoint
ers to pass all of
the flag_vertex attribu
tes to the vertex
shader:
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
static void render_mesh (struct
flag_mesh const *mesh ) {
glBindTexture(GL_TEXTURE_2D
, mesh->texture);
glBindBuffer(GL_ARRAY_BUFFE
R, mesh->vertex_buffer);
glVertexAttribPointer(
g_resources.flag_program.attribu
tes.position, 3, GL_FLOAT,
GL_FALSE, sizeof ( struct
flag_vertex), (void*) offsetof (
struct flag_vertex, position) );
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
The pipeline revisited The pipeline revisited
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
When we
render, we set
up glVertexAttr
ibPointers to
pass all of
the flag_vertex
attributes to
the vertex
shader:
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
glVertexAttribPointer(
g_resources.flag_program.attribu
tes.normal, 3, GL_FLOAT,
GL_FALSE, sizeof ( struct
flag_vertex), (void*)offsetof(
struct flag_vertex, normal) );
glVertexAttribPointer(
g_resources.flag_program.attribu
tes.texcoord, 2, GL_FLOAT,
GL_FALSE, sizeof(struct
flag_vertex), (void*)offsetof(struct
flag_vertex, texcoord) );
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Overview of
the cube program
 Pour notre tutorial, nous
allons réutiliser notre
précédent exemple avec
le cube en rotation.
For this chapter, we'll
render the image on the
right by implementing
the Phong
shading model,
which will serve as the
basis for more
advanced effects we'll
look at later on.
Pour notre tutorial, nous
allons simplifier le model
d'éclairage, en
considérant seulement
une unique lumière
directionnelle et une
Overview of the cube program
 Une fois que nous avons appréhendé le
concept de source et de réflexion de la
lumière, il y a deux choses que nous avons
besoin d'implémenter pour nos lumières
directionnelles.
1. Nous avons besoin d'associer la surface
normale avec chaque sommet.
 C'est un vecteur qui est
perpendiculaire à la face associé à
ce sommet.
2. Nous avons besoin de connaître la
direction dans laquelle la lumière arrive.
 Ceci est défini par la direction du
vecteur.
3. pour ajuster la couleur de chaque
sommet en prenant en compte la
lumière ambiante ainsi que l'effet de la
lumière directionnelle donné par l'angle
The pipeline revisited The pipeline revisited
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Note that
the glVertexAttribPointer call for
the specular color attribute
passes GL_TRUE for
the normalized argument.
The specular colors are stored as
four-component arrays of bytes
between 0 and 255, much as
they would be in a bitmap image,
but with the normalized flag set,
they'll be presented to the
shaders as normalized floating-
point values
between 0.0 and 1.0.
glVertexAttribPointer(
g_resources.flag_program.attribu
tes.shininess, 1, GL_FLOAT,
GL_FALSE, sizeof(struct
flag_vertex), (void*)offsetof(struct
flag_vertex, shininess) );
glVertexAttribPointer(
g_resources.flag_program.attribu
tes.specular, 4,
GL_UNSIGNED_BYTE,
GL_TRUE, sizeof(struct
flag_vertex), (void*)offsetof(struct
flag_vertex, specular) );
Overview of
the cube program
 Pour notre tutorial, nous
allons réutiliser notre
précédent exemple avec
le cube en rotation.
For this chapter, we'll
render the image on the
right by implementing
the Phong
shading model,
which will serve as the
basis for more
advanced effects we'll
look at later on.
Pour notre tutorial, nous
allons simplifier le model
d'éclairage, en
considérant seulement
une unique lumière
directionnelle et une
Overview of the cube program
 Une fois que nous avons appréhendé le
concept de source et de réflexion de la
lumière, il y a deux choses que nous avons
besoin d'implémenter pour nos lumières
directionnelles.
1. Nous avons besoin d'associer la surface
normale avec chaque sommet.
 C'est un vecteur qui est
perpendiculaire à la face associé à
ce sommet.
2. Nous avons besoin de connaître la
direction dans laquelle la lumière arrive.
 Ceci est défini par la direction du
vecteur.
3. pour ajuster la couleur de
chaque sommet en prenant en
compte la lumière ambiante
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
The pipeline revisited The pipeline revisited
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Mesh
construction
When we
render, we set
up glVertexAttri
bPointers to
pass all of
the flag_vertex
attributes to the
vertex shader:
glBindBuffer(GL_ELEMENT_AR
RAY_BUFFER, mesh-
>element_buffer);
glDrawElements(
GL_TRIANGLES, mesh-
>element_count,
GL_UNSIGNED_SHORT,
(void*)0 );
}// render( )
Overview of
the cube program
 Pour notre tutorial, nous
allons réutiliser notre
précédent exemple avec
le cube en rotation.
For this chapter, we'll
render the image on the
right by implementing
the Phong
shading model,
which will serve as the
basis for more
advanced effects we'll
look at later on.
Pour notre tutorial, nous
allons simplifier le model
d'éclairage, en
considérant seulement
une unique lumière
directionnelle et une
Overview of the cube program
 Une fois que nous avons appréhendé le
concept de source et de réflexion de la
lumière, il y a deux choses que nous avons
besoin d'implémenter pour nos lumières
directionnelles.
1. Nous avons besoin d'associer la surface
normale avec chaque sommet.
 C'est un vecteur qui est
perpendiculaire à la face associé à
ce sommet.
2. Nous avons besoin de connaître la
direction dans laquelle la lumière arrive.
 Ceci est défini par la direction du
vecteur.
3. pour ajuster la couleur de
chaque sommet en prenant en
compte la lumière ambiante
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Simuler l'éclairage et les ombres en 3D
Créer les normales pour les sommets
 Ensuite
nous
allons
ajouter le
code à la
fonction
drawScen
e() pour
attacher
le tableau
de
normales
à l'attribut
du shader,
comme ça
le code du
shader y
aura
accès:
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
35
 Une fois que nous avons appréhendé le concept
de source et de réflexion de la lumière, il y a deux
choses que nous avons besoin d'implémenter
pour nos lumières directionnelles.
1. Nous avons besoin d'associer la surface
normale avec chaque sommet. C'est un vecteur
qui est perpendiculaire à la face associé à ce
sommet.
2. Nous avons besoin de connaître la direction
dans laquelle la lumière arrive. Ceci est défini
par la direction du vecteur.
 Puis nous mettons à jour le vertex shader pour
ajuster la couleur de chaque sommet en prenant
en compte la lumière ambiante ainsi que l'effet
de la lumière directionnelle donné par l'angle qui
rencontre la face du cube. Nous allons voir
comment faire avec les shaders.
gl.bindBuffer(gl.ARRAY_BUFFER,
cubeVerticesNormalBuffer);
gl.vertexAttribPointer(vertexNormalA
ttribute, 3, gl.FLOAT, false, 0, 0);
cubeVerticesNormalBuffer =
gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,
cubeVerticesNormalBuffer);
var vertexNormals = [
// Front
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
// Left
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new
WebGLFloatArray(
vertexNormals),gl.STATIC_DRAW);
Enfin, nous avons besoin de mettre à jour le code
qui construit les matrices uniformes pour générer
et livrer au shader une matrice normale, qui sera
utilisée pour transformer les normales en fonction
de l'orientation actuelle du cube par rapport à la
source de lumière.
var normalMatrix = mvMatrix.inverse();
normalMatrix = normalMatrix.transpose();
var nUniform =
gl.getUniformLocation(shaderProgram,
'uNormalMatrix');
gl.uniformMatrix4fv(nUniform, false, new
WebGLFloatArray(normalMatrix.flatten()));
Overview of
the cube program
Puis nous mettons à jour le
vertex shader pour ajuster la
couleur de chaque sommet
en prenant en compte la
lumière ambiante ainsi que
l'effet de la lumière
directionnelle donné par
l'angle qui rencontre la face
du cube.
Simuler l'éclairage et les ombres en 3D
Mettre à jour les shaders: Le vertex shader
<script id="shader-vs" type="x-
shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix
* vec4(aVertexPosition, 1.0);
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
36
 Une fois que nous avons appréhendé le concept
de source et de réflexion de la lumière, il y a deux
choses que nous avons besoin d'implémenter
pour nos lumières directionnelles.
 Nous avons besoin d'associer la surface normale avec
chaque sommet. C'est un vecteur qui est
perpendiculaire à la face associé à ce sommet.
 Nous avons besoin de connaître la direction dans
laquelle la lumière arrive. Ceci est défini par la direction
du vecteur.
 Puis nous mettons à jour le vertex shader pour
ajuster la couleur de chaque sommet en prenant
en compte la lumière ambiante ainsi que l'effet
de la lumière directionnelle donné par l'angle qui
rencontre la face du cube. Nous allons voir
comment faire avec les shaders.
Maintenant que les shaders ont toutes les données
dont ils ont besoin, nous mettons à jour leur code.
vTextureCoord = aTextureCoord;
// Apply lighting effect
highp vec3 ambientLight = vec3(0.6, 0.6,
0.6);
highp vec3 directionalLightColor = vec3(0.5,
0.5, 0.75);
highp vec3 directionalVector = vec3(0.85,
0.8, 0.75);
highp vec4 transformedNormal =
uNormalMatrix * vec4(aVertexNormal, 1.0);
highp float directional = max(dot(
transformedNormal.xyz, directionalVector),
0.0);
vLighting = ambientLight + (
directionalLightColor * directional);
}
</script>
La première
chose à faire
est de mettre
à jour le
vertex shader
en générant
une valeur
pour l'ombre
de chaque
sommet, en se
basant sur
l'éclairage
ambiant ainsi
que la
direction de
la lumière.
Jetons un œil
sur le code
suivant:
Simuler l'éclairage et les ombres en 3D
Mettre à jour les shaders: Le vertex shader
<script id="shader-vs" type="x-
shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix
* vec4(aVertexPosition, 1.0);
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
37
 implémenter pour nos
lumières directionnelles.
 Nous avons besoin d'associer la surface
normale avec chaque sommet. C'est un
vecteur qui est perpendiculaire à la face
associé à ce sommet.
 Nous avons besoin de connaître la
direction dans laquelle la lumière
arrive. Ceci est défini par la direction du
vecteur.
mettons à jour:
 le vertex shader pour ajuster
la couleur de chaque
sommet en prenant en
compte la lumière ambiante
ainsi que l'effet de la lumière
directionnelle donné par
l'angle qui rencontre la face
du cube.
vTextureCoord = aTextureCoord;
// Apply lighting effect
highp vec3 ambientLight = vec3(0.6, 0.6,
0.6);
highp vec3 directionalLightColor = vec3(0.5,
0.5, 0.75);
highp vec3 directionalVector = vec3(0.85,
0.8, 0.75);
highp vec4 transformedNormal =
uNormalMatrix * vec4(aVertexNormal, 1.0);
highp float directional = max(dot(
transformedNormal.xyz, directionalVector),
0.0);
vLighting = ambientLight + (
directionalLightColor * directional);
}
</script>
Une fois que
 la position du sommet est
calculée, et que nous
obtenons
 les coordonnées des texels
(tas de pixel pour une
texture) correspondant au
sommet,
 nous pouvons travailler sur
le calcul de l'ombre de
chaque sommet.
La première chose que nous
allons faire est de
transformer la base normale
sur la position actuelle et
l'orientation du cube, en
calculant les normales des
sommets par la matrice
normale.
Simuler l'éclairage et les ombres en 3D
Mettre à jour les shaders: Le vertex shader
<script id="shader-vs" type="x-
shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix
* vec4(aVertexPosition, 1.0);
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
38
 implémenter pour nos
lumières directionnelles.
 Nous avons besoin d'associer la surface
normale avec chaque sommet. C'est un
vecteur qui est perpendiculaire à la face
associé à ce sommet.
 Nous avons besoin de connaître la
direction dans laquelle la lumière
arrive. Ceci est défini par la direction du
vecteur.
mettons à jour:
 le vertex shader pour ajuster
la couleur de chaque
sommet en prenant en
compte la lumière ambiante
ainsi que l'effet de la lumière
directionnelle donné par
l'angle qui rencontre la face
du cube.
vTextureCoord = aTextureCoord;
// Apply lighting effect
highp vec3 ambientLight = vec3(0.6, 0.6,
0.6);
highp vec3 directionalLightColor = vec3(0.5,
0.5, 0.75);
highp vec3 directionalVector = vec3(0.85,
0.8, 0.75);
highp vec4 transformedNormal =
uNormalMatrix * vec4(aVertexNormal, 1.0);
highp float directional = max(dot(
transformedNormal.xyz, directionalVector),
0.0);
vLighting = ambientLight + (
directionalLightColor * directional);
}
</script>
Nous pouvons alors
calculer la quantité
d'éclairage qui doit être
appliquée au sommet
 en calculant le produit
de la normale
transformée et du
vecteur directionnel (la
direction d'où la
lumière vient). Si le
résultat est inférieur à
zéro, alors on le met à
0. Car une lumière
négative n'a pas de sens
dans notre cas.
Simuler l'éclairage et les ombres en 3D
Mettre à jour les shaders: Le vertex shader
<script id="shader-vs" type="x-
shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix
* vec4(aVertexPosition, 1.0);
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
39
 implémenter pour nos
lumières directionnelles.
 Nous avons besoin d'associer la surface
normale avec chaque sommet. C'est un
vecteur qui est perpendiculaire à la face
associé à ce sommet.
 Nous avons besoin de connaître la
direction dans laquelle la lumière
arrive. Ceci est défini par la direction du
vecteur.
mettons à jour:
 le vertex shader pour ajuster
la couleur de chaque
sommet en prenant en
compte la lumière ambiante
ainsi que l'effet de la lumière
directionnelle donné par
l'angle qui rencontre la face
du cube.
vTextureCoord = aTextureCoord;
// Apply lighting effect
highp vec3 ambientLight = vec3(0.6, 0.6,
0.6);
highp vec3 directionalLightColor = vec3(0.5,
0.5, 0.75);
highp vec3 directionalVector = vec3(0.85,
0.8, 0.75);
highp vec4 transformedNormal =
uNormalMatrix * vec4(aVertexNormal, 1.0);
highp float directional = max(dot(
transformedNormal.xyz, directionalVector),
0.0);
vLighting = ambientLight + (
directionalLightColor * directional);
}
</script>
Nous pouvons alors calculer la
quantité d'éclairage qui doit
être appliquée au sommet
 Une fois la quantité de
lumière directionnelle
calculée,
 nous pouvons générer la
valeur d'éclairage en
prenant
 l'éclairage ambiant et en y
ajoutant le produit de la
couleur de la lumière
directionnelle, et aussi la
quantité de la lumière
directionnelle à fournir.
 Comme résultat, nous avons
maintenant une valeur RGB
qui sera utilisé par le
fragment shader pour
ajuster la couleur de
chaque pixel.
Simuler l'éclairage et les ombres en 3D
Mettre à jour les shaders: Le fragment shader
Ici nous récupérons la
couleur de chaque texel (tas
de pixel pour une texture) ,
comme nous avons fait pour
l'exemple précédent, mais
avant d'ajuster la couleur du
fragment, nous multiplions
la couleur des pixels par la
quantité de lumière, pour
appliquer l'effet d'éclairage.
Et c'est tout !
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
Éclairage en WebGL
40
 implémenter pour nos
lumières directionnelles.
 Nous avons besoin d'associer la surface
normale avec chaque sommet. C'est un
vecteur qui est perpendiculaire à la face
associé à ce sommet.
 Nous avons besoin de connaître la
direction dans laquelle la lumière
arrive. Ceci est défini par la direction du
vecteur.
mettons à jour:
 le vertex shader pour ajuster
la couleur de chaque
sommet en prenant en
compte la lumière ambiante
ainsi que l'effet de la lumière
directionnelle donné par
l'angle qui rencontre la face
du cube.
<script id="shader-fs" type="x-shader/x-
fragment">
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
uniform sampler2D uSampler;
void main(void) {
mediump vec4 texelColor =
texture2D(uSampler, vec2(vTextureCoord.s,
vTextureCoord.t));
gl_FragColor = vec4(texelColor.rgb *
vLighting, texelColor.a);
}
</script>
Le fragment shader a
maintenant besoin d'être mis à
jour en prenant en compte la
quantité de lumière calculée
précédemment par le vertex
shader:
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
 The vertex
shader, flag.v.glsl, thus
only performs
transformation and
projection, using
the p_matrix and mv_
matrix we pass in as
uniforms.
 The shader forwards
most of the material
vertex attributes to
varying variables for the
fragment shader to use:
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat texcoord[2];
GLfloat shininess;
GLubyte specular[4];
};
void main() {
vec4 eye_position =
mv_matrix *
vec4(position, 1.0);
gl_Position = p_matrix *
eye_position;
frag_position =
eye_position.xyz;
frag_normal = (mv_matrix *
vec4(normal,
0.0)).xyz;
frag_texcoord = texcoord;
frag_shininess = shininess;
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
attribute vec3 position, normal;
attribute vec2 texcoord;
attribute float shininess;
attribute vec4 specular;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
In addition to the texture
coordinate, shininess,
and specular color, the
vertex shader also
outputs to the fragment
shader the model-view-
transformed vertex
position.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat texcoord[2];
GLfloat shininess;
GLubyte specular[4];
};
void main() {
vec4 eye_position =
mv_matrix *
vec4(position, 1.0);
gl_Position = p_matrix *
eye_position;
frag_position =
eye_position.xyz;
frag_normal = (mv_matrix *
vec4(normal,
0.0)).xyz;
frag_texcoord = texcoord;
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
attribute vec3 position, normal;
attribute vec2 texcoord;
attribute float shininess;
attribute vec4 specular;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
The model-view matrix
transforms the
coordinate space so
that the viewer is at the
origin, so we can
determine the surface-to-
viewer direction needed
by the specular
calculation from the
transformed position.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
void main() {
vec4 eye_position =
mv_matrix *
vec4(position, 1.0);
gl_Position = p_matrix *
eye_position;
frag_position =
eye_position.xyz;
frag_normal = (mv_matrix *
vec4(normal,
0.0)).xyz;
frag_texcoord = texcoord;
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
attribute vec3 position, normal;
attribute vec2 texcoord;
attribute float shininess;
attribute vec4 specular;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
We likewise transform the
normal vector to keep it in
the same frame of reference
as the position. Since the
normal is a directional vector
without a position,
we apply the matrix to it with
a w component of zero,
which cancels out the
translation of the modelview
matrix and only applies its
rotation.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
void main() {
vec4 eye_position =
mv_matrix *
vec4(position, 1.0);
gl_Position = p_matrix *
eye_position;
frag_position =
eye_position.xyz;
frag_normal = (mv_matrix *
vec4(normal,
0.0)).xyz;
frag_texcoord = texcoord;
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
attribute vec3 position, normal;
attribute vec2 texcoord;
attribute float shininess;
attribute vec4 specular;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
The pipeline
revisited
The pipeline
revisited
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementi
ng Phong
shading in
GLSL
With this set
of varying
values, the
fragment
shader, flag.f
.glsl, can
perform the
actual Phong
calculation:
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
void main() {
vec3 mv_light_direction = (
mv_matrix * vec4(light_direction,
0.0)).xyz,
normal = normalize(frag_normal),
eye = normalize(frag_position),
reflection = reflect(
mv_light_direction , normal );
vec4 frag_diffuse =
texture2D(texture, frag_texcoord);
vec4 diffuse_factor = max(-
dot(normal, mv_light_direction),
0.0) * light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye),
frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular +
ambient_diffuse_factor *
frag_diffuse;
}
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
const vec4 light_specular =
void main() {
vec4 eye_position = mv_matrix *
vec4(position, 1.0);
gl_Position = p_matrix *
eye_position;
frag_position = eye_position.xyz;
frag_normal = (mv_matrix *
vec4(normal, 0.0)).xyz;
frag_texcoord = texcoord;
frag_shininess = shininess;
frag_specular = specular;
}
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
attribute vec3 position, normal;
attribute vec2 texcoord;
attribute float shininess;
attribute vec4 specular;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
To keep things simple, the
shader defines a single
light source
using const values in the
shader source.
A real renderer would
likely feed these light
parameters in as uniform
values, so that lights can
be moved
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
void main() {
vec3 mv_light_direction = (mv_matrix
vec4(light_direction, 0.0)).xyz,
normal = normalize(frag_normal
eye = normalize(frag_position),
reflection = reflect(mv_light_direction
normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
or their material attributes changed
from the host program.
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
With the light attributes
embedded in the GLSL as
constants, it's easy to
change the light attributes in
the source, press R to reload
the shader, and see the
result.
Our light source acts as if it
were infinitely far away,
shining from the
same light_direction on
every surface in the scene.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz,
normal = normalize(frag_normal),
eye = normalize(frag_position),
reflection = reflect(mv_light_direction ,
normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) *
light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor +
light_ambient;
vec4 specular_factor = max(pow(
-dot(reflection, eye),
frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular +
ambient_diffuse_factor *
frag_diffuse;
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
const vec4 light_specular =
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
The light is white, with a 20%
baseline ambient light level.
It can be made colored by
replacing light_diffuse, light_
ambient, light_specular with
RGBA values.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading
in GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
const vec4 light_specular =
vec4(1.0, 1.0, 1.0, 1.0);
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz,
normal = normalize(frag_normal),
eye = normalize(frag_position),
reflection = reflect(mv_light_direction ,
normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) *
light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor +
light_ambient;
vec4 specular_factor = max(pow(
-dot(reflection, eye),
frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular +
ambient_diffuse_factor *
frag_diffuse;
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading mod
el, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
The fragment shader uses
several new GLSL functions
we haven't seen before:
normalize(v) returns a unit
vector with the same
direction as v. We use it here
to convert the fragment
position into a direction
vector, and to ensure that the
normal is a unit vector.
Even if our original vertex
normals are all unit vectors,
their linear interpolations
won't be.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz,
normal = normalize(frag_normal),
eye = normalize(frag_position),
reflection = reflect(mv_light_direction,
normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
const vec4 light_specular =
vec4(1.0, 1.0, 1.0, 1.0);
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
pow(x,n) raises x to the nth
power, which we use to
apply the specular shininess
factor.
max(n,m) returns the larger
of n or m. We use it to clamp
dot products less than zero
so they shade the same as if
they were zero.
•reflect(u,v) reflects the
vector u around v, giving a
vector that makes the same
angle with v as u, but in the
opposite direction. With it we
derive the reflected eye
direction for the specular
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
void main() {
vec3 mv_light_direction =
(mv_matrix * vec4(light_direction,
0.0)).xyz,
normal = normalize(frag_normal),
eye = normalize(frag_position),
reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse =
texture2D(texture, frag_texcoord);
vec4 diffuse_factor = max(-
dot(normal, mv_light_direction), 0.0)
* light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess),
0.0) * light_specular;
gl_FragColor = specular_factor *
frag_specular +
ambient_diffuse_factor *
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
const vec4 light_specular =
vec4(1.0, 1.0, 1.0, 1.0);
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Implementing Phong
shading in GLSL
We transform our
constant light_direction to
put it in the same coordinate
space as
the normal and eye vectors. :
We then sample the
surface's diffuse color from
the mesh texture
We assign the shaded value
to gl_FragColor to generate
the final shaded fragment.
struct flag_vertex {
GLfloat position[4];
GLfloat normal[4];
GLfloat
texcoord[2];
GLfloat shininess;
GLubyte
specular[4];
};
void main() {
vec3 mv_light_direction =
(mv_matrix * vec4(light_direction,
0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position),
reflection =
reflect(mv_light_direction,
normal);
vec4 frag_diffuse =
texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-
dot(normal, mv_light_direction),
0.0) * light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient;
vec4 specular_factor =
max(pow(-dot(reflection, eye),
frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular +
ambient_diffuse_factor *
struct flag_mesh {
GLuint
vertex_buffer,
element_buffer;
GLsizei
element_count;
GLuint texture;
};
Implementing Phong shading in
GLSL
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
const vec4 light_specular =
vec4(1.0, 1.0, 1.0, 1.0);
FIN DU CHAPITRE
FIN DU CHAPITRE
FIN DU CHAPITRE
Programmation 2D/3D: INF 1483
Effet de Lumière sur les Objets
FIN DU CHAPITRE
52
FIN DU CHAPITRE
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
Before we wrap things up,
let's take a quick look at how
the Phong framework can be
manipulated to give more
stylized results. The classic
Phong model is
a photorealistic model:
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor *
Tweaking the Phong model
for stylistic effects
it attempts to model real-world light
behavior. But photorealism isn't
always desirable.
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
Many games set themselves
apart visually by using more
stylized shading effects.
These effects often use the
basic Phong model of
diffuse, ambient, and
specular lighting, but they
warp the individual factors
before summing them
together.
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor *
frag_diffuse;
Tweaking the Phong model
for stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
As a trivial example, we can
get a brighter, softer shading
effect if, instead of clamping
the diffuse dot product of
back-facing surfaces to zero,
we scale it so that
perpendicular surfaces
receive half illumination, and
back-facing surfaces scale
linearly toward zero.
struct flag_vertex {
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor
frag_diffuse;
Tweaking the Phong model
for stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
Team Fortress 2 uses this
"half Lambert" reflectance
scale, so called because the
standard Lambertian dropoff
rate is halved, as a basis for
its cartoonish but semi-
photorealistic look
(albeit heavily modified).
struct flag_vertex {
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor
frag_diffuse;
struct flag_mesh {
Tweaking the Phong model
for stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
Let's modify flag.f.glsl to
warp the diffuse dot product:
float warp_diffuse(float d) {
return d * 0.5 + 0.5; }
void main() {
// ... vec4 diffuse_factor =
max(warp_diffuse(-
dot(normal,
mv_light_direction)), 0.0) *
light_diffuse;
// ...
}
struct flag_vertex {
void main() {
vec3 mv_light_direction = (mv_matrix
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor
frag_diffuse;
Tweaking the Phong model for
stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
A popular effect that builds
from this half-Lambert scale
is cel shading, in which a
stair-step function is applied
to the half-Lambert factor so
that surfaces are shaded
flatly with higher contrast
between light and dark
areas, in the style of
traditional hand-drawn
animation cels.
void main() {
vec3 mv_light_direction = (mv_matrix
* vec4(light_direction, 0.0)).xyz,
normal = normalize(frag_normal), eye
= normalize(frag_position), reflection
= reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-
dot(normal, mv_light_direction), 0.0) *
light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess),
0.0) * light_specular;
gl_FragColor = specular_factor *
frag_specular +
ambient_diffuse_factor * frag_diffuse;
}
Tweaking the Phong model for
stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
The pipeline revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
Jet Set Radio pioneered this
look, and it's since been
used in countless games.
Implementing it in GLSL is
easy:
float cel(float d) {
return smoothstep(0.35,
0.37, d) * 0.4 +
smoothstep(0.70, 0.72, d) *
0.6; }
float warp_diffuse(float d) {
return cel(d * 0.5 + 0.5); }
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
Tweaking the Phong model for
stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
GLSL's smoothstep(lo,hi,x) f
unction behaves like this:
if x is less than lo, it
returns 0.0; if greater than hi,
it returns 1.0; if in between, it
transitions linearly from zero
to one.
Our cel function above
uses smoothstep to create
three flat shading levels with
short linear transitions in
between.
void main() {
vec3 mv_light_direction = (mv_matrix *
vec4(light_direction, 0.0)).xyz, normal =
normalize(frag_normal), eye =
normalize(frag_position), reflection =
reflect(mv_light_direction, normal);
vec4 frag_diffuse = texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-dot(normal,
mv_light_direction), 0.0) * light_diffuse;
vec4 ambient_diffuse_factor = diffuse_factor
light_ambient;
vec4 specular_factor = max(pow(-
dot(reflection, eye), frag_shininess), 0.0) *
light_specular;
gl_FragColor = specular_factor *
frag_specular + ambient_diffuse_factor *
Tweaking the Phong model for
stylistic effects
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
0.408248);
const vec4 light_diffuse =
vec4(0.8, 0.8, 0.8, 0.0);
const vec4 light_ambient =
vec4(0.2, 0.2, 0.2, 1.0);
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Tweaking the Phong model
for stylistic effects
There are other effects that
can be performed by
messing with
the warp_diffuse function.
For example, the function
doesn't need to be float-to-
float but could also map to a
color scale; you could map
greater dot products to
warmer reddish colors while
lesser products map to
cooler bluish colors to give
an artistic illustration effect.
void main() {
vec3 mv_light_direction =
(mv_matrix *
vec4(light_direction, 0.0)).xyz,
normal =
normalize(frag_normal), eye =
normalize(frag_position),
reflection =
reflect(mv_light_direction,
normal);
vec4 frag_diffuse =
texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-
dot(normal, mv_light_direction),
0.0) * light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient;
Tweaking the Phong model for
stylistic effects
I encourage you to experiment
with the fragment shader code
to see what other effects you
can create.
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,
The pipeline
revisited
With the flat,
wallpaper-looking
grass and brick
textures and the
unnatural lack of
shadow cast by the
flag, it looks like
something a
Nintendo 64 would
have rendered, but
it's a start.
We'll improve the
graphical fidelity of
the demo over the
next few chapters.
The pipeline
revisited
For this
chapter, we'll
render the
image on the
right by
implementing
the Phong
shading model
, which will
serve as the
basis for more
advanced
effects we'll
look at later
on.
Rendering a Dynamic 3D Scene with Phong
Shading
Effet de lumière sur les objets
Programmation 2D/3D:
INF 1483
Conclusion
With Phong shading
implemented, we can start
adding additional effects to
further improve the look of
the flag scene. The most
glaring problem is the lack of
shadow cast by the flag, so
next chapter we'll look at
shadow mapping, a
technique for rendering
accurate shadows into a
scene, and learn about off-
screen framebuffer objects in
void main() {
vec3 mv_light_direction =
(mv_matrix *
vec4(light_direction, 0.0)).xyz,
normal =
normalize(frag_normal), eye =
normalize(frag_position),
reflection =
reflect(mv_light_direction,
normal);
vec4 frag_diffuse =
texture2D(texture,
frag_texcoord);
vec4 diffuse_factor = max(-
dot(normal, mv_light_direction),
0.0) * light_diffuse;
vec4 ambient_diffuse_factor =
diffuse_factor + light_ambient;
vec4 specular_factor =
max(pow(-dot(reflection, eye),
frag_shininess), 0.0) *
light_specular;
Conclusion
Meanwhile, if you're interested in
learning more about real-time
shading techniques on your own
without an OpenGL bias, I highly
recommend the book Real-Time
Rendering.
#version 110
uniform mat4 p_matrix, mv_matrix;
uniform sampler2D texture;
varying vec3 frag_position,
frag_normal;
varying vec2 frag_texcoord;
varying float frag_shininess;
varying vec4 frag_specular;
const vec3 light_direction =
vec3(0.408248, -0.816497,