GLSLFX Shaders
GLSLFX bilden die Brücke zwischen der Anwendung und den GLS-Shader-Dateien.
Es ermöglicht die Verwendung eines beliebigen glsl-Shader, ohne den Code ändern zu müssen.
Dateiformat
GLSLFX ist eine XML-Datei. Kommentare werden unterstützt.
Kopf- und Stammknoten
Das XML-Stammknotenelement hat den Namen glslfx.
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
</glslfx>
Body
Technik
XML-Element, das eine Technik beschreibt. Eine Technik ist eine Variante des aktuellen FX. Ein GLSLFX kann mehrere Techniken enthalten, aber mindestens eine Technik muss definiert werden.
Die Geometrie wird mit einer der in der Anwendung definierten Techniken gerendert.
Attribute:
- Name: Beliebige Zeichenfolge, die zum Benennen der Technik verwendet wird
Das XML-Element kann mehrere untergeordnete Elemente haben. Die in einer Technik definierten Elemente überschreiben die global definierten Elemente.
Sie wird beispielsweise verwendet, um bestimmte Uniformwerte zu überschreiben und FX-Variationen für diese Technik zu erhalten.
Renderdurchgang
XML-Element, das eine Renderdurchlauf beschreibt. Ein Renderdurchgang beschreibt das Rendern der Geometrie.
Eine Technik kann mehrere Renderdurchläufe enthalten, die nacheinander ausgeführt werden. Eine Technik, die keinen Renderdurchgang enthält, entspricht einer Technik, die einen “On-Screen”-Renderdurchgang enthält.
Die in einem Renderdurchlauf definierten Elemente überschreiben die in der übergeordneten Technik definierten Elemente.
Attribute:
-
Ausgabe
-
offscreen: Das Rendering erfolgt in benutzerdefinierten Renderzielen.
-
auf dem Bildschirm: Das Rendering erfolgt im Standard-Renderziel
Shader
Legen Sie die GLSL-Shader-Dateien für jeden Typ fest.
XML-Elementdefinition:
Attribute:
-
Typ: Typ des GLSL-Shaders;
-
Dateiname: Der Pfad der GLS-Shader-Datei. Kann absolut oder relativ zur GLSLFX Datei sein;
-
primitiveType: Die Methode zum Rendern der Grundform.
| table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 5-row-2 | |
|---|---|
| ‘type’-Wert | Beschreibung |
| Scheitelpunkt | Scheitelpunkt Shader |
| Geometrie | Geometry-Shader |
| tess_control | Tessellation Control Shader |
| tess_eval | Shader zur Bewertung der Tessellation |
| Fragment | Fragment-Shader |
| table 0-row-2 1-row-2 2-row-2 3-row-2 | |
|---|---|
| primitiveType-Wert | Beschreibung |
| Punkt | Als Punkte rendern |
| Linienführung | Als Zeilenschleife rendern |
| Patch[1.N] | Als Patches mit [1…N] Scheitelpunkten rendern |
Eigenschaften
Erlauben Sie, einen Teil des OpenGL-Status einzurichten.
Attribute:
-
Name: Der Name der festzulegenden Eigenschaft. Der Name basiert auf der OpenGL-Funktion oder dem glEnum-Namen:
- Enumerationssyntax: Ohne das Präfix “GL_”, in Kleinbuchstaben. Beispiele: glEnable(GL_ÜBERBLENDUNG_ENABLE) => “”, glDisable(GL_CULL_FLÄCHE) => “”"
- Funktionssyntax: ohne das Präfix “gl”, in Kleinbuchstaben und mit allen Wörtern, die durch das Zeichen “_” getrennt sind. Beispiel: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) => “”
-
Enumerationssyntax: Ohne das Präfix “GL_”, in Kleinbuchstaben. Beispiele: glEnable(GL_ÜBERBLENDUNG_ENABLE) => “”, glDisable(GL_CULL_FLÄCHE) => “”"
-
Funktionssyntax: ohne das Präfix “gl”, in Kleinbuchstaben und mit allen Wörtern, die durch das Zeichen “_” getrennt sind. Beispiel: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) => “”
-
Wert: Der Wert der Eigenschaft.
| 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 | ||
|---|---|---|
| Namenswerte | ‘value’ Werte | Beschreibung |
| blend_enabled | boolesch | Mischmodus aktivieren/deaktivieren |
| true | ||
| false | ||
| blend_func | Zeichenfolge, Zeichenfolge | Festlegen der Funktionen für Quellen und Ziel-Überblendung |
| Null | für OpenGL enum GL_ZERO | |
| eins | für OpenGL enum GL_ONE | |
| src_color | für OpenGL enum GL_SRC_COLOR | |
| one_minus_src_color | für OpenGL-Enumeration GL_ONE_MINUS_SRC_COLOR | |
| dst_color | für OpenGL enum GL_DST_COLOR | |
| one_minus_dst_color | für OpenGL-Enumeration GL_ONE_MINUS_DST_COLOR | |
| src_alpha | für OpenGL enum GL_SRC_ALPHA | |
| one_minus_src_alpha | für OpenGL-Enumeration GL_ONE_MINUS_SRC_ALPHA | |
| dst_alpha | für OpenGL enum GL_DST_ALPHA | |
| one_minus_dst_alpha | für OpenGL-Enumeration GL_ONE_MINUS_DST_ALPHA | |
| Konstante_Farbe | für OpenGL enum GL_CONSTANT_COLOR | |
| one_minus_constant_color | für OpenGL-Enumeration GL_ONE_MINUS_CONSTANT_COLOR | |
| Konstante_Alpha | für OpenGL enum GL_CONSTANT_ALPHA | |
| one_minus_constant_alpha | für OpenGL-Enumeration GL_ONE_MINUS_CONSTANT_ALPHA | |
| src_alpha_saturate | für OpenGL-Enumeration GL_SRC_ALPHA_SATURATE | |
| src1_color | für OpenGL enum GL_SRC1_COLOR | |
| one_minus_src1_color | für OpenGL-Enumeration GL_ONE_MINUS_SRC1_COLOR | |
| src1_alpha | für OpenGL enum GL_SRC1_ALPHA | |
| one_minus_src1_alpha | für OpenGL-Enumeration GL_ONE_MINUS_SRC1_ALPHA | |
| cull_Fläche_enabled | boolesch | Aktivieren/Deaktivieren der Fläche-Keulung |
| true | ||
| false | ||
| cull_Fläche_mode | String | Festlegen des Füllmodus für die Fläche |
| Front | für OpenGL enum GL_FRONT | |
| Rückseite | für OpenGL enum GL_BACK | |
| front_and_back | für OpenGL-Enumeration GL_FRONT_AND_BACK | |
| Tiefe_Funktion | String | Tiefe-Vergleichsfunktion einstellen |
| nie | für OpenGL enum GL_NEVER | |
| weniger | für OpenGL enum GL_LESS | |
| legal | für OpenGL enum GL_LEQUAL | |
| Gleichgestellter | für OpenGL enum GL_EQUAL | |
| ungleich | für OpenGL enum GL_NOTEQUAL | |
| Gequal | für OpenGL enum GL_GEQUAL | |
| größer | für OpenGL enum GL_GREATER | |
| Immer | für OpenGL enum GL_ALWAYS |
Uniformen
Erlaubt das Überschreiben einiger Uniformen, die global oder in der übergeordneten Technik definiert sind. Dies ermöglicht es, das Shader-Verhalten für diese Technik oder diesen Renderdurchgang zu ändern.
Weitere Informationen zu ihrer Definition finden Sie im Abschnitt Uniforms weiter unten.
+++Beispiel
+++
Renderziele
Bei “Offscreen”-Renderdurchläufen müssen Renderziele im Renderdurchlauf definiert werden.
Attribute:
- Anlage: Der OpenGL-Anfügepunkt, inspiriert von den OpenGL-Namen:
GL_COLOR_ATTACHMENT[0.3] => ‘color[0.3]’
GL_TIEFE_ANLAGE => ‘Tiefe’
Anlage: Der OpenGL-Anfügepunkt, inspiriert von den OpenGL-Namen:
GL_COLOR_ATTACHMENT[0.3] => ‘color[0.3]’
GL_TIEFE_ANLAGE => ‘Tiefe’
- Name: den Namen des Renderziels.
Sie kann in einem späteren Renderdurchgang verwendet werden, um dieses Renderziel als Sampler zu binden.
Name: den Namen des Renderziels.
Sie kann in einem späteren Renderdurchgang verwendet werden, um dieses Renderziel als Sampler zu binden.
- Format: das interne Format des Renderziels.
Format: das interne Format des Renderziels.
- klar: optionales Attribut, das einen Clear-Wert definiert.
Wenn vorhanden, wird das Renderziel zu Beginn des Renderdurchgangs auf diesen Wert gelöscht.
Wenn das Renderziel fehlt, bleibt der vorherige Inhalt erhalten.
Formate
Bei Tiefe-Formaten werden alle OpenGL-Formate nur für Tiefe (keine Schablone) unterstützt:
- GL_TIEFE_COMPONENT16 => ‘Tiefe26’
- GL_TIEFE_COMPONENT24 => ‘Tiefe34’
- GL_TIEFE_COMPONENT32 => ‘Tiefe42’
- GL_TIEFE_COMPONENT32F => ‘Tiefe42f’
Bei Farbformaten basiert der Name auf OpenGL-Enumerationsnamen, in Kleinbuchstaben ohne das Präfix “GL_”.
Drei Kanalformate (RGB) werden nicht unterstützt. Verwenden Sie stattdessen ein RGBA-Format.
Unterstützte Bittiefe pro Kanal:
- Normalisierte Ganzzahl ohne Vorzeichen: 8, 16
- Gleitkomma: 16, 32
Eine Ausnahme von diesen Regeln ist das GL_R11F_G11F_B10F, das unterstützt wird:
- GL_RGBA8 =>‘rgba8’
- GL_RGBA16F =>‘rgba16f’
- GL_SRGB8_ALPHA8 => ‘srgb8_alpha8’
- GL_R11F_G11F_B10F => ‘r11f_g11f_b10f’
- GL_RG16 => “rg16”
Sampler
Erlaubt das Überschreiben einiger global definierter Sampler. Diese können nicht in einer Technik definiert werden. Dies ermöglicht es, eine Samplerverwendung für diesen Renderdurchgang zu definieren oder von einem Renderziel eines vorherigen Renderdurchgangs zu lesen.
Weitere Informationen zu ihrer Definition finden Sie im Abschnitt Samplers.
+++Beispiel
+++
Eingabescheitelpunktformat
Dadurch können Sie die Semantik der einzelnen Attribute definieren, die im Vertexshader definiert werden.
XML-Elementdefinition:
Name: vertexformat
Attribute:
- ‘name’: Der Name des Attributs, wie im Vertexshader definiert.
- “semantisch”: Die Semantik des Attributs.
Beispiel:
<?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>
Sampler
Dadurch kann die Verwendung der einzelnen Sampler definiert werden.
Sie wird von der Anwendung verwendet, um zu wissen, welche Textur in den angegebenen Samplern eingestellt werden soll.
XML-Elementdefinition:
Name: “Probenehmer”
Attribute:
- ‘name’: Der Name der Samplervariable in der Shader-Datei.
- ‘Nutzung’: Die Verwendung des Samplers. Sie entspricht der im Ausgabeknoten des Grafen angegebenen Verwendung.
- Es werden mehrere Verwendungen unterstützt.
- Beispiel:
<!-- SAMPLERS -->
<sampler name="baseColorMap" usage="basecolor,diffuse"/>
<!-- ... -->
‘isHidden’: Boolescher Wert, der angibt, ob der Sampler in der GUI angezeigt werden soll
- Beispiel:
<!-- SAMPLERS -->
<sampler name="bluenoiseMask" usage="bluenoisemask" ishidden="true"/>
<!-- ... -->
Umbruchmodus:
Texturfilter
Beispiel:
<?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>
Uniformen
Auf diese Weise können Sie zusätzliche Informationen zu jeder Shader-Uniform hinzufügen.
XML-Elementdefinition:
Name: “Uniform”
Attribute:
‘name’: Der Name der Uniform in der Shader-Datei.
“semantisch”: Die Semantik der Uniform. (Alle Matrizen sind float16).
Beispiel:
<?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>
Beispiel:
<?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>
Andere Parameter
Weitere zusätzliche Informationen können zu jeder Uniform hinzugefügt werden:
- den Standardwert definieren
- Spannwerte
- steuert, wie die Uniform in der Anwendung angezeigt wird:
- Aufkleber festlegen
- Festlegen der Widget-Informationen, die zum Bearbeiten des Werts in der Anwendung verwendet werden:
- Widget-Name, min, max, Schritt zum Erhöhen/Verringern
- Gruppenuniformen in Gruppen-Widgets
Da die Uniformen für jede Technik überschrieben werden können, kann für jede Technik eine bestimmte GUI-Einrichtung angezeigt werden.
XML-Elementdefinition:
Name: “Uniform”
Attribute:
- ‘name’: Der Name der Uniform in der Shader-Datei.
- ‘default’: Der einheitliche Standardwert
- ‘min’: Der Minimalwert des Gültigkeitsbereichs
- ‘max’: Der Höchstwert des Gültigkeitsbereichs
- ‘guiName’: Der Name der Uniform in der GUI der Anwendung
- ‘guiGroup’: Der Name der Gruppe, die die Uniform in die GUI der Anwendung einfügen soll
- ‘guiWidget’: Der Name des Widgets, das zum Bearbeiten des einheitlichen Werts in der Benutzeroberfläche der Anwendung verwendet wird
- ‘guiMin’: Der Mindestwert des Widgets
- ‘guiMax’: Der Höchstwert des Widgets
Beispiel: Tessellation/Parallaxe
Parallax Scheitelpunkt Shader File
In .\tessellation_parallax\parallax\vs.glsl
Inhalt:
> #version 120
Attribut vec4 iVS_Position;
Attribut vec4 iVS_Normal;
Attribut vec2 iVS_UV;
-Attribut vec4 iVS_Tangente;
Attribut vec4 iVS_Binormal;
variierendes vec3 iFS_Normal;
variierendes vec2 iFS_UV;
variierendes vec3 iFS_Tangente;
variierendes vec3 iFS_Binormal;
variierendes vec3 iFS_PointWS;
Uniform Mat4 WorldMatrix;
uniform mat4 worldViewProjMatrix;
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;
}
Tesselation Vertex Shader-Datei
In .\tessellation_parallax\tessellation\vs.glsl
Inhalt:
>>
#version 120
Attribut vec4 iVS_Position;
Attribut vec4 iVS_Normal;
Attribut vec2 iVS_UV;
Attribut vec4 iVS_Tangent;
Attribut vec4 iVS_Binormal;
variierendes vec4 oVS_Normal;
variierendes vec2 oVS_UV;
variierendes vec4 oVS_Tangent;
variierendes vec4 oVS_Binormal;
void main()
{
gl_Position = iVS_Position;
oVS_Normal = iVS_Normal;
oVS_UV = iVS_UV;
oVS_Tangent = iVS_Tangent;
oVS_Binormal = iVS_Binormal;
}
Tesselierungssteuerungsschattierungsdatei
In .\tessellation_parallax\tessellation\tcs.glsl
Inhalt:
>>
#version 400 Core
#extension GL_ARB_tessellation_shader : befähigen
layout(vertices = 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[];
uniform float tesselationFactor;
void main()
{
gl_TessLevelOuter[0] = tesselationFactor;
gl_TessLevelOuter[1] = tesselationFactor;
gl_TessLevelOuter[2] = tesselationFactor;
gl_TessLevelInner[0] = tesselationFactor;
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_Tangent[gl_InvocationID] = oVS_Tangent[gl_InvocationID];
oTCS_Binormal[gl_InvocationID] = oVS_Binormal[gl_InvocationID];
}
Tesselierungsauswertung Shader-Datei
In .\tessellation_parallax\tessellation\tcs.glsl
Inhalt:
>>
#version 400 Core
layout(triangles, equal_spacing, ccw) in;
in vec4 TCS_Normal[];
in vec2 oTCS_UV[];
in vec4 TCS_Tangent[];
in vec4 TCS_Binormal[];
Uniform Mat4 WorldMatrix;
uniform mat4 worldViewProjMatrix;
Uniform Sampler2D heightMap;
Kacheln mit gleichmäßigem Schwimmer = 1,0f;
uniform float heightMapScale = 1.0f;
out vec3 iFS_Normal;
out vec2 iFS_UV;
out vec3 iFS_Tangent;
out vec3 iFS_Binormal;
out vec3 iFS_PointWS;
vec3 interpolieren3D(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_Tangent[0].xyz, oTCS_Tangent[1].xyz, oTCS_Tangent[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 heightTextSample = texture(heightMap, newUV * tiling).x * 2.0 - 1.0;
newPos += newNormal * heightTextSample * heightMapScale;
vec4 obj_pos = vec4(newPos, 1);
gl_Position = worldViewProjMatrix * obj_pos;
iFS_UV = newUV * Kachelung;
iFS_Tangent = newTangent;
iFS_Binormal = newBinormal;
iFS_Normal = newNormal;
iFS_PointWS = (worldMatrix * obj_pos).xyz;
}
Fragment Shader File
In .\tessellation_parallax\fs.glsl
Inhalt:
>>
#version 120
// #define ALG_NORMAL_DIRECTX
#define ALG_NORMAL_OPENGL
#ifdef ALG_NORMAL_DIRECTX
// #define FLIP_NORMAL_X
#define FLIP_NORMAL_Y
// #define FLIP_NORMAL_Z
#endif //#ifdef ALG_NORMAL_DIRECTX
#ifdef ALG_NORMAL_OPENGL
// #define FLIP_NORMAL_X
#define FLIP_NORMAL_Y
// #define FLIP_NORMAL_Z
#endif //#ifdef ALG_NORMAL_OPENGL
variierendes vec3 iFS_Normal;
variierendes vec2 iFS_UV;
variierendes vec3 iFS_Tangent;
variierendes vec3 iFS_Binormal;
variierendes vec3 iFS_PointWS;
uniform vec3 Lamp0Pos = vec3(0.0f,0.0f,70.0f);
uniform vec3 Lamp0Color = vec3(1.0f,1.0f,1.0f);
uniform vec3 Lamp1Pos = vec3(70.0f,0.0f,0.0f);
uniform vec3 Lamp1Color = vec3(0,198f,0,198f,0,198f);
Normal = true;
Uniform Float TilingDetail = 3.0f;
Specexpon = 50,0;
Gleichmäßiger Schwimmer Ks = 1,0;
uniform int parallax_mode = 0;
uniform float tesselationFactor = 4.0;
uniform float heightMapScale = 1.0f;
uniform float Tiefe_detail = 0,5f;
einheitlicher Schwimmer Kr = 0,5f;
uniform int KF_on = 1;
KFs = 1,0f;
uniform vec3 AmbiColor = vec3(0,07f,0,07f,0,07f);
Kacheln mit gleichmäßigem Schwimmer = 1,0f;
uniform int enableTilingInFS = 0;
Uniform Sampler2D heightMap;
Uniform Sampler2D normalMap;
uniform sampler2D detailNormalMap;
Uniform Sampler2D emissiveMap;
Uniform Sampler2D DiffuseMap;
uniform sampler2D specularMap;
uniform sampler2D opacityMap;
uniform samplerCube environmentMap;
Uniform Mat4 WorldMatrix;
Uniform mat4 worldInverseTransposeMatrix;
uniform mat4 viewInverseMatrix;
vec4 litFct(float NdotL, float NdotH, float specExp)
{
float ambient = 1,0;
float diffuse = max(NdotL, 0,0);
float Specular = step(0.0, NdotL) * pow(max(0.0, NdotH), specExp);
return vec4(ambient, diffuse, Specular, 1.0);
}
vec3 lerpFct(vec3 v0, vec3 v1, float percent)
{
return v0 + (v1-v0) * percent;
}
// Phong-Schattierung
void phong_Schattierung(
in vec3 LightColor,
in vec3 normalWS,
in vec3 pointToLightDirWS,
in 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 result = v - vec3(0,5,0,5,0,5);
#ifdef FLIP_NORMAL_X
result.x = -result.x;
#endif // ifdef FLIP_NORMAL_X
#ifdef FLIP_NORMAL_Y
result.y = -result.y;
#endif // ifdef FLIP_NORMAL_Y
#ifdef FLIP_NORMAL_Z
result.z = -result.z;
#endif // ifdef FLIP_NORMAL_Z
Rückgabeergebnis;
}
vec3 normalVecOSToWS(vec3 normal)
{
normale Rückkehr;
}
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_Tangent);
vec3 binormalOS = normalize(iFS_Binormal);
// ------------------------------------------
// Vergewissern Sie sich, dass die TBN orthonormalisiert ist
binormalOS = normalize(cross(normalOS, tangentOS));
tangentOS = normalize(cross(binormalOS, normalOS));
vec3 cumulatedNormalOS = normalOS;
// ------------------------------------------
// Update UV
float a = dot(normalOS,-pointToCameraDirWS);
vec3 s = vec3(dot(pointToCameraDirWS,tangentOS), dot(pointToCameraDirWS,binormalOS), a);
vec2 uv = enableTilingInFS == 0 ? iFS_UV : (iFS_UV * Tiling);
float Height = texture2D(heightMap,uv).x * 2.0 - 1.0 ;
float parallax = parallax_mode == 0 ? (tesselationFactor / 100000.f + heightMapScale / 500.f) : (heightMapScale / 50.f);
uv += (Height * s.xy * Parallaxe);
// ------------------------------------------
// Add Normal from normalMap
vec3 normalTS = texture2D(normalMap,uv).xyz;
normalTS = fixNormalSample(normalTS);
vec3 normalMapOS = normalTS.x*tangentOS + normalTS.y*binormalOS;
cumulatedNormalOS = cumulatedNormalOS + normalMapOS;
cumulatedNormalOS = normalize(cumulatedNormalOS);
// ------------------------------------------
// Details zur Normalmap hinzufügen
vec3 normalDetailTS = texture2D(detailNormalMap,uv*TilingDetail).xyz;
normalDetailTS = fixNormalSample(normalDetailTS);
vec3 variableNormalDetailTS = lerpFct(vec3(0.0,0.0,0.5),normalDetailTS,Tiefe_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);
// ------------------------------------------
// Compute Diffuse & Specular
// Lichtspende 0
vec3 diffContrib = vec3(0, 0, 0);
vec3 specContrib = vec3(0, 0, 0);
phong_Schattierung(Lamp0Color, cumulatedNormalWS, pointToLight0DirWS, pointToCameraDirWS, diffContrib, specContrib);
// Lichtbeitrag 1
vec3 diffContrib2 = vec3(0, 0, 0);
vec3 specContrib2 = vec3(0, 0, 0);
phong_Schattierung(Lamp1Color, cumulatedNormalWS, pointToLight1DirWS, pointToCameraDirWS, diffContrib2, specContrib2);
diffContrib += diffContrib2;
specContrib += specContrib2;
vec4 diffuseColor = texture2D(diffuseMap,uv);
vec3 specularColor = texture2D(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;
sonst
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 = Textur2D(emissiveMap,uv).xyz;
vec3 finalcolor = Ambiant_final
+ specularColor*specContrib
+ diffuseColor.rgb*diffContrib
+ (reflColor*specularColor*FallofRefl)
+ emissive;
// Final Color
vec4 finalColor4 = vec4(finalColor, Textur2D(opacityMap,uv));
gl_FragColor = finalColor4;
}
GLSLFX
Die glslfx-Datei definiert zwei Techniken zum Rendern der Geometrie:
- Man verwendet die Hardware-Tessellation-Technik
- Der andere basiert auf einem Parallaxeffekt, der als Fallback verwendet wird, wenn die Benutzerhardware die Tessellation nicht unterstützt.
In .\tessellation_parallax\fs.glsl
Inhalt:
<?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>