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)

the vertex shader


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;
}


the fragment shader


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?

thx in advance.

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 :slight_smile:


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() 
		glLoadMatrixf(new_mat.grid)
		
		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)
		glLoadIdentity()
		'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)
		glLoadIdentity()
		glTranslatef(-eyedx,-eyedy,0.0)

		
	End Method

the gluperspective version is directly before the glFrustum call.

thx in advance

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.