User Guide Cancel

GLSLFX Shaders | Substance 3D Designer

GLSLFX Shaders

GLSLFX files make the bridge between the application and the glsl shader files.
It allows to use any glsl shader without having to modify the code.


File Format

GLSLFX file format is a XML file. Comments are supported.

Header and Root node

The XML root node element is named glslfx.

<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
<!-- BODY -->
<!-- ... -->
</glslfx>
<?xml version="1.0" encoding="UTF-8"?> <glslfx version="1.0.0" author="allegorithmic.com"> <!-- BODY --> <!-- ... --> </glslfx>
<?xml version="1.0" encoding="UTF-8"?>
<glslfx version="1.0.0" author="allegorithmic.com">
    <!-- BODY -->
    <!-- ... -->
</glslfx>

Body

Technique

XML Element that describes a technique. A technique is a variation of the current FX. A GLSLFX can contain multiple techniques but at least one technique has to be defined.

The geometry will be rendered with one of the techniques defined by the application.

The XML element can have multiples children. The elements defined in a techniques override the elements defined globally.

For example, it is used to override some uniforms values and obtain FX variation for this technique.

Render Pass

XML Element that describes a render pass. A render pass describes the rendering of the geometry.

A technique can contain multiple render passes that will be executed sequentially. A technique containing no render pass is equivalent to a technique containing an 'onscreen' render pass.

The elements defined in a render pass override the elements defined in the parent technique.

Shaders

Set the GLSL shader files for each type.

XML Element Definition:

Properties

Allow to set up some part of the OpenGL state.

Uniforms

Allow to override some uniforms defined globally or in the parent technique. This allow to change shader behavior for this technique or render pass.

See the Uniforms section below for more details about their definition.

Render Targets

For 'offscreen' render passes, render targets must be defined in the render pass.

Note:

