Jump to content
  • Advertisement
Sign in to follow this  
Enalis

OpenGL GLSL

This topic is 4405 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

I have been working on getting all the shaders I want to use with a working example. I recently added per pixel lighting and shadow mapping with PCF. I wanted to add parallax mapping. So I looked around for an example and found one at www.ultimategameprogramming.com under opengl page 10. I decided to use my shader class and adapt the code to work with mine. So that's what I did. I'll post my code for everyone to see, but as for results, right now I only get a very dark quad textured with the detail map but it's extremely dark. And it seems that none of the parallax effects are working. Here is some code...
// these are the parts of my init function that pertains to the shader
LoadGLTexture(&parallaxTestTextures[DECAL_TEXTURE], "data/decal.PNG", LINEAR_FILTERING, &screenSettings.anisotropy);
LoadGLTexture(&parallaxTestTextures[NORMAL_TEXTURE], "data/normal.PNG", LINEAR_FILTERING, &screenSettings.anisotropy);
LoadGLTexture(&parallaxTestTextures[HEIGHT_TEXTURE], "data/height.PNG", LINEAR_FILTERING, &screenSettings.anisotropy);

parallaxShader.InitShaders("shaders/parallaxVS.glsl", "shaders/parallaxPS.glsl");

// NOTE: All shaders turned off in the beginning of render func and turned on in the function they are used in and turned off at the end.

// this draws the object and is called once in my render function
void DrawParallaxMappedObject(void){
	glPushMatrix();
	glDisable(GL_BLEND);
	glTranslatef(0.0f, 0.0f, -7.5f);
	glRotatef(-yRot, 1.0f, 0.0f, 0.0f);
	glRotatef(-xRot, 0.0f, 1.0f, 0.0f);

	// Here we pass in the light position
	parallaxShader.SetFloat4(parallaxShader.GetVariable("lightPos"), g_LightPosition[0], g_LightPosition[1], g_LightPosition[2], g_LightPosition[3]);
	parallaxShader.SetFloat3(parallaxShader.GetVariable("camPos"), camera.xPos, camera.yPos, camera.zPos);
	// Here pass in our texture unit 0 (GL_TEXTURE0_ARB) for "texture1" in the shader.
	parallaxShader.SetInt(parallaxShader.GetVariable("decal"), 0);
	parallaxShader.SetInt(parallaxShader.GetVariable("parallaxMap"), 1);
	parallaxShader.SetInt(parallaxShader.GetVariable("normalMap"), 2);

	// we need to turn on our shader for the parallax objects
	parallaxShader.TurnOn();

	glEnable(GL_LIGHTING);	
	float lightValue[4] = {1.0f, 1.0f, 1.0f, 1.0f};
	glLightfv(GL_LIGHT0, GL_AMBIENT, lightValue);
//	glDisable(GL_LIGHTING);
	
	// now we'll draw our objects
	// Bind both images to unit 0 and 1 respectively.
	glActiveTextureARB(GL_TEXTURE0_ARB);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, parallaxTestTextures[DECAL_TEXTURE]);

	glActiveTextureARB(GL_TEXTURE1_ARB);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, parallaxTestTextures[HEIGHT_TEXTURE]);

	glActiveTextureARB(GL_TEXTURE2_ARB);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, parallaxTestTextures[NORMAL_TEXTURE]);

	// Draw our wall.  Keep in mind we are sending the s tangent through glColor3f().
	glBegin(GL_TRIANGLES);

//		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 1.0f);    glNormal3f(0.0f, 0.0f, 1.0f);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-10.0f, 10.0f, 0.0f);

//		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);    glNormal3f(0.0f, 0.0f, 1.0f);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-10.0f, -10.0f, 0.0f);

//		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f);    glNormal3f(0.0f, 0.0f, 1.0f);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(10.0f, -10.0f, 0.0f);

		// Triangle 2.
//		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f);    glNormal3f(0.0f, 0.0f, 1.0f);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(10.0f, -10.0f, 0.0f);

//		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 1.0f);    glNormal3f(0.0f, 0.0f, 1.0f);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-10.0f, 10.0f, 0.0f);

