ripple/nuanceurSommetsSolution.glsl

131 lines
5.1 KiB
Text
Raw Normal View History

#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;
}