Color render targets are forbidden in an 'onscreen' render pass, but a depth render target can be shared with any render pass (but it's likely to break rendering when mixing multiple materials in the scene).

About formats

For depth formats, all depth-only (no stencil) OpenGL formats are supported:

  • GL_DEPTH_COMPONENT16 => 'depth26'
  • GL_DEPTH_COMPONENT24 => 'depth34'
  • GL_DEPTH_COMPONENT32 => 'depth42'
  • GL_DEPTH_COMPONENT32F => 'depth42f'

For color formats, the name is based on OpenGL enum names, without the 'GL_' prefix, in lower case.
Three channel formats (RGB) are not supported, use an RGBA format instead.
Bit depth per channel supported:

  • Normalized unsigned integer: 8, 16
  • Floating point: 16, 32

An exception to these rules is the GL_R11F_G11F_B10F format which is supported.:

  • GL_RGBA8 => 'rgba8'
  • GL_RGBA16F => 'rgba16f'
  • GL_SRGB8_ALPHA8 => 'srgb8_alpha8'
  • GL_R11F_G11F_B10F => 'r11f_g11f_b10f'
  • GL_RG16 => "rg16"

Samplers

Allow to override some samplers defined globally, they cannot be defined in a technique. This allow to define a sampler usage for this render pass, or to read from a render target of a previous render pass.

See the Samplers section for more details about their definition.

2. Input Vertex Format

This allow to define the semantic of each attributes define in the vertex shader.

XML Element Definition:

    • Name: 'vertexformat'

    • Attributes:

      • 'name': The name of the attribute as defined in the vertex shader.

      • 'semantic': The semantic of the attribute.

        'semantic' ValueDescription
        positionVertex position (float3)
        normalVertex normal (float3)
        texcoord[0..N]Vertex texture coordinate buffer N (float2)
        tangent[0..N]Vertex tangent buffer N (float4)
        binormal[0..N]Vertex binormal buffer N (float4)

Example:

<?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>
<?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>
<?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>

3. Samplers

This allow to define the usage of each samplers.
It is used by the application to known which texture to set in the specified samplers.

XML Element Definition:

    • Name: 'sampler'

    • Attributes:

      • 'name': The name of the sampler variable in the shader file.

      • 'usage': The usage of the sampler. It matches the usage specified in the Ouput node of the graph.

        'usage' ValueDescription
        diffuseDiffuse map
        opacityOpacity map
        emissiveEmissive map
        ambientocclusionAmbient occlusion map
        ambientAmbient map
        maskMask map
        detailnormalDetail Normal map
        normalNormal map
        bumpBump map
        heightHeight map
        displacementDisplacement map
        specularlevelSpecular level map
        specularcolorSpecular color map
        specularSpecular map
        glossinessGlossiness map
        roughnessRoughness map
        anisotropylevelAnisothropy level map
        anisotropyangleAnisothropy angle map
        transmissiveTransmissive map
        reflectionReflection map
        refractionRefraction map
        environmentEnvironment map (cube map)
        panoramaThe Panorama Map (Latitude/Longitude Map)
        bluenoisemaskA 256x256 dithering texture
        • Multiple usages are supported.
          • Example:
        <!-- SAMPLERS -->
        <sampler name="baseColorMap" usage="basecolor,diffuse"/>
        <!-- ... -->
        <!-- SAMPLERS --> <sampler name="baseColorMap" usage="basecolor,diffuse"/> <!-- ... -->
           <!-- SAMPLERS -->
            <sampler name="baseColorMap" usage="basecolor,diffuse"/>
             <!-- ... -->
      • 'isHidden': Boolean that indicates if the sampler should appear in the GUI

        • Example:
        <!-- SAMPLERS -->
        <sampler name="bluenoiseMask" usage="bluenoisemask" ishidden="true"/>
        <!-- ... -->
        <!-- SAMPLERS --> <sampler name="bluenoiseMask" usage="bluenoisemask" ishidden="true"/> <!-- ... -->
             <!-- SAMPLERS -->
            <sampler name="bluenoiseMask" usage="bluenoisemask" ishidden="true"/>
             <!-- ... -->
      • Wrapping Mode:

        NameValue
        texture_wrap_s, texture_wrap_t, texture_wrap_r


        clamp_to_edge
        clamp_to_border
        mirrored_repeat
        repeat

      • Texture Filter

        NameValue
        texture_min_filter, texture_mag_filter


        nearest
        linear
        nearest_mipmap_nearest
        linear_mipmap_nearest
        nearest_mipmap_linear
        linear_mipmap_linear

Example:

<?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>
<?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>
<?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>

4. Uniforms

This allow to add additional information on each shader uniforms.

XML Element Definition:

    • Name: 'uniform'

    • Attributes:

      • 'name': The name of the uniform in the shader file.

      • 'semantic': The semantic of the uniform. (All matrices are float16).

        'semantic' ValueDescription
        worldWorld Matrix (float16)
        worldinversetransposeWorld Inverse Transpose Matrix (float16)
        worldviewprojectionWorld View Projection Matrix (float16)
        viewinverseWorld Inverse Matrix (float16)
        worldviewWorld View Matrix (float16)
        modelviewModel View Matrix (float16)
        projectionProjection Matrix (float16)
        ambientScene Ambient Color (float3)
        lightposition[0..N]Position of the scene's Nth light (float3)
        lightcolor[0..N]Color of the scene's Nth light (float3)
        lightintensity[0..N]Intensity of the scene's Nth light (float)
        globaltimeCurrent time in secs (float)
        resolutionViewport resolution (int2)
        mouseMouse position (int2)
        samplespostablesizeNumber of samples to use to compute the environment lighting (int)
        irradianceshcoefsThe array of spherical harmonics vectors (float3[10])
        panoramamipmapheightNumber of mipmap levels in the panorama map (float)
        panoramarotationAngle Rotation angle of the panorama map (float)
        panoramaintensityIntensity of the panorama map (float)
        computebinormalinfragmentshaderDoes the binormal be computedt per fragment ? (if not then per vertex) (bool)
        isdirectxnormalIs the normal map format DirectX ? (bool)
        uvwscaleScale values of u, v, w (float3)
        renderuvtileRender only 1 UV tile ? (bool)
        uvtilecoordsUV tile coordinate to render (int2)

Example:

<?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>
<?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>
<?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>

Example:

<?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>
<?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>
<?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>

Other parameters

Other additional information can be add to each uniforms to:

    • define the default value
    • clamp values
    • control the way the uniform will be display in the application:
    • set the label
    • set the widget info used to edit the value in the application:
    • widget name, min, max, increment/decrement step
    • group uniforms in group widgets

As the Uniforms can be override for each techniques, it allows to display a specific gui setup for each techniques.

XML Element Definition:

    • Name: 'uniform'

    • Attributes:

      • 'name': The name of the uniform in the shader file.

      • 'default': The uniform default value

      • 'min': The min value of the validity range

      • 'max': The max value of the validity range

      • 'guiName': The name of the uniform in the GUI of the application

      • 'guiGroup': The name of the group to put the uniform in the GUI of the application

      • 'guiWidget': The name of the widget used to edit the uniform value in the GUI of application

        'guiWidget' ValueDescription
        sliderSlider widget for floatN
        angleAngle widget for float
        colorColor widget for float3, float4 color
        checkboxCheckBox widget for bool
      • 'guiMin': The min value of the widget

      • 'guiMax': The max value of the widget


Example: Tessellation/Parallax

Parallax Vertex Shader File

Located in .\tessellation_parallax\parallax\vs.glsl

Content:

#version 120

attribute vec4 iVS_Position;
attribute vec4 iVS_Normal;
attribute vec2 iVS_UV;
attribute vec4 iVS_Tangent;
attribute vec4 iVS_Binormal;

varying vec3 iFS_Normal;
varying vec2 iFS_UV;
varying vec3 iFS_Tangent;
varying vec3 iFS_Binormal;
varying 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_Tangent = iVS_Tangent.xyz;
iFS_Binormal = iVS_Binormal.xyz;
iFS_PointWS = (worldMatrix * iVS_Position).xyz;
}

Tessellation Vertex Shader File