//		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
//		glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1.0f, 1.0f);
		glTexCoord2f(1.0f, 1.0f);    glNormal3f(0.0f, 0.0f, 1.0f);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(10.0f, 10.0f, 0.0f);

	glEnd();

	glActiveTextureARB(GL_TEXTURE1_ARB);
	glBindTexture(GL_TEXTURE_2D, NULL);
	glDisable(GL_TEXTURE_2D);
	
	glActiveTextureARB(GL_TEXTURE2_ARB);
	glBindTexture(GL_TEXTURE_2D, NULL);
	glDisable(GL_TEXTURE_2D);

	glActiveTextureARB(GL_TEXTURE0_ARB);
	glBindTexture(GL_TEXTURE_2D, NULL);
//	glDisable(GL_TEXTURE_2D);

	glDisable(GL_LIGHTING);

	// were done rendering parallax shaded objects so turn it off
	parallaxShader.TurnOff();
	glPopMatrix();
}

// here are the shaders vertex shader first
/*
 www.UltimateGameProgramming.com
 Parallax Mapping Vertex Shader in GLSlang.
 Created by the Programming Ace.


 Input...
   gl_Vertex = vertex object space position.
   gl_Normal = vertex normal.
   gl_ModelViewProjectionMatrix = current model view projection matrix.
   gl_ModelViewMatrixInverse = current inverse model view matrix.
   gl_MultiTexCoord0.xy = texture coords for unit 0.


 Varying...
   texCoord = output vertex texture coordinates.
   direction = light direction.
   viewDir = camera - vertex direction.


 Output...
   gl_Position = output vertex position.
*/


varying vec2 texCoord;
varying vec3 direction;
varying vec3 viewDir;

uniform vec4 lightPos;
uniform vec3 camPos;


void main()
{
   // Transform vertex to clip space and save tex coord.
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   texCoord = gl_MultiTexCoord0.xy;
   
   // Calculate world space position.
   vec4 pos = gl_ModelViewMatrixInverse * gl_Vertex;
   
   // Calculate the light direction.
   direction = lightPos - gl_Vertex;
   
   // Get the normal.
   vec3 normal = gl_NormalMatrix * gl_Normal;
   
   // Save a copy of the s tangent which was sent through the color (glColor3f).
   vec3 sTangent = gl_Color.xyz;

   // Calculate the binormal as the cross between tangent and normal.
   vec3 binormal = cross(sTangent, normal);
   
   // Create the matrix used to convert the light direction to texture space.
   mat3 tbnMatrix = mat3(sTangent, binormal, normal);

   // Convert light direction to texture space.
   direction = tbnMatrix * direction;

   // Calculate the view direction then convert it to texture space.
   viewDir = camPos - pos;
   viewDir = tbnMatrix * viewDir;
}

// and now the fragment shader
/*
 www.UltimateGameProgramming.com
 Parallax Mapping Pixel Shader in GLSlang.
 Created by the Programming Ace.


 Varying...
   texCoord = output vertex texture coordinates for unit 0.
   direction = light direction in texture space.
   viewDir = camera - vertex direction.


 Uniform...
   decal = decal image texture.
   parallaxMap = height map texture.
   normalMap = bump map texture.

 Output...
   gl_FragColor = output vertex color.
*/


varying vec2 texCoord;
varying vec3 direction;
varying vec3 viewDir;

uniform sampler2D decal;
uniform sampler2D parallaxMap;
uniform sampler2D normalMap;


void main()
{
//   float scale = 0.04f;
//   float bias = 0.02f;
   
   float scale = 0.5f;
   float bias = 0.25f;
   // Normalize the light direction and view vector on a per pixel level.
   direction = normalize(direction);
   viewDir = normalize(viewDir);
   
   // Get the height value and calculate the new texture coord.
   vec3 heightTex = texture2D(parallaxMap, texCoord).xyz;
   float height = scale * heightTex - bias;
   vec2 newTexCoord = height * viewDir + texCoord;
   
   // Get the bump map normal.
   vec3 normalTex = texture2D(normalMap, newTexCoord).xyz;
   
   // Convert from 0 to 1 range to -1 to 1.
   normalTex = (normalTex - 0.5f) * 2;

   // Calculate the bump value as n dot l.
   float dp = saturate(dot(normalTex, direction));
   
   // Get the decal texture color with the new tex coords.
   vec4 decalCol = texture2D(decal, newTexCoord);
   
   // material properties.
   vec4 abmient = vec4(1.0f, 1.0f, 1.0f, 1.0f);
   //vec4 abmient = vec4(0.4f, 0.4f, 0.4f, 1.0f);
   vec4 diffuse = vec4(0.8f, 0.8f, 0.8f, 1.0f);
   diffuse = diffuse * dp;
   
   // Combine the decal with the bump value.
   gl_FragColor = (abmient + diffuse) * decalCol;
}


