Shading Technique - Fresnel

From Horde3D Wiki
Jump to: navigation, search

Overview

What is the Fresnel shader? This shader combine reflection and refraction that depends on the viewing angle.

What is refraction? According to the "OpenGL Shading Language Book", refraction is the blending of light as it passes trough a boundary between surfaces with different optical densities.

Requirements:
- A cube map texture.

The shader

Can be put in the ATTRIBPASS or AMBIENT context to be used with the examples pipelines in the Horde3D SDK 1.0 beta.

Vertex shader: In the vertex shader, you can freely change the indices of refraction or the degree of reflectivity to change de final result.

Fresnel - Vertex Shader
const float Eta = 0.67;          // Ratio of indices of refraction (air -> glass)
const float FresnelPower = 10.0; // Controls degree of reflectivity at grazing angles

const float F  = ((1.0 - Eta) * (1.0 - Eta)) / ((1.0 + Eta) * (1.0 + Eta));

varying vec3  Reflect;
varying vec3  Refract;
varying float Ratio;

attribute vec3 normal;

uniform vec3 viewer;

void main( void )
{
    vec4 worldPosition = calcWorldPos( gl_Vertex );
    vec3 ecPosition3  = worldPosition.xyz - viewer;

    vec3 i = normalize(ecPosition3);
    vec3 n = normalize( calcWorldVec(normal) );

    Ratio = F + (1.0 - F) * pow((1.0 - dot(-i, n)), FresnelPower);
    //Ratio = 1.0 - Ratio; // Add this line if your cube map is not based on the right side

    Refract = refract(i, n, Eta);
    Refract = vec3(gl_TextureMatrix[0] * vec4(Refract, 1.0));


    Reflect = reflect(i, n);
    Reflect = vec3(gl_TextureMatrix[0] * vec4(Reflect, 1.0));


    gl_Position   = gl_ModelViewProjectionMatrix * worldPosition;
}

Fragment shader:

Fresnel - Fragment Shader
varying vec3  Reflect;
varying vec3  Refract;
varying float Ratio;

uniform samplerCube tex0;

void main(void)
{
    vec3 refractColor = vec3 (textureCube(tex0, Refract));
    vec3 reflectColor = vec3 (textureCube(tex0, Reflect));

    vec3 color   = mix(refractColor, reflectColor, Ratio);

    gl_FragColor = vec4(color, 1.0);
}

How to use it

You must create a material in wich the shader is defined as the fresnel shader. Then, you must add the Texture unit 0 with a cube map type texture.

Example Result

http://www.horde3d.org/forums/download/file.php?id=52

Pictures

fresnel3ej6.png

To-Do List for this Article

- Better explanation

Technique - Fresnel
[[Image:]]
Using reflection and refraction
Version: 1.0
Compatible with Horde3D: 1.0 beta
Release date: 2008-08-10
Author(s): Mikmacer