Located in .\tessellation_parallax\tessellation\vs.glsl

Content:

#version 120

attribute vec4 iVS_Position;
attribute vec4 iVS_Normal;
attribute vec2 iVS_UV;
attribute vec4 iVS_Tangent;
attribute vec4 iVS_Binormal;

varying vec4 oVS_Normal;
varying vec2 oVS_UV;
varying vec4 oVS_Tangent;
varying 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;
}

Tessellation Control Shader File

Located in .\tessellation_parallax\tessellation\tcs.glsl

Content:

#version 400 core
#extension GL_ARB_tessellation_shader : enable

layout(vertices = 3) out;

in vec4 oVS_Normal[];
in vec2 oVS_UV[];
in vec4 oVS_Tangent[];
in vec4 oVS_Binormal[];

out vec4 oTCS_Normal[];
out vec2 oTCS_UV[];
out vec4 oTCS_Tangent[];
out vec4 oTCS_Binormal[];

uniform float tessellationFactor;

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_Tangent[gl_InvocationID] = oVS_Tangent[gl_InvocationID];
oTCS_Binormal[gl_InvocationID] = oVS_Binormal[gl_InvocationID];
}

Tessellation Evaluation Shader File

Located in .\tessellation_parallax\tessellation\tcs.glsl

Content:

#version 400 core

layout(triangles, equal_spacing, ccw) in;

in vec4 oTCS_Normal[];
in vec2 oTCS_UV[];
in vec4 oTCS_Tangent[];
in vec4 oTCS_Binormal[];

uniform mat4 worldMatrix;
uniform mat4 worldViewProjMatrix;

uniform sampler2D heightMap;

uniform float tiling = 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 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_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 heightTexSample = texture(heightMap, newUV * tiling).x * 2.0 - 1.0;
newPos += newNormal * heightTexSample * heightMapScale;

vec4 obj_pos = vec4(newPos, 1);
gl_Position = worldViewProjMatrix * obj_pos;

iFS_UV = newUV * tiling;
iFS_Tangent = newTangent;
iFS_Binormal = newBinormal;
iFS_Normal = newNormal;
iFS_PointWS = (worldMatrix * obj_pos).xyz;
}

Fragment Shader File

Located in .\tessellation_parallax\fs.glsl

Content:

#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

varying vec3 iFS_Normal;
varying vec2 iFS_UV;
varying vec3 iFS_Tangent;
varying vec3 iFS_Binormal;
varying 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);
uniform bool flipNormal = true;
uniform float TilingDetail = 3.0f;
uniform float SpecExpon = 50.0;
uniform float Ks = 1.0;
uniform int parallax_mode = 0;
uniform float tessellationFactor = 4.0;
uniform float heightMapScale = 1.0f;
uniform float Depth_detail = 0.5f;
uniform float Kr = 0.5f;
uniform int KF_on = 1;
uniform float KFs = 1.0f;
uniform vec3 AmbiColor = vec3(0.07f,0.07f,0.07f);
uniform float tiling = 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 Shading
void phong_shading(
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

return result;
}

vec3 normalVecOSToWS(vec3 normal)
{
return 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_Tangent);
vec3 binormalOS = normalize(iFS_Binormal);

// ------------------------------------------
// Make sure the TBN is Orthonormalized
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 ? (tessellationFactor / 100000.f + heightMapScale / 500.f) : (heightMapScale / 50.f);
uv += (height * s.xy * parallax) ;

// ------------------------------------------
// 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);

// ------------------------------------------
// Add detail normalmap
vec3 normalDetailTS = texture2D(detailNormalMap,uv*TilingDetail).xyz;
normalDetailTS = fixNormalSample(normalDetailTS);
vec3 variableNormalDetailTS = lerpFct(vec3(0.0,0.0,0.5),normalDetailTS,Depth_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

// Light 0 contribution
vec3 diffContrib = vec3(0, 0, 0);
vec3 specContrib = vec3(0, 0, 0);
phong_shading(Lamp0Color, cumulatedNormalWS, pointToLight0DirWS, pointToCameraDirWS, diffContrib, specContrib);

// Light 1 contribution
vec3 diffContrib2 = vec3(0, 0, 0);
vec3 specContrib2 = vec3(0, 0, 0);
phong_shading(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;
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 = texture2D(emissiveMap,uv).xyz;

vec3 finalcolor = Ambiant_final
+ specularColor*specContrib
+ diffuseColor.rgb*diffContrib
+ (reflColor*specularColor*FallofRefl)
+ emissive;

// Final Color
vec4 finalColor4 = vec4(finalcolor, texture2D(opacityMap,uv));

gl_FragColor = finalColor4;
}

GLSLFX File

The glslfx file defines two techniques to render the geometry:

  • One uses the hardware tessellation technique
  • The other based on a parallax effect that will be used as a fall-back if the user hardware don't support the Tessellation.

Located in .\tessellation_parallax\fs.glsl

Content:

<?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>
<?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>
<?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>



Get help faster and easier

New user?