Jump to content
  • Advertisement
Sign in to follow this  

Need opinions on glass refraction shader

This topic is 2598 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone - first post in this community...

I have some experience with OpenGL's fixed pipeline and now I'm playing around with GLSL. One effect that I really like from games is the simulated distortion when looking through thick glass (like security glass in Doom 3, the offices in Portal, etc.).

So I spent some time trying to recreate the effect. There are many tutorials out there that show you how to do refraction based on cubemaps but this is not useable as you simply want to modify what you are seeing.
I would like to get some feedback on my approach. I would really like some hints on performance or if am totally running in the wrong direction.

I will describe what I am doing. After that I'll insert a screenshot to make things more clear.
The basic idea is to render the scene without the window-effect into a texture. Then - into a second texture - the window geometry is rendered where the vertex colors represent the texture coordinates for the displacement (normal) map.
Finally the sceneTexture, the texCoordTexture and the normal map are bound to individual texture units and a full screen quad is drawn that would render the sceneTexture.
At this point a shader creates the window-effect: the vertex shader only does the fixed pipeline stuff (transform vertex, set texture coords). The important step happens in the fragment shader:
The texture coordinate is used to lookup the color in the texCoordTexture. This color encodes two things: a) if the pixel belongs to the window (z/b part) and b) the location of the normal. So if it is part of the window, look up the normal and scale it down to limit the displacement. Final color is then determined by adding the scaled normal to the original texCoord and looking up the color in the sceneTexture.

This is the fragment shader:

uniform sampler2D tex;
uniform sampler2D disptc;
uniform sampler2D disp;

void main(void) {
vec3 dispnormal;
vec3 displace;
vec2 tcfragment = gl_TexCoord[0].st;
vec3 disptc = texture2D(disptc, tcfragment).xyz;

if(disptc.z == 0.0) {
} else {
dispnormal = normalize(texture2D(disp, disptc.xy).xyz);
dispnormal = dispnormal * 2.0 - 1.0;
displace = dispnormal * 0.035;

vec4 color = texture2D(tex, tcfragment + displace.xy);
gl_FragColor = color;

Here is a screenshot of the shader in action:


The upper part is the scene, below you see the sceneTexture (without window) and the texCoordTexture. The scene consists of a hollow cube (wall thickness 1.0) and the window has a small border (not on floor level). Inside is a 'poster' (quad with a texture) and a Teapot.

One thing that bothers me: The shader acts on an image that is drawn on a full-screen quad. This makes including highlights a bit difficult as it seems. Currently I think this can be solved with even more textures that store the needed info but maybe someone knows a better way ?

I would really like some feedback on this. Maybe there even is a guide for this kind of effect that I could not find...

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!