![lhark](/assets/img/avatar_default.png)
OpenGL boilerplate by Benoit Ozell Packets code taken from https://github.com/jeschke/water-wave-packets
130 lines
5.1 KiB
GLSL
130 lines
5.1 KiB
GLSL
#version 410
|
|
|
|
// Définition des paramètres des sources de lumière
|
|
layout (std140) uniform LightSourceParameters
|
|
{
|
|
vec4 ambient;
|
|
vec4 diffuse;
|
|
vec4 specular;
|
|
vec4 position;
|
|
vec3 spotDirection;
|
|
float spotExponent;
|
|
float spotCutoff; // ([0.0,90.0] ou 180.0)
|
|
float constantAttenuation;
|
|
float linearAttenuation;
|
|
float quadraticAttenuation;
|
|
} LightSource[1];
|
|
|
|
// Définition des paramètres des matériaux
|
|
layout (std140) uniform MaterialParameters
|
|
{
|
|
vec4 emission;
|
|
vec4 ambient;
|
|
vec4 diffuse;
|
|
vec4 specular;
|
|
float shininess;
|
|
} FrontMaterial;
|
|
|
|
// Définition des paramètres globaux du modèle de lumière
|
|
layout (std140) uniform LightModelParameters
|
|
{
|
|
vec4 ambient; // couleur ambiante
|
|
bool localViewer; // observateur local ou à l'infini?
|
|
bool twoSide; // éclairage sur les deux côtés ou un seul?
|
|
} LightModel;
|
|
|
|
layout (std140) uniform varsUnif
|
|
{
|
|
// partie 1: illumination
|
|
int typeIllumination; // 0:Lambert, 1:Gouraud, 2:Phong
|
|
bool utiliseBlinn; // indique si on veut utiliser modèle spéculaire de Blinn ou Phong
|
|
bool utiliseDirect; // indique si on utilise un spot style Direct3D ou OpenGL
|
|
bool afficheNormales; // indique si on utilise les normales comme couleurs (utile pour le débogage)
|
|
// partie 3: texture
|
|
int texnumero; // numéro de la texture appliquée
|
|
bool utiliseCouleur; // doit-on utiliser la couleur de base de l'objet en plus de celle de la texture?
|
|
int afficheTexelNoir; // un texel noir doit-il être affiché 0:noir, 1:mi-coloré, 2:transparent?
|
|
};
|
|
|
|
uniform mat4 matrModel;
|
|
uniform mat4 matrVisu;
|
|
uniform mat4 matrProj;
|
|
uniform mat3 matrNormale;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
layout(location=0) in vec4 Vertex;
|
|
layout(location=2) in vec3 Normal;
|
|
layout(location=3) in vec4 Color;
|
|
layout(location=8) in vec4 TexCoord;
|
|
|
|
out Attribs {
|
|
vec3 lumiDir, spotDir;
|
|
vec3 normale, obsVec;
|
|
vec2 texCoord;
|
|
vec4 couleur;
|
|
} AttribsOut;
|
|
|
|
vec4 calculerReflexion( in vec3 L, in vec3 N, in vec3 O )
|
|
{
|
|
vec4 coul = FrontMaterial.emission + FrontMaterial.ambient * LightModel.ambient;
|
|
|
|
// calcul de la composante ambiante
|
|
coul += FrontMaterial.ambient * LightSource[0].ambient;
|
|
|
|
// calcul de l'éclairage seulement si le produit scalaire est positif
|
|
float NdotL = max( 0.0, dot( N, L ) );
|
|
if ( NdotL > 0.0 )
|
|
{
|
|
// calcul de la composante diffuse
|
|
//coul += ( utiliseCouleur ? FrontMaterial.diffuse : vec4(1.0) ) * LightSource[0].diffuse * NdotL;
|
|
coul += FrontMaterial.diffuse * LightSource[0].diffuse * NdotL;
|
|
|
|
// calcul de la composante spéculaire (Blinn ou Phong)
|
|
float NdotHV = max( 0.0, ( utiliseBlinn ) ? dot( normalize( L + O ), N ) : dot( reflect( -L, N ), O ) );
|
|
coul += FrontMaterial.specular * LightSource[0].specular * ( ( NdotHV == 0.0 ) ? 0.0 : pow( NdotHV, FrontMaterial.shininess ) );
|
|
}
|
|
return( coul );
|
|
}
|
|
|
|
void main( void )
|
|
{
|
|
// transformation standard du sommet, ** sans la projection **
|
|
gl_Position = matrVisu * matrModel * Vertex;
|
|
|
|
// calculer la normale qui sera interpolée pour le nuanceur de fragment
|
|
AttribsOut.normale = matrNormale * Normal;
|
|
|
|
// calculer la position du sommet (dans le repère de la caméra)
|
|
vec3 pos = vec3( matrVisu * matrModel * Vertex );
|
|
|
|
// vecteur de la direction de la lumière (dans le repère de la caméra)
|
|
AttribsOut.lumiDir = vec3( ( matrVisu * LightSource[0].position ).xyz - pos );
|
|
|
|
// vecteur de la direction vers l'observateur (dans le repère de la caméra)
|
|
AttribsOut.obsVec = ( LightModel.localViewer ?
|
|
normalize(-pos) : // =(0-pos) un vecteur qui pointe vers le (0,0,0), c'est-à-dire vers la caméra
|
|
vec3( 0.0, 0.0, 1.0 ) ); // on considère que l'observateur (la caméra) est à l'infini dans la direction (0,0,1)
|
|
// vecteur de la direction du spot (en tenant compte seulement des rotations de la caméra)
|
|
AttribsOut.spotDir = inverse(mat3(matrVisu)) * -LightSource[0].spotDirection;
|
|
// On accepte aussi: (si on suppose que .spotDirection est déjà dans le repère de la caméra)
|
|
//AttribsOut.spotDir = -LightSource[0].spotDirection;
|
|
// On accepte aussi: (car matrVisu a seulement une translation et pas de rotation => "mat3(matrVisu) == I" )
|
|
//AttribsOut.spotDir = -LightSource[0].spotDirection;
|
|
// On accepte aussi: (car c'était le calcul qui était dans la solution précédente présentée dans le lab!)
|
|
//AttribsOut.spotDir = -( matrVisu * vec4(LightSource[0].spotDirection,1.0) ).xyz;
|
|
|
|
// si illumination est 1:Gouraud, calculer la réflexion ici, sinon ne rien faire de plus
|
|
if ( typeIllumination == 1 )
|
|
{
|
|
vec3 L = normalize( AttribsOut.lumiDir ); // calcul du vecteur de la surface vers la source lumineuse
|
|
vec3 N = normalize( AttribsOut.normale ); // vecteur normal
|
|
vec3 O = normalize( AttribsOut.obsVec ); // position de l'observateur
|
|
AttribsOut.couleur = calculerReflexion( L, N, O );
|
|
}
|
|
//else
|
|
// couleur = vec4(0.0); // inutile
|
|
|
|
// assigner les coordonnées de texture
|
|
AttribsOut.texCoord = TexCoord.st;
|
|
}
|