# GLSL Projection problem

Hi,
I’m having a problem with implementing a water shader in my own engine. The shader is based on the free water tutorial on gametutorials.com and their demo works fine. If I implement this in my engine I get not the correct reflections/refractions back.

Here are 2 screens showing the problem:

this is how it shoull look at least nearly:

and this is how it looks like if I’m rotating my cam :

Here is my shader code (maybe it helps)

``````
varying vec4 refrCoords;
varying vec4 normCoords;
varying vec4 viewCoords;
varying vec4 viewTangetSpace;
varying vec4 lightTangetSpace;

uniform vec4 lightPos, cameraPos;

void main()
{
// Because we have a flat plane for water we already know the vectors for tangent space
vec4 tangent = vec4(1.0, 0.0, 0.0, 0.0);
vec4 normal = vec4(0.0, 1.0, 0.0, 0.0);
vec4 biTangent = vec4(0.0, 0.0, 1.0, 0.0);

// Calculate the vector coming from the vertex to the camera
vec4 viewDir = cameraPos - gl_Vertex;

// Compute tangent space for the view direction
viewTangetSpace.x = dot(viewDir, tangent);
viewTangetSpace.y = dot(viewDir, biTangent);
viewTangetSpace.z = dot(viewDir, normal);
viewTangetSpace.w = 1.0;

// Calculate the vector that the light hits the vertex
vec4 lightDir = lightPos - gl_Vertex;

// Compute tangent space for the light direction
lightTangetSpace.x = dot(lightDir, tangent);
lightTangetSpace.y = dot(lightDir, biTangent);
lightTangetSpace.z = dot(lightDir, normal);
lightTangetSpace.w = 1.0;

refrCoords = gl_MultiTexCoord1*1.50;
normCoords = gl_MultiTexCoord2*1.50;

// This calculates our current projection coordinates
viewCoords = gl_ModelViewProjectionMatrix * gl_Vertex;

gl_Position = viewCoords;
}

``````

``````
varying vec4 refrCoords;
varying vec4 normCoords;
varying vec4 viewCoords;
varying vec4 viewTangetSpace;
varying vec4 lightTangetSpace;

uniform sampler2D reflection;
uniform sampler2D refraction;
uniform sampler2D normalMap;
uniform sampler2D dudvMap;
uniform sampler2D depthMap;
uniform vec4 waterColor;

void main()
{
const float kShine = 64.0;
const float kDistortion = 0.015;
const float kRefraction = 0.09;

vec4 distOffset = texture2D(dudvMap, normCoords.xy) * kDistortion;
vec4 dudvColor = texture2D(dudvMap, vec2(refrCoords + distOffset));
dudvColor = normalize(dudvColor * 2.0 - 1.0) * kRefraction;

vec4 normalVector = texture2D(normalMap, vec2(refrCoords + distOffset));
normalVector = normalVector * 2.0 - 1.0;
normalVector.a = 0.0;

vec4 lightReflection = normalize( reflect(-lightTangetSpace, normalVector) );

vec4 invertedFresnel = vec4( dot(normalVector, lightReflection ) );
vec4 fresnelTerm = 1.0 - invertedFresnel;

vec4 projCoord = viewCoords / viewCoords.q;
projCoord = (projCoord + 1.0) * 0.5;
projCoord += dudvColor;
projCoord = clamp(projCoord, 0.001, 0.999);

vec4 reflectionColor  = texture2D(reflection, projCoord.xy);
vec4 refractionColor  = texture2D(refraction, projCoord.xy);
vec4 depthValue = texture2D(depthMap, projCoord.xy);

vec4 invDepth = 1.0 - depthValue;
refractionColor *= invertedFresnel * invDepth;
refractionColor +=  waterColor * depthValue * invertedFresnel;

reflectionColor *= fresnelTerm;

vec4 localView = normalize(viewTangetSpace);
float intensity = max(0.0, dot(lightReflection, localView) );
vec4 specular = vec4(pow(intensity, kShine));

gl_FragColor = refractionColor + reflectionColor + specular;
}

