GLSL shader not working fresnel correctly

As we know, to get fresnel value, we need to get the facing amount. And we do it by calculating the dot product of normalDirection and viewDirection. I took this code:


import bge
 
cont = bge.logic.getCurrentController()
 
VertexShader = """
         uniform mat4 viewMatrix; // world to view transformation
         uniform mat4 viewMatrixInverse; 
            // view to world transformation
 
         varying vec3 viewDirection; // direction in world space 
            // in which the viewer is looking
         varying vec3 normalDirection; // normal vector in world space 
 
         void main()
         {
            vec4 positionInViewSpace = gl_ModelViewMatrix * gl_Vertex;
               // transformation of gl_Vertex from object coordinates 
               // to view coordinates
 
            vec4 viewDirectionInViewSpace = positionInViewSpace 
               - vec4(0.0, 0.0, 0.0, 1.0);
               // camera is always at (0,0,0,1) in view coordinates;
               // this is the direction in which the viewer is looking 
               // (not the direction to the viewer)
 
            viewDirection = 
               vec3(viewMatrixInverse * viewDirectionInViewSpace);
               // transformation from view coordinates 
               // to world coordinates
 
            vec3 normalDirectionInViewSpace = 
               gl_NormalMatrix * gl_Normal;
               // transformation of gl_Normal from object coordinates 
               // to view coordinates
 
            normalDirection = normalize(vec3(
               vec4(normalDirectionInViewSpace, 0.0) * viewMatrix));
               // transformation of normal vector from view coordinates 
               // to world coordinates with the transposed 
               // (multiplication of the vector from the left) of 
               // the inverse of viewMatrixInverse, which is viewMatrix
 
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
         }
"""
 
FragmentShader = """
         varying vec3 viewDirection;
         varying vec3 normalDirection;
         uniform samplerCube cubeMap;
 
         void main()
         {
            vec3 reflectedDirection = reflect(viewDirection, normalize(normalDirection));
 
            vec3 specularColor = textureCube(cubeMap, vec3(reflectedDirection.x, -reflectedDirection.z, reflectedDirection.y));
            vec4 specular = vec4(specularColor.xyz, 1.0);
            gl_FragColor = specular;
         }
"""
 
mesh = cont.owner.meshes[0]
for mat in mesh.materials:
    shader = mat.getShader()
    if shader != None:
        if not shader.isValid():
            shader.setSource(VertexShader, FragmentShader, 1)
            shader.setSampler('cubeMap', 0)
        viewMatrix = bge.logic.getCurrentScene().active_camera.world_to_camera
        shader.setUniformMatrix4('viewMatrix', viewMatrix)
        viewMatrixInverse = bge.logic.getCurrentScene().active_camera.camera_to_world
        shader.setUniformMatrix4('viewMatrixInverse', viewMatrixInverse)

to play out with it and found a problem. If I do:


float facing = dot(viewDirection, normalDirection);

gl_FragColor = mix(specular, vec4(1.0, 0.0, 0.3, 1.0), facing);
//The vec4(...) in mix is a random color I pick for test.

in fragment shader, than I don’t get the fresnel effect, but whole reflection gets tinted in inverted color of the one I pick there, and it’s not tinted naturally.
I need a quick fix.

Hey! I don’t know about normalDirection calculation. However, when I use this method(normal and view in dot product) in nodes, it gives me facing output.

Come on - could you tell me if the normal thing is not calculated right or something like that?


import bge
 
cont = bge.logic.getCurrentController()
 
VertexShader = """
         uniform mat4 viewMatrix; // world to view transformation
         uniform mat4 viewMatrixInverse; 
            // view to world transformation
 
         varying vec3 viewDirection; // direction in world space 
            // in which the viewer is looking
         varying vec3 normalDirection; // normal vector in world space 
         varying vec3 normal;
         varying vec3 view;
 
         void main()
         {
            vec4 positionInViewSpace = gl_ModelViewMatrix * gl_Vertex;
               // transformation of gl_Vertex from object coordinates 
               // to view coordinates
 
            vec4 viewDirectionInViewSpace = positionInViewSpace 
               - vec4(0.0, 0.0, 0.0, 1.0);
               // camera is always at (0,0,0,1) in view coordinates;
               // this is the direction in which the viewer is looking 
               // (not the direction to the viewer)
 
            viewDirection = 
               vec3(viewMatrixInverse * viewDirectionInViewSpace);
               // transformation from view coordinates 
               // to world coordinates
 
            vec3 normalDirectionInViewSpace = 
               gl_NormalMatrix * gl_Normal;
               // transformation of gl_Normal from object coordinates 
               // to view coordinates
 
            normalDirection = normalize(vec3(
               vec4(normalDirectionInViewSpace, 0.0) * viewMatrix));
               // transformation of normal vector from view coordinates 
               // to world coordinates with the transposed 
               // (multiplication of the vector from the left) of 
               // the inverse of viewMatrixInverse, which is viewMatrix
               
            normal = normalize(gl_NormalMatrix * gl_Normal);
            view = -normalize(vec3(gl_ModelViewMatrix * gl_Vertex)); 
 
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
         }
"""
 
FragmentShader = """
         varying vec3 viewDirection;
         varying vec3 normalDirection;
         varying vec3 normal;
         varying vec3 view;
         uniform samplerCube cubeMap;
 
         void main()
         {
            vec3 reflectedDirection = reflect(viewDirection, normalize(normalDirection));
            vec4 color = vec4(0.0, 0.5, 0.5, 1.0);
            float fresnel = dot(view, normal);
 
            vec3 specularColor = textureCube(cubeMap, vec3(reflectedDirection.x, -reflectedDirection.z, reflectedDirection.y));
            vec4 specular = vec4(specularColor.xyz, 1.0);
            gl_FragColor = mix(specular, color + specular * 0.04, fresnel);
         }
"""
 
mesh = cont.owner.meshes[0]
for mat in mesh.materials:
    shader = mat.getShader()
    if shader != None:
        if not shader.isValid():
            shader.setSource(VertexShader, FragmentShader, 1)
            shader.setSampler('cubeMap', 0)
        viewMatrix = bge.logic.getCurrentScene().active_camera.world_to_camera
        shader.setUniformMatrix4('viewMatrix', viewMatrix)
        viewMatrixInverse = bge.logic.getCurrentScene().active_camera.camera_to_world
        shader.setUniformMatrix4('viewMatrixInverse', viewMatrixInverse)

A fix code!