If you need any more info such as a screenshot please respond with such requests

Share this post


Link to post
Share on other sites
Advertisement
1. Post a screenshot
2. Why are you computing world space vertex position using inverse of the modelview matrix? You should be using normal modelview.

Share this post


Link to post
Share on other sites
Looks like there are many problems.


That's not world space (eye space, camera space). This is
vec4 pos = gl_ModelViewMatrix * gl_Vertex;


This is wrong. Just use gl_Normal
// Get the normal.
vec3 normal = gl_NormalMatrix * gl_Normal;

This is not ideal. Send as a texcoord
vec3 sTangent = gl_Color.xyz;

I'm not 100% sure about this
// Convert light direction to texture space.
direction = tbnMatrix * direction;

You can try this to be sure
direction2.x = dot(sTangent, direction);
direction2.y = dot(binormal, direction);
direction2.z = dot(gl_Normal, direction);

You can put the height map into the alpha of the normal map.

normalTex = (normalTex - 0.5f) * 2;
Maybe
normalTex = 2.0 * normalTex + 1.0;
is faster

Secondly, notice the "f" in 0.5f. Remove that.
normalTex = (normalTex - 0.5f) * 2;

It's also a good idea to make that into
normalTex = normalize(2.0 * normalTex + 1.0);

abmient? You mean ambient

This is from UltimateGameProgramming? I'll be sure not to go there.
Why don't you download Terry Welsh's pdf on the subject. He explains it well and code is better.

Share this post


Link to post
Share on other sites
I made all of those changes but it didn't seem to work, well I made all but the direction one, Did you mean to have it define another direction and add those lines after the original or did you mean for those to replace direction. Also, I was wondering if the shader recompiles every time it's run. And if not is there a way to force it to because I'm not sure my changes are being made. I've severely altered one of my other shaders but it didn't seem to do anything?

Share this post


Link to post
Share on other sites
You replace the code about the direction. I just made up a variable called direction2. You can name it as directionInTangentSpace if it's clearer, but the important thing is not to do this

direction.x = dot(sTangent, direction);
direction.y = dot(binormal, direction);
direction.z = dot(gl_Normal, direction);

Because the first line already modifies direction.x!

Moer comments
If you are using shaders, glEnable and glDisable are ignored. Shaders are a magical world where these have no effect because your shader is executed as written.

glDisable(GL_LIGHTING); Useless!
glEnable(GL_TEXTURE_2D); Useless!
glEnable(GL_LIGHTING); Useless!

Why bind 0?
glBindTexture(GL_TEXTURE_2D, NULL); Useless!

I know that this is for learning, but to be honest, UltimateGameProgramming has done a awful job.

Quote:
Also, I was wondering if the shader recompiles every time it's run. And if not is there a way to force it to because I'm not sure my changes are being made. I've severely altered one of my other shaders but it didn't seem to do anything?


It probably compiles when you call
parallaxShader.InitShaders("shaders/parallaxVS.glsl", "shaders/parallaxPS.glsl");
It's also a good idea to check if compilation fails because your GLSL code was wrong. DON'T put a f after floats! Some old nVidia drivers accepted it but doesn't work elsewhere.

This is Terry Welshs pdf
He also had a working demo but who knows where it is now.
http://www.cs.ualberta.ca/~keith/610/papers/parallax_mapping.pdf

Try these guys for learning to use shaders (GLSL)
http://lighthouse3d.com/opengl/

GLSL specification
http://www.opengl.org/documentation/glsl/

Tools for GLSL, runnable programs, GLSL validator to check your shaders for errors (reference GLSL compiler).
http://developer.3dlabs.com/

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!