Refraction in OpenGL and Cg

Started by
8 comments, last by Nichiyoobiko 16 years, 11 months ago
Hi! I'm a real noob to Shader programming but I have to implement a refraction shader in a project of mine. I am using a cubemap for a skybox and to map the refractions onto a sphere in the center of that skybox. I am also moving the camera around that sphere, following a character which is placed on the sphere's surface. My problem now is, that the refraction shader isn't updating. That means, that I see always the same image on the sphere although I am moving the camera. I'm sure there is something wrong with my OpenGL setup. Can anybody tell me step by step what I have to do to get that shader running? My OpenGL code is a total mess now, so I chose to not post it here, but if you want to see it, I will make up for that. I chose to use the following Nvidia Cg Tutorial codes: vertex shader code:

void C7E3v_refraction(float4 position : POSITION,
                      float2 texCoord : TEXCOORD0,
                      float3 normal   : NORMAL,
   
                  out float4 oPosition  : POSITION,
                  out float2 oTexCoord  : TEXCOORD0,
                  out float3 T          : TEXCOORD1,

              uniform float etaRatio,
              uniform float3 eyePositionW,
              uniform float4x4 modelViewProj, 
              uniform float4x4 modelToWorld)
{
  oPosition = mul(modelViewProj, position);
  oTexCoord = texCoord;

  // Compute position and normal in world space
  float3 positionW = mul(modelToWorld, position).xyz;
  float3 N = mul((float3x3)modelToWorld, normal);
  N = normalize(N);
  
  // Compute the incident and refracted vectors
  float3 I = normalize(positionW - eyePositionW);
  T = refract(I, N, etaRatio);
}
fragment shader code:

void C7E4f_refraction(float2 texCoord : TEXCOORD0,
                      float3 T        : TEXCOORD1,

                  out float4 color : COLOR,

              uniform float       transmittance,
              uniform sampler2D   decalMap,
              uniform samplerCUBE environmentMap)
{
  // Fetch the decal base color
  float4 decalColor = tex2D(decalMap, texCoord);

  // Fetch refracted environment color
  float4 refractedColor = texCUBE(environmentMap, T);

  // Compute the final color
  color = lerp(decalColor, refractedColor, transmittance);
}
Advertisement
The shader looks correct. Are you updating the matrices?
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Hi, i once had the same problem. There seems nothing wrong with the shader itself, i guess you might passed a wrong matrix to the "modelToWorld" parameter.
hello! thanks for the replies! I am using the openGL modelViewMatrix as modelToWorld matrix.
Isn't it the same matrix?

I'll post my openGL code later today.

I think my problem lies in the eyePosition vector. I am using gluLookAt to position the camera. Can I use the same vector as eyePosition as i used in gluLookAt as position parameter? Because when I try this vector, then the map on my object gets distorted but in a completely wrong and strange way. :(

I also tried to read the translation part of my modelViewMatrix and invert it, but it didn't have any effect.
Quote:Original post by Nichiyoobiko
hello! thanks for the replies! I am using the openGL modelViewMatrix as modelToWorld matrix.
Isn't it the same matrix?


Not necessarily. OpenGL's ModelView matrix is used to transform vertices to view space. The view space and world space transformations are the same if the camera has not been translated nor rotated.
Hmmm...
I am first placing the camera (with gluLookAt), then passing over my parameters to the shader and after that I am drawing the object. The camera is correctly following the object. So this is the incorrect order?


So at first, I should calculate the transformations of my object in world space and then save a matrix which positions the camera relative to it. Then I position the cam. After that I pass over the matrix to the shader and then I draw the object, right?

[Edited by - Nichiyoobiko on May 14, 2007 3:36:33 AM]
post my shaders here, i do all the stuff in view space.
vertex shader
void main(float4 position : POSITION,	  float3 normal   : NORMAL,	  uniform float4x4 modelView,	  uniform float4x4 modelViewIT,	  uniform float4x4 modelViewProj,	  out float4 oPosition    : POSITION,	  out float3 positionEye : TEXCOORD0,	  out float3 oNormal     : TEXCOORD1){	oPosition = mul(modelViewProj, position);	positionEye = mul(modelView, position).xyz;	oNormal = mul((float3x3)modelViewIT, normal);}

fragment shader
void main(float3 position : TEXCOORD0,	  float3 normal   : TEXCOORD1,          //refracted vectors are calculated in view space, but environment map          //are located relative to world space, so we need to convert it back          //into world space by multiplying the parameter "prog0trans", which is          //the inverse of view matrix.	  uniform float4x4 prog0trans, 	  uniform samplerCUBE cubemap,	  uniform float etaRatio,		  	  out float4 color : COLOR){	float3 N = normalize(normal);        float3 I = normalize(position);	float3 T = refract(I, N, etaRatio);	float3 TT = mul((float3x3)prog0trans,T);        color = texCUBE(cubemap, TT);}


[Edited by - hmcen on May 15, 2007 12:55:51 AM]
what exactly is the prog0trans matrix?

EDIT: argh, I must be blind. Sorry I haven't seen the comments. :)
EDIT2: How do I get the view matrix in openGL? Is it the same as the modelViewMatrix?

[Edited by - Nichiyoobiko on May 14, 2007 11:28:08 PM]
modelViewMatrix convert from object space to view space. However, viewMatrix convert from world space to view space, so they are not exactly the same. You can simply obtain the view matrix by utilizing the parameters in gluLookAt() function.
In Nvidia Cg toolkit, the sample code "08_vertex_transform" provides a function named buildLookAtMatrix(), copy it to your app, call it to obtain view matrix, remember to inverse it before you pass to "prog0trans" in fragment program, and you can find the routine to inverse matrix in "09_vertex_lighting". Enjoy it!
THX!
I'll try your code.

:)

This topic is closed to new replies.

Advertisement