GLSLFX Shaders
Les fichiers GLSLFX font le pont entre l’application et les fichiers glsl shader.
Il permet d’utiliser n’importe quel shader glsl sans avoir à modifier le code.
Format de fichier
Le format de fichier GLSLFX est un fichier XML. Les commentaires sont pris en charge.
En-tête et nœud racine
L’élément de nœud racine XML est nommé glslfx.
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
</glslfx>
Corps
Technique
Elément XML décrivant une technique. Une technique est une variante du courant FX. Un GLSLFX peut contenir plusieurs techniques, mais au moins une technique doit être définie.
Le rendu de la géométrie s’effectue selon l’une des techniques définies par l’application.
Technique Name:
Attributs :
- name : Toute chaîne utilisée pour nommer la technique
L’élément XML peut avoir plusieurs enfants. Les éléments définis dans une technique remplacent les éléments définis globalement.
Par exemple, il est utilisé pour remplacer certaines valeurs d’uniforme et obtenir une variation FX pour cette technique.
Passe de rendu
Elément XML décrivant une passe de rendu. Une passe de rendu décrit le rendu de la géométrie.
Une technique peut contenir plusieurs passes de rendu exécutées de manière séquentielle. Une technique ne contenant aucune passe de rendu équivaut à une technique contenant une passe de rendu à l’écran.
Les éléments définis dans une passe de rendu remplacent les éléments définis dans la technique parent.
Attributs :
-
sortie
-
hors écran : le rendu sera effectué en cibles de rendu définies par l’utilisateur
-
à l’écran : le rendu est effectué dans la cible de rendu par défaut
Shaders
Définissez les fichiers de shader GLSL pour chaque type.
Définition d’élément XML :
Attributs :
-
type : type de shader GLSL ;
-
nom du fichier : chemin du fichier glsl shader. Peut être absolu ou relatif par rapport au fichier GLSLFX ;
-
primitiveType : méthode de rendu de la primitive.
| table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 5-row-2 | |
|---|---|
| Valeur ‘type’ | Description |
| vertex | shader vertex |
| géométrie | Shader de géométrie |
| test_control | shader de contrôle de tessellation |
| tess_eval | shader d’évaluation des tessellations |
| fragment | Shader de fragment |
| table 0-row-2 1-row-2 2-row-2 3-row-2 | |
|---|---|
| Valeur « primitiveType » | Description |
| point | Rendu sous forme de points |
| boucle de ligne | Rendu en tant que boucle de ligne |
| patch[1…N] | Rendu sous forme de correctifs avec [1…N] vertex |
Propriétés
Permet de configurer une partie de l’état OpenGL.
Propriété Name:
Attributs :
-
name : Le nom de la propriété à définir. Le nom est basé sur la fonction OpenGL ou le nom glEnum :
- Syntaxe des énumérations : sans le préfixe « GL_ », en minuscules. Exemples : glEnable(GL_FUSION_ENABLE) => « » », glDisable(GL_CULL_FACE) => « » »
- Syntaxe des fonctions : sans le préfixe « gl », en minuscules et avec tous les mots séparés par le caractère « _ ». Exemple : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) => « »
-
Syntaxe des énumérations : sans le préfixe « GL_ », en minuscules. Exemples : glEnable(GL_FUSION_ENABLE) => « » », glDisable(GL_CULL_FACE) => « » »
-
Syntaxe des fonctions : sans le préfixe « gl », en minuscules et avec tous les mots séparés par le caractère « _ ». Exemple : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) => « »
-
value : Valeur de la propriété.
| table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 5-row-3 6-row-3 7-row-3 8-row-3 9-row-3 10-row-3 11-row-3 12-row-3 13-row-3 14-row-3 15-row-3 16-row-3 17-row-3 18-row-3 19-row-3 20-row-3 21-row-3 22-row-3 23-row-3 24-row-3 25-row-3 26-row-3 27-row-3 28-row-3 29-row-3 30-row-3 31-row-3 32-row-3 33-row-3 34-row-3 35-row-3 36-row-3 37-row-3 38-row-3 39-row-3 | ||
|---|---|---|
| Valeurs ‘name’ | Valeurs ‘value’ | Description |
| blend_enabled | booléen | Activation/désactivation du mode de fusion |
| vrai | ||
| faux | ||
| blend_func | chaîne, chaîne | Définition des fonctions de fusion source et cible |
| zéro | pour OpenGL enum GL_ZERO | |
| un | pour OpenGL enum GL_ONE | |
| src_color | pour OpenGL enum GL_SRC_COLOR | |
| one_minus_src_color | pour l’énumération OpenGL GL_ONE_MINUS_SRC_COLOR | |
| dst_color | pour OpenGL enum GL_DST_COLOR | |
| one_minus_dst_color | pour l’énumération OpenGL GL_ONE_MINUS_DST_COLOR | |
| src_alpha | pour OpenGL enum GL_SRC_ALPHA | |
| one_minus_src_alpha | pour l’énumération OpenGL GL_ONE_MINUS_SRC_ALPHA | |
| dst_alpha | pour OpenGL enum GL_DST_ALPHA | |
| one_minus_dst_alpha | pour l’énumération OpenGL GL_ONE_MINUS_DST_ALPHA | |
| constante_color | pour OpenGL enum GL_CONSTANT_COLOR | |
| one_minus_constant_color | pour l’énumération OpenGL GL_ONE_MINUS_CONSTANT_COLOR | |
| constante_alpha | pour OpenGL enum GL_CONSTANT_ALPHA | |
| one_minus_constant_alpha | pour l’énumération OpenGL GL_ONE_MINUS_CONSTANT_ALPHA | |
| src_alpha_saturate | pour l’énumération OpenGL GL_SRC_ALPHA_SATURATE | |
| src1_color | pour OpenGL enum GL_SRC1_COLOR | |
| one_minus_src1_color | pour l’énumération OpenGL GL_ONE_MINUS_SRC1_COLOR | |
| src1_alpha | pour OpenGL enum GL_SRC1_ALPHA | |
| one_minus_src1_alpha | pour l’énumération OpenGL GL_ONE_MINUS_SRC1_ALPHA | |
| cull_face_enabled | booléen | Activation/désactivation de l’abattage de faces |
| vrai | ||
| faux | ||
| cull_face_mode | chaîne | Définir le mode d’abattage de la face |
| avant | pour OpenGL enum GL_FRONT | |
| envers | pour OpenGL enum GL_BACK | |
| avant_et_arrière | pour l’énumération OpenGL GL_FRONT_AND_BACK | |
| profondeur_func | chaîne | Définition de la fonction de comparaison des profondeurs |
| jamais | pour OpenGL enum GL_NEVER | |
| moins | pour OpenGL enum GL_LESS | |
| égal | pour OpenGL enum GL_LEQUAL | |
| égal à | pour OpenGL enum GL_EQUAL | |
| notequal | pour OpenGL enum GL_NOTEQUAL | |
| égaler | pour OpenGL enum GL_GEQUAL | |
| supérieur | pour OpenGL enum GL_GREATER | |
| toujours | pour OpenGL enum GL_ALWAYS |
Uniformes
Permet de remplacer certains uniformes définis globalement ou dans la technique parent. Cela permet de modifier le comportement du shader pour cette technique ou passe de rendu.
Voir la section Uniformes ci-dessous pour plus de détails sur leur définition.
+++Exemple
+++
Cibles de rendu
Pour les passes de rendu hors écran, les cibles de rendu doivent être définies dans la passe de rendu.
Sortie Name:
Attributs :
- attachment : point d’attache OpenGL, inspiré des noms OpenGL :
GL_COLOR_ATTACHMENT[0…3] => ‘color[0…3]’
GL_PROFONDEUR_ATTACHMENT => ‘profondeur’
attachment : point d’attache OpenGL, inspiré des noms OpenGL :
GL_COLOR_ATTACHMENT[0…3] => ‘color[0…3]’
GL_PROFONDEUR_ATTACHMENT => ‘profondeur’
- nom : nom de la cible de rendu.
Il peut être utilisé lors d’une passe de rendu ultérieure pour lier cette cible de rendu en tant qu’échantillonneur.
nom : nom de la cible de rendu.
Il peut être utilisé lors d’une passe de rendu ultérieure pour lier cette cible de rendu en tant qu’échantillonneur.
- format : format interne de la cible de rendu.
format : format interne de la cible de rendu.
- clear : attribut facultatif qui définit une valeur clear.
Si elle est présente, la cible de rendu sera effacée à cette valeur au début de la passe de rendu.
S’il est manquant, la cible de rendu conservera son contenu précédent.
À propos des formats
Pour les formats de profondeur, tous les formats OpenGL de profondeur seule (sans pochoir) sont pris en charge :
- GL_PROFONDEUR_COMPONENT16 => ‘profondeur 26’
- GL_PROFONDEUR_COMPONENT24 => ‘profondeur 34’
- GL_PROFONDEUR_COMPONENT32 => ‘profondeur 42’
- GL_PROFONDEUR_COMPONENT32F => ‘profondeur 42f’
Pour les formats de couleur, le nom est basé sur les noms d’énumération OpenGL, sans le préfixe « GL_ », en minuscules.
Trois formats de canal (RGB) ne sont pas pris en charge. Utilisez plutôt un format RVBA.
Nombre de bits par pixel par canal pris en charge :
- Entier non signé normalisé : 8, 16
- Point flottant : 16, 32
Une exception à ces règles est le format GL_R11F_G11F_B10F qui est pris en charge. :
- GL_RGBA8 => ‘rgba8’
- GL_RGBA16F => ‘rgba16f’
- GL_SRGB8_ALPHA 8 => ‘srgb8_alpha8’
- GL_R11F_G11F_B10F => ‘r11f_g11f_b10f’
- GL_RG16 => « rg16 »
Échantillonnages
Autorisez le remplacement de certains échantillonnages définis globalement, car ils ne peuvent pas être définis dans une technique. Cela permet de définir une utilisation d’échantillonnage pour cette passe de rendu ou de lire à partir d’une cible de rendu d’une passe de rendu précédente.
Voir la section Échantillonneurs pour plus de détails sur leur définition.
+++Exemple
+++
Format du Vertex d’entrée
Cela permet de définir la sémantique de chaque attribut défini dans le shader vertex.
Définition d’élément XML :
Nom : ‘vertexformat’
Attributs :
- ‘name’ : Le nom de l’attribut tel que défini dans le shader du vertex.
- ‘sémantique’ : Sémantique de l’attribut.
Exemple :
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
<!-- INPUT VERTEX FORMAT -->
<vertexformat name="iVS_Position" semantic="position"/>
<vertexformat name="iVS_Normal" semantic="normal"/>
<vertexformat name="iVS_UV" semantic="texcoord0"/>
<vertexformat name="iVS_Tangent" semantic="tangent0"/>
<vertexformat name="iVS_Binormal" semantic="binormal0"/>
</glslfx>
Échantillonnages
Cela permet de définir l’utilisation de chaque échantillonneur.
Il est utilisé par l’application pour savoir quelle texture régler dans les échantillonneurs spécifiés.
Définition d’élément XML :
Nom : ‘sampler’
Attributs :
- ‘name’ : Le nom de la variable d’échantillonnage dans le fichier shader.
- ‘usage’ : Utilisation de l’échantillonneur. Elle correspond à l’utilisation spécifiée dans le nœud Sortie du graphe.
- Plusieurs utilisations sont prises en charge.
- Exemple :
<!-- SAMPLERS -->
<sampler name="baseColorMap" usage="basecolor,diffuse"/>
<!-- ... -->
‘isHidden’ : Booléen qui indique si l’échantillonneur doit apparaître dans l’interface graphique
- Exemple :
<!-- SAMPLERS -->
<sampler name="bluenoiseMask" usage="bluenoisemask" ishidden="true"/>
<!-- ... -->
Mode d’habillage :
Filtre texture
Exemple :
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
<!-- SAMPLERS -->
<sampler name="baseColorMap" usage="basecolor,diffuse"/>
<sampler name="heightMap" usage="height"/>
<sampler name="normalMap" usage="normal"/>
<sampler name="detailNormalMap" usage="detailNormal"/>
<sampler name="environmentMap" usage="environment"/>
<sampler name="bluenoiseMask" usage="bluenoisemask" ishidden="true"/>
<sampler name="sssDiffuseMap" usage="sssDiffuse"/>
</glslfx>
Uniformes
Cela vous permet d’ajouter des informations supplémentaires sur chaque uniforme de shader.
Définition d’élément XML :
Nom : ‘uniforme’
Attributs :
‘name’ : Le nom de l’uniforme dans le fichier shader.
« sémantique » : sémantique de l’uniforme. (Toutes les matrices sont float16).
Exemple :
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
<!-- MATRICES -->
<uniform name="worldMatrix" semantic="world"/>
<uniform name="worldViewProjMatrix" semantic="worldviewprojection"/>
<uniform name="worldViewMatrix" semantic="worldview"/>
<uniform name="worldInverseTransposeMatrix" semantic="worldinversetranspose"/>
<uniform name="viewInverseMatrix" semantic="viewinverse"/>
<uniform name="modelViewMatrix" semantic="modelview"/>
<uniform name="projectionMatrix" semantic="projection"/>
</glslfx>
Exemple :
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
<!-- SCENE PARAMETERS -->
<uniform name="AmbiColor" semantic="ambient"/>
<uniform name="Lamp0Pos" semantic="lightposition0"/>
<uniform name="Lamp0Color" semantic="lightcolor0"/>
<uniform name="Lamp1Pos" semantic="lightposition1"/>
<uniform name="Lamp1Color" semantic="lightcolor1"/>
</glslfx>
Autres paramètres
D’autres renseignements supplémentaires peuvent être ajoutés à chaque uniforme pour :
- définir la valeur par défaut
- valeurs de pince
- contrôler la façon dont l’uniforme sera affiché dans l’application :
- définir le libellé
- définissez les informations de widget utilisées pour modifier la valeur dans l’application :
- nom du widget, min, max, étape d’incrémentation/décrémentation
- groupes d’uniformes dans des widgets de groupe
Comme les uniformes peuvent être remplacés pour chaque technique, cela permet d’afficher une configuration d’interface graphique spécifique pour chaque technique.
Définition d’élément XML :
Nom : ‘uniforme’
Attributs :
- ‘name’ : Le nom de l’uniforme dans le fichier shader.
- ‘default’ : la valeur par défaut uniforme
- ‘min’ : la valeur min de la plage de validité
- ‘max’ : la valeur maximale de la plage de validité
- ‘guiName’ : nom de l’uniforme dans l’interface graphique de l’application
- ‘guiGroup’ : nom du groupe pour placer l’uniforme dans l’interface graphique de l’application
- ‘guiWidget’ : nom du widget utilisé pour modifier la valeur uniforme dans l’interface graphique de l’application
- ‘guiMin’ : valeur min du widget
- ‘guiMax’ : valeur maximale du widget
Exemple : Tessellation/Parallaxe
Fichier de Shader de Vertex Parallax
Situé dans .\tessellation_parallax\parallax\vs.glsl
Contenu :
> #version 120
attribute vec4 iVS_Position ;
attribute vec4 iVS_Normal ;
attribute vec2 iVS_UV ;
attribute vec4 iVS_Tangente ;
attribute vec4 iVS_Binormal ;
variable vec3 iFS_Normal ;
variable vec2 iFS_UV ;
variable vec3 iFS_Tangente ;
vec3 iFS_Binormal variable ;
variable vec3 iFS_PointWS ;
mat4 worldMatrix uniforme ;
mat4 worldViewProjMatrix uniforme ;
void main()
{
gl_Position = worldViewProjMatrix * iVS_Position ;
iFS_Normal = iVS_Normal.xyz ;
iFS_UV = iVS_UV ;
iFS_Tangente = iVS_Tangente.xyz ;
iFS_Binormal = iVS_Binormal.xyz ;
iFS_PointWS = (worldMatrix * iVS_Position).xyz ;
}
Fichier de Shader de Vertex de tessellation
Situé dans .\tessellation_parallax\tessellation\vs.glsl
Contenu :
>>
#version 120
attribute vec4 iVS_Position ;
attribute vec4 iVS_Normal ;
attribute vec2 iVS_UV ;
attribute vec4 iVS_Tangente ;
attribute vec4 iVS_Binormal ;
variable vec4 oVS_Normal ;
variable vec2 oVS_UV ;
variation de vec4 oVS_Tangente ;
vec4 oVS_Binormal variable ;
void main()
{
gl_Position = iVS_Position ;
oVS_Normal = iVS_Normal ;
oVS_UV = iVS_UV ;
oVS_Tangente = iVS_Tangente ;
oVS_Binormal = iVS_Binormal ;
}
Fichier de Shader de contrôle de tessellation
Situé dans .\tessellation_parallax\tessellation\tcs.glsl
Contenu :
>>
#version 400 core
#extension GL_ARB_tessellation_shader : enable
layout(vertex = 3) out ;
in vec4 oVS_Normal[];
in vec2 oVS_UV[];
in vec4 oVS_Tangente[];
in vec4 oVS_Binormal[];
out vec4 oTCS_Normal[];
out vec2 oTCS_UV[];
out vec4 oTCS_Tangente[];
out vec4 oTCS_Binormal[];
facteur de tessellation uniforme du flotteur ;
void main()
{
gl_TessLevelOuter[0] = tessellationFactor ;
gl_TessLevelOuter[1] = tessellationFactor ;
gl_TessLevelOuter[2] = tessellationFactor ;
gl_TessLevelInner[0] = tessellationFactor ;
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position ;
oTCS_Normal[gl_InvocationID] = oVS_Normal[gl_InvocationID];
oTCS_UV[gl_InvocationID] = oVS_UV[gl_InvocationID];
oTCS_Tangente[gl_InvocationID] = oVS_Tangente[gl_InvocationID];
oTCS_Binormal[gl_InvocationID] = oVS_Binormal[gl_InvocationID];
}
Fichier de Shader d’évaluation de tessellation
Situé dans .\tessellation_parallax\tessellation\tcs.glsl
Contenu :
>>
#version 400 core
layout(triangles, equal_espacement, ccw) in ;
in vec4 oTCS_Normal[];
in vec2 oTCS_UV[];
in vec4 oTCS_Tangente[];
in vec4 oTCS_Binormal[];
mat4 worldMatrix uniforme ;
mat4 worldViewProjMatrix uniforme ;
sampler2D heightMap uniforme ;
répétition uniforme du flotteur = 1,0f ;
uniformise float heightMapScale = 1.0f ;
out vec3 iFS_Normal ;
out vec2 iFS_UV ;
out vec3 iFS_Tangente ;
out vec3 iFS_Binormal ;
out vec3 iFS_PointWS ;
vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2, vec3 uvw)
{
return uvw.x * v0 + uvw.y * v1 + uvw.z * v2 ;
}
vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2, vec3 uvw)
{
return uvw.x * v0 + uvw.y * v1 + uvw.z * v2 ;
}
void main()
{
vec3 uvw = gl_TessCoord.xyz ;
vec3 newPos = interpolate3D(gl_in[0].gl_Position.xyz, gl_in[1].gl_Position.xyz, gl_in[2].gl_Position.xyz, uvw);
vec3 newNormal = normalize(interpolate3D(oTCS_Normal[0].xyz, oTCS_Normal[1].xyz, oTCS_Normal[2].xyz, uvw);
vec3 newTangent = normalize(interpolate3D(oTCS_Tangente[0].xyz, oTCS_Tangente[1].xyz, oTCS_Tangente[2].xyz, uvw);
vec3 newBinormal = normalize(interpolate3D(oTCS_Binormal[0].xyz, oTCS_Binormal[1].xyz, oTCS_Binormal[2].xyz, uvw);
vec2 newUV = interpolate2D(oTCS_UV[0], oTCS_UV[1], oTCS_UV[2], uvw);
float heightTexSample = texture(heightMap, newUV * répétition).x * 2.0 - 1.0 ;
newPos += newNormal * heightTexSample * heightMapScale ;
vec4 obj_pos = vec4(newPos, 1);
gl_Position = worldViewProjMatrix * obj_pos ;
iFS_UV = newUV * répétition ;
iFS_Tangente = newTangent ;
iFS_Binormal = newBinormal ;
iFS_Normal = newNormal ;
iFS_PointWS = (worldMatrix * obj_pos).xyz ;
}
Fichier de Shader de fragment
Situé dans .\tessellation_parallax\fs.glsl
Contenu :
>>
#version 120
// #define ALG_NORMAL_DIRECTX
#define ALG_NORMAL_OPENGL
#ifdef ALG_NORMAL_DIRECTX
// #define FLIP_NORMAL_X
SYMÉTRIE #define_NORMALE_Y
// #define FLIP_NORMAL_Z
#endif //#ifdef ALG_NORMAL_DIRECTX
#ifdef ALG_NORMAL_OPENGL
// #define FLIP_NORMAL_X
SYMÉTRIE #define_NORMALE_Y
// #define FLIP_NORMAL_Z
#endif //#ifdef ALG_NORMAL_OPENGL
variable vec3 iFS_Normal ;
variable vec2 iFS_UV ;
variable vec3 iFS_Tangente ;
vec3 iFS_Binormal variable ;
variable vec3 iFS_PointWS ;
uniforme vec3 Lamp0Pos = vec3(0.0f,0.0f,70.0f);
uniforme vec3 Lamp0Color = vec3(1.0f,1.0f,1.0f);
uniforme vec3 Lamp1Pos = vec3(70.0f,0.0f,0.0f);
uniforme vec3 Lamp1Color = vec3(0.198f,0.198f,0.198f);
bool uniforme flipNormal = true ;
Uniform float TilingDetail = 3.0f ;
SpecExpon = 50,0 ;
flotteur uniforme Ks = 1,0 ;
uniforme int parallax_mode = 0 ;
facteur de tessellation uniforme du flotteur = 4,0 ;
uniformise float heightMapScale = 1.0f ;
profondeur uniforme du flotteur_detail = 0.5f ;
flotteur uniforme Kr = 0,5 f ;
int uniforme KF_on = 1 ;
KFs flottants uniformes = 1,0f ;
uniforme vec3 AmbiColor = vec3(0.07f,0.07f,0.07f);
répétition uniforme du flotteur = 1,0f ;
uniforme int enableTilingInFS = 0 ;
sampler2D heightMap uniforme ;
sampler2D normalMap uniforme ;
sampler2D detailNormalMap uniforme ;
sampler2D emissiveMap uniforme ;
sampler2D diffuseMap uniforme ;
specularMap de sampler2D uniforme ;
opacityMap sampler2D uniforme ;
samplerCube environmentMap uniforme ;
mat4 worldMatrix uniforme ;
mat4 worldInverseTransposeMatrix uniforme ;
mat4 viewInverseMatrix uniforme ;
vec4 litFct(float NdotL, float NdotH, float specExp)
{
flottant ambiant = 1,0 ;
diffusion flottante = max(NdotL, 0,0);
specular flottant = step(0.0, NdotL) * pow(max(0.0, NdotH), specExp);
return vec4(ambiante, diffuse, specular, 1,0);
}
vec3 lerpFct(vec3 v0, vec3 v1, float percent)
{
return v0 + (v1-v0) * %;
}
// Phong Ombrage
void phong_ombrage(
dans vec3 LightColor,
dans vec3 normalWS,
dans vec3 pointToLightDirWS,
dans vec3 pointToCameraDirWS,
inout vec3 DiffuseContrib,
inout vec3 SpecularContrib)
{
vec3 Hn = normalize(pointToCameraDirWS + pointToLightDirWS);
vec4 litV = litFct(dot(normalWS, pointToLightDirWS), dot(normalWS, Hn), SpecExpon);
DiffuseContrib = litV.y * LightColor ;
SpecularContrib = litV.y * litV.z * Ks * LightColor ;
}
vec3 fixNormalSample(vec3 v)
{
vec3 résultat = v - vec3(0.5,0.5,0.5);
SYMÉTRIE #ifdef_NORMALE_X
result.x = -result.x ;
#endif // ifdef FLIP_NORMAL_X
SYMÉTRIE #ifdef_NORMALE_Y
result.y = -result.y ;
#endif // ifdef FLIP_NORMAL_Y
SYMÉTRIE #ifdef_NORMALE_Z
result.z = -result.z ;
#endif // ifdef FLIP_NORMAL_Z
résultat du retour ;
}
vec3 normalVecOSToWS(vec3 normal)
{
retour normal ;
}
void main()
{
vec3 cameraPosWS = viewInverseMatrix[3].xyz ;
vec3 pointToLight0DirWS = normalize(Lamp0Pos - iFS_PointWS);
vec3 pointToLight1DirWS = normalize(Lamp1Pos - iFS_PointWS);
vec3 pointToCameraDirWS = normalize(cameraPosWS);
vec3 normalOS = normalize(iFS_Normal);
vec3 tangentOS = normalize(iFS_Tangente);
vec3 binormalOS = normalize(iFS_Binormal);
// ------------------------------------------
// S’assurer que le TBN est orthonormé
binormalOS = normalize(cross(normalOS, tangentOS));
tangentOS = normalize(cross(binormalOS, normalOS));
vec3 cumulatedNormalOS = normalOS;
// ------------------------------------------
// Mettre à jour l’UV
float a = dot(normalOS,-pointToCameraDirWS);
vec3 s = vec3(dot(pointToCameraDirWS,tangentOS), dot(pointToCameraDirWS,binormalOS), a);
vec2 uv = enableTilingInFS == 0 ? iFS_UV : (répétition iFS_UV *);
height float = texture 2D(heightMap,uv).x * 2.0 - 1.0 ;
float parallax = parallax_mode == 0 ? (tessellationFactor / 100000.f + heightMapScale / 500.f) : (heightMapScale / 50.f);
+= uv (height * s.xy * parallaxe) ;
// ------------------------------------------
// Ajouter la normale à partir de normalMap
vec3 normalTS = texture 2D(normalMap,uv).xyz ;
normalTS = fixNormalSample(normalTS);
vec3 normalMapOS = normalTS.x*tangentOS + normalTS.y*binormalOS ;
cumulatedNormalOS = cumulatedNormalOS + normalMapOS;
cumulatedNormalOS = normalize(cumulatedNormalOS);
// ------------------------------------------
// Ajouter un mappage normal détaillé
vec3 normalDetailTS = texture 2D(detailNormalMap,uv*TilingDetail).xyz ;
normalDetailTS = fixNormalSample(normalDetailTS);
vec3 variableNormalDetailTS = lerpFct(vec3(0.0,0.0,0.5),normalDetailTS,Profondeur_detail);
vec3 normalDetailOS = variableNormalDetailTS.x*tangentOS + variableNormalDetailTS.y*binormalOS ;
cumulatedNormalOS = cumulatedNormalOS + normalDetailOS ;
cumulatedNormalOS = normalize(cumulatedNormalOS);
if (length(normalTS)<0.0001)
cumulatedNormalOS = normalOS;
vec3 cumulatedNormalWS = normalVecOSToWS(cumulatedNormalOS);
// ------------------------------------------
// Calculer Diffuse et Specular
// Contribution Light 0
vec3 diffContrib = vec3(0, 0, 0);
vec3 specContrib = vec3(0, 0, 0);
phong_ombrage(Lamp0Color, cumulatedNormalWS, pointToLight0DirWS, pointToCameraDirWS, diffContrib, specContrib);
// Contribution Light 1
vec3 diffContrib2 = vec3(0, 0, 0);
vec3 specContrib2 = vec3(0, 0, 0);
phong_ombrage(Lamp1Color, cumulatedNormalWS, pointToLight1DirWS, pointToCameraDirWS, diffContrib2, specContrib2);
diffContrib += diffContrib2 ;
specContrib += specContrib2 ;
vec4 diffuseColor = texture 2D(diffuseMap,uv);
vec3 specularColor = texture 2D(specularMap,uv).rgb ;
vec3 R = reflect(pointToCameraDirWS, cumulatedNormalWS);
vec3 reflColor = Kr * textureCube(environmentMap,R.xyz).bgr ;
float FallofRefl ;
if (KFs >= 0,0)
FallofRefl = max((1-dot(pointToCameraDirWS/(KFs),cumulatedNormalWS)),0)*KF_on ;
else
FallofRefl = (1-max(((1-dot(pointToCameraDirWS/(-KFs),cumulatedNormalWS))),0))*KF_on ;
if (KF_on == 0)
FallofRefl=1,0 ;
vec3 Ambiant_final = diffuseColor.rgb*AmbiColor ;
// ------------------------------------------
vec3 emissive = texture 2D(emissiveMap,uv).xyz ;
vec3 finalcolor = Ambiant_final
+ specularColor*specContrib
+ diffuseColor.rgb*diffContrib
+ (reflColor*specularColor*FallofRefl)
+ EMISSIVE ;
// Couleur finale
vec4 finalColor4 = vec4(finalcolor, texture 2D(opacityMap,uv));
gl_FragColor = finalColor4 ;
}
Fichier GLSLFX
Le fichier glslfx définit deux techniques de rendu de la géométrie :
- On utilise la technique de la tessellation matérielle
- L’autre repose sur un effet de parallaxe qui sera utilisé comme solution de secours si le matériel de l’utilisateur ne prend pas en charge la Tessellation.
Situé dans .\tessellation_parallax\fs.glsl
Contenu :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sbsbatchnode SYSTEM "glslfx.dtd">
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- TECHNIQUES -->
<technique name="Tesselation">
<!-- PROPERTIES -->
<property name="blend_enabled" value="true"/>
<property name="blend_func" value="src_alpha,one_minus_src_alpha"/>
<property name="cull_face_enabled" value="true"/>
<property name="cull_face_mode" value="back"/>
<!-- SHADERS -->
<shader type="vertex" filename="tessellation_parallax/tessellation/vs.glsl" primitiveType="patch4"/>
<shader type="tess_control" filename="tessellation_parallax/tessellation/tcs.glsl"/>
<shader type="tess_eval" filename="tessellation_parallax/tessellation/tes.glsl"/>
<shader type="fragment" filename="tessellation_parallax/fs.glsl"/>
<!-- UNIFORMS -->
<uniform name="parallax_mode" guiName="Parallax Mode" min="0" max="0" />
<uniform name="enableTilingInFS" guiName="Tiling Enabled In FS" min="0" max="0" />
<uniform name="tessellationFactor" guiName="Tessellation Factor" default="4" min="1" max="64" guiStep="1" guiWidget="slider"/>
</technique>
<technique name="Parallax">
<!-- PROPERTIES -->
<property name="blend_enabled" value="true"/>
<property name="blend_func" value="src_alpha,one_minus_src_alpha"/>
<property name="cull_face_enabled" value="true"/>
<property name="cull_face_mode" value="back"/>
<!-- SHADERS -->
<shader type="vertex" filename="tessellation_parallax/parallax/vs.glsl"/>
<shader type="fragment" filename="tessellation_parallax/fs.glsl"/>
<!-- UNIFORMS -->
<uniform name="parallax_mode" guiName="Parallax Mode" min="1" max="1" />
<uniform name="enableTilingInFS" guiName="Tiling Enabled In FS" min="1" max="1" />
</technique>
<!-- INPUT VERTEX FORMAT -->
<vertexformat name="iVS_Position" semantic="position"/>
<vertexformat name="iVS_Normal" semantic="normal"/>
<vertexformat name="iVS_UV" semantic="texcoord0"/>
<vertexformat name="iVS_Tangent" semantic="tangent0"/>
<vertexformat name="iVS_Binormal" semantic="binormal0"/>
<!-- SAMPLERS -->
<sampler name="diffuseMap" usage="diffuse"/>
<sampler name="heightMap" usage="height"/>
<sampler name="normalMap" usage="normal"/>
<sampler name="detailNormalMap" usage="detailNormal"/>
<sampler name="emissiveMap" usage="emissive"/>
<sampler name="specularMap" usage="specular"/>
<sampler name="opacityMap" usage="opacity"/>
<sampler name="environmentMap" usage="environment"/>
<!-- MATRICES -->
<uniform name="worldMatrix" semantic="world"/>
<uniform name="worldViewProjMatrix" semantic="worldviewprojection"/>
<uniform name="worldViewMatrix" semantic="worldview"/>
<uniform name="worldInverseTransposeMatrix" semantic="worldinversetranspose"/>
<uniform name="viewInverseMatrix" semantic="viewinverse"/>
<uniform name="modelViewMatrix" semantic="modelview"/>
<uniform name="projectionMatrix" semantic="projection"/>
<!-- SCENE PARAMETERS -->
<uniform name="AmbiColor" semantic="ambient"/>
<uniform name="Lamp0Pos" semantic="lightposition0"/>
<uniform name="Lamp0Color" semantic="lightcolor0"/>
<uniform name="Lamp1Pos" semantic="lightposition1"/>
<uniform name="Lamp1Color" semantic="lightcolor1"/>
<!-- UNIFORMS -->
<uniform name="tiling" guiName="Tiling" default="1" min="1" guiWidget="slider" guiMax="10"/>
<uniform name="heightMapScale" guiGroup="Height" guiName="Scale" default="1" min="0" guiWidget="slider" guiMin="-50" guiMax="50" />
<uniform name="TilingDetail" guiGroup="Detail Normal" guiName="Tiling" default="3" min="1" guiWidget="slider" guiMax="10"/>
<uniform name="Depth_detail" guiGroup="Detail Normal" guiName="Intensity" default="0.5" min="0" max="1" guiStep="0.05" guiWidget="slider"/>
<uniform name="SpecExpon" guiGroup="Specular" guiName="Power" default="50" min="1" guiWidget="slider" guiMax="128"/>
<uniform name="Ks" guiGroup="Specular" guiName="Intensity" default="1" min="0" guiWidget="slider" guiMax="3"/>
<uniform name="Kr" guiGroup="Reflection" guiName="Intensity" default="0.5" min="0" max="1" guiStep="0.01" guiWidget="slider"/>
<uniform name="KF_on" guiGroup="Reflection" guiName="Falloff" default="1" min="0" max="1" guiStep="1" guiWidget="slider"/>
<uniform name="KFs" guiGroup="Reflection" guiName="Falloff Size" default="1" min="-1" max="1" guiStep="0.05" guiWidget="slider"/>
</glslfx>