Fresnel term in a texture ?

I’m working on a water simulation which is currently running nice and fast with VBO’s. It’s done in such a way that the water tiles and leaves me with the problem of how to calculate the fresnel term for each vertex without having to update each vertex in my VBO for each tile I want to draw. The eye point is free ranging and so pre-computing is not really an option.

I read in one article that it was possible to encode the fresnel term in a 1d texture and “simply” index into that. Does anyone have any idea how one would go about doing that ?

Or does anyone have any other ideas on how to achieve the same ?

The only limitation at the moment is that I’m not able to use vertex or fragment programs/shaders.

Fresnel term for dielectrics is approximated by Schlick’s equation:

Fr(theta)=Fni+(1-Fni)*(1-cos(theta))^5

where theta is angle between normal to surface and vector to camera (V in common notation), and Fni is a value of Fresnel term at normal incidence (i.e. theta=0),

Too bad you cannot use shaders. So you just put dot(N,V) into texture coordinate, then peform lookup to get Fr, and then interpolate between reflected and refracted images using it. Unfortunately, if you don’t want to change your VB, you probably have to make some assumptions about N and/or V.

[This message has been edited by h2 (edited 07-17-2003).]

You can put the texture coordinate for the Fresnel term in a separate, dynamic vertex buffer, and only calculate that per frame, while leaving the majority of your data un-touched and still do complete, linear writes to your dynamic buffer.

newt,

Lets see what assumptions you can make about vectors:

  1. N is constant over some group of vertices. This holds true for instance if you have realatively small waves. Try following:

glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_ARB);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_ARB);
glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_ARB);

This puts reflection vector in eye coordinates to texture coordinates. Then set texture matrix:

| Nx Ny Nz 0 |
| 0 0 0 0 |
| 0 0 0 0 |
| 0 0 0 1 |

where N is normal to surface in eye coordinates. This gives you dot(N,R), which is equal to dot(N,V), in S coordinate.

  1. V is constant over some group of vertices. This is valid when your normal varies intensively, i.e. huge waves or something like this. Everything is identical to previous case, except texgen mode is GL_NORMAL_MAP_ARB and texture matrix is made of V in eye coordinates.

[This message has been edited by h2 (edited 07-18-2003).]

Thanks guys.

h2, the normal varies for each vertex and the eye vector also varies for each vertex.

Good optimization though. Was attempting something like this by putting V into one texture and N into another and DOT3’ing them. But couldn’t work out how to change the V texture for the tile offsets.

Anywat have implemented the texture lookup and a seperate 1d texture coord array which I update per tile. Still have to calculte V.N for each vertex in each tile, but it’s a LOT less intensive than re-mapping my VBO and changing the base color for each vertex in each tile.Have for find some good values for Fni as well, looks a bit crappy at the moment.

Now to get the enviroment mapped bump mapping working…