Sunday 8 July 2012

Basic HLSL Lighting Techniques - Episode 5: Environment Maps - NVIDIA Glass



OK, as you can see this may well not be all that basic, but if you have already used my sky box sample then you have already used an Environment map (as a result of this have found that my sky box shader is still in correct..sorry, fixed in this post though). In this post I hope to show the NVIDIA Glass shader.

The NVIDIA Glass Shader

This shader comes with a nice Fresnel function, now I had never hear of Fresnel (to my shame) until I started to play with shaders, but the Fresnel Term is useful for reflective surfaces as it calculates the ratio between reflected and refracted rays and so the surface becomes more reflective the angle of view changes. I have given 3 examples of the glass shader, the first calculates it's own Fresnel term, the second is passed a texture to emulate the Fresnel term and the last uses no Fresnel term at all.

As you will see the shaders are drawn in the following order from top to bottom, self calculating Fresnel Term, Fresnel texture passed and then no Fresnel used. I have also added a tint parameter so the class can be coloured.







I am not going to give an explanation of the NVIDIA glass shader as I don't feel qualified to having not written it myself, but I will show what we need to pass to the shader to get this effect working.
We need to pass a World, World Inverse Transpose, World View Projection and an Inverse View matrix to the shader like this:


Matrix world = Matrix.CreateScale(Scale) * Matrix.CreateFromQuaternion(Rotation) * Matrix.CreateTranslation(Position); Matrix wvp = world * Camera.View * Camera.Projection; if (effect.Parameters["world"] != null) effect.Parameters["world"].SetValue(world); if (effect.Parameters["wvp"] != null) effect.Parameters["wvp"].SetValue(wvp); if (effect.Parameters["worldIT"] != null) effect.Parameters["worldIT"].SetValue(Matrix.Invert(Matrix.Transpose(world))); if (effect.Parameters["viewI"] != null) effect.Parameters["viewI"].SetValue(Matrix.Invert(Camera.View));


We also need to pass the environment map to the shader to as well as the Fresnel texture to use (if the shader needs it) I have also added a "tint" variable so the glass can be coloured. The environment map is the same one that has been passed to the sky box

if (effect.Parameters["cubeMap"] != null)
effect.Parameters["cubeMap"].SetValue(env);

if (effect.Parameters["tint"] != null)
effect.Parameters["tint"].SetValue(Tint.ToVector4());

if (effect.Parameters["fresnelTex"] != null)
effect.Parameters["fresnelTex"].SetValue(fresnel);
There are other parameters in the shader but I have not modified them as they look pretty good now, but by all means give them a go too.

My next post will again be on environment maps using a reflection and refraction method.

Thanks NVIDIA!

You can download the solution here.

3 comments:

  1. The glass effect looks great, the link seems to be broken. Any chance of fixing it?

    ReplyDelete