``````

I should also say that I’m using a left handed coordinate system instead of the right handed one. Could this be the problem? If yes any idea how to solve this?

This looks like your mirrorplane has the wrong z-values. Make shure the plane on which you are mirroring is on the same hight than the ocean.

thx for the reply. Unfortunatly the plane is setup correctly. I was able to solve it by switching from glFrustum to gluPerspective. Somehow it seems that glFrustum behaves different with the projection matrix sent to the shaderpipeline.

Any experience with this issue?

Can you post the glFrustum parameters you used before and the new gluPerspective parameters?

oh, sure

``````
Method UpdateView(mat:TMatrix)

Local ratio	:Float = (Float(m_viewport.w)/m_viewport.h)
Local jx	:Float = TGlobal.j[TGlobal.jitter,0]
Local jy	:Float = TGlobal.j[TGlobal.jitter,1]

If TGLobal.aa = False Then 'TOglRenderer.m_bAntiAlias = False Then
jx#=0;jy#=0
EndIf

accPerspective(ATan((1.0/(m_Zoom*ratio)))*2.0,ratio,m_Near,m_far,jx,jy,0.0,0.0,1.0)

Local new_mat:TMatrix = mat.Inverse()

If Self.flip_enable Then
glTranslatef(0.0, 40.0*2.0, 0.0)
glScalef(1.0, -1.0, 1.0)
End If

' Get projection/model/viewport info - for use with CameraProject
glGetDoublev(GL_MODELVIEW_MATRIX,Varptr mod_mat[0])
glGetDoublev(GL_PROJECTION_MATRIX,Varptr proj_mat[0])
glGetIntegerv(GL_VIEWPORT, Varptr viewport[0] )

End Method

'######################################################################################################################

Method accPerspective(fovy:Float, aspect:Float, zNear:Float, zFar:Float, pixdx:Float, pixdy:Float, eyedx:Float, eyedy:Float, focus:Float)

Local fov2#,left_#,right_#,bottom#,top#
'fov2=((fovy*Pi)/180.0)/2.0
fov2=fovy/2.0

top=zNear/(Cos(fov2)/Sin(fov2))
bottom=-top
right_=top*aspect
left_=-right_

accFrustum(left_,right_,bottom,top,zNear,zFar,pixdx,pixdy,eyedx,eyedy,focus)

End Method

Method accFrustum(left_#,right_#,bottom#,top#,zNear#,zFar#,pixdx#,pixdy#,eyedx#,eyedy#,focus#)

Local xwsize#,ywsize#
Local dx#,dy#

xwsize=right_-left_
ywsize=top-bottom
dx=-(pixdx*xwsize/Float(viewport[2])+eyedx*zNear/focus)
dy=-(pixdy*ywsize/Float(viewport[3])+eyedy*zNear/focus)

glMatrixMode(GL_PROJECTION)
'Local ratio#=(Float(viewport[2])/viewport[3])
'gluPerspective(ATan((1.0/(m_zoom#*ratio#)))*2.0,ratio#,range_near#,range_far#)
glFrustum(left_+dx,right_+dx,bottom+dy,top+dy,zNear,zFar)
glMatrixMode(GL_MODELVIEW)
glTranslatef(-eyedx,-eyedy,0.0)

End Method

``````

the gluperspective version is directly before the glFrustum call.

I’m guessing the problem is that your viewing frustum is not symmetrical.

glFrustum(left,right,bottom,top,zNear,zFar);

returns exactly the same results as

gluPerspective( 360.0atan((top-bottom)/(2zNear))/M_PI,(right-left)/(top-bottom),zNear,zFar);

only if

top == -bottom
and
right == -left

That’s because gluPerspective always generates a symmetrical viewing frustum, meaning that the opening angles on the left side and the right side are equal and the opening angles on the bottom side and the top side are equal.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.