Refraction shader for dummies

Started by
0 comments, last by skow 17 years ago
Can someone point me an article/tutorial/sample code that would help me understand the theory and implementation of refraction shaders in OpenGL? I've been Googling my way around the net, but all I have found are implementation articles that assume you already know everything on the matter. Thanks! :D
Advertisement
Well I have no links but I can give you a brief explanation of planar Refraction. If you are looking for information using cube map refraction, disregard this.

First you will want to render what is being refracted to a texture. In the case of water refraction, this would be everything below the water. Or if this is a window, draw everything behind the window. You will want to make sure not to draw anything in front of the refracting plane. To render to the texture you can use a FBO or simply glCopyTexSubImage.

Now that you have your texture, you will be using projective texturing and distort the 3d texture coordinates to create the refraction. These 3d texture coordinates should be the same as the vertex coordinates. So now do your standard scene draw, and note that now you don’t need to draw anything behind this refraction plane as it will be projectively drawn.

Normal maps are a great way to distort the cords for nice refractions. For water you can scroll multiple normal maps for a really simple but good looking flowing water look.

I’ll include some shaders I use, just with the disclaimer that they use just one of many ways this can be done.

Here is a sample vertex shader
outdata main(appdata IN, uniform float4x4 ModelViewProj, uniform float4x4 TextureMatrix, uniform float4 shift){	outdata OUT;		OUT.color = IN.color;	OUT.textCordRefract = mul(TextureMatrix, IN.position + shift);		OUT.position = mul(ModelViewProj, IN.position + shift);		OUT.textCorNormal = IN.textCoords;	return OUT;}

Note the above shift above is how I translate my plane.

Here is a sample fragment shader
outdata main(appdata IN, 	uniform sampler2D refractTex,		uniform sampler2D normalTex, float amplitude) {	outdata OUT;	float4 normals = (tex2D(normalTex, IN.texNorm.xy)*2.0-1.0 )* amplitude;	OUT.color0  = IN.color0 * (tex2Dproj(refractTex, IN.texRelect +(normals)));	return OUT;}


Hopefully this is enough to get you started.

This topic is closed to new replies.

Advertisement