Jump to content
  • Advertisement
Sign in to follow this  
Enalis

GLSL Parallax Mapping

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

Parallax mapping seems somewhat simple. I understand the equations and have shaders set up to perform it. Thing is I need another more keen eye in the ways of GLSL to take a look at this code. I can't figure out what's wrong with it. I am currently supplying correct variables please take a look.
// vertex shader
varying vec3 normal, lightVector, halfVector, viewVector, texCoord;
	
void main()
{
	vec4 worldPos;

	normal = normalize(gl_NormalMatrix * gl_Normal);
	vec3 tangent = gl_MultiTexCoord1.xyz;;
	vec3 binormal = cross(tangent, normal);

	mat3 TBNMatrix;
	TBNMatrix[0] =  gl_NormalMatrix * tangent;
	TBNMatrix[1] =  gl_NormalMatrix * binormal;
	TBNMatrix[2] =  normal;

	worldPos = gl_ModelViewMatrix * gl_Vertex;
	lightVec = normalize(vec3(gl_LightSource[0].position - worldPos));

	viewVector = vec3(-worldPos) * TBNMatrix ;

	halfVector = normalize(gl_LightSource[0].halfVector.xyz);

	gl_TexCoord[0] = gl_MultiTexCoord0;
	texCoord = glMultiTexCoord0;
	gl_Position = ftransform();

}

// fragment shader
varying vec3 normal, lightVector, halfVector, viewVector, texCoord;
uniform sampler2D decalMap, heightMap, normalMap;

void main()
{
	vec4 diffuseLight, specularLight;	
	float shine = 64.0;
	float scale = 0.5;
	float bias = 0.25;

	normal = normalize(normal);
	lightVector = normalize(lightVector);
	viewVector = normalize(viewVector);

	// Get the height value and calculate the new texture coord.
	float height = scale * texture2D(heightMap, texCoord).r - bias;
	vec2 newTexCoord = height * viewVector + texCoord;

	// Get the bump map normal.
	vec3 normalTex = texture2D(normalMap, newTexCoord).xyz;
	
	// Convert from 0 to 1 range to -1 to 1.
	normalTex = normalize(2.0 * normalTex + 1.0);

	// Calculate the bump value as n dot l.
	float dp = saturate(dot(normalMap, lightVector));
	
	// Get the decal texture color with the new tex coords.
	vec4 decalCol = texture2D(decalMap, newTexCoord);

	float lightIntensity = max(dot(normal, lightVector), 0.0);

	diffuseLight = lightIntensity * gl_LightSource[0].diffuse;
	diffuseLight = diffuseLight * dp;
	specularLight = pow(max(dot(n, normalize(halfVector)), 0.0), shine) * gl_LightSource[0].specular;
	
	vec4 lightColor = diffuseLight + specularLight + gl_LightSource[0].ambient;

	vec4 texColor = texture2D(decalMap,newTexCoord);

	vec4 color = texColor * lightColor;
	gl_FragColor = color;
}



Please have a look and please ask any questions and I'll respond. My current results are a black square, that's it, no lighting, no textures... :(

Share this post


Link to post
Share on other sites
Advertisement
Have you checked the shader log? A black square might be a result of the fragment program not being bound. Two things I could spot are:

Quote:
lightVec = normalize(vec3(gl_LightSource[0].position - worldPos));
I can't find lightVec declared anywhere, maybe oyu meant lightVector (since there is an active varying by that name whose value you haven't set)?

Quote:
vec3 tangent = gl_MultiTexCoord1.xyz;;
Two semicolons after that line. The compiler may ignore an empty statement, or it may issue an error (I don't know).

Share this post


Link to post
Share on other sites
Quote:
Original post by Enalis
How does one check said shader log?

You can get the compiler output by using glGetInfoLogARB. This usually contains something like "Shader will run in hardware/software" or will give you an error message.

A black square can also mean not having a sampler bound correctly but it looks like you have an error in the shader.

Hope that helps

Share this post


Link to post
Share on other sites
Got it working and you were right. There is one error in each file. If I fix those and still doesn't work I'll reply, thanks for your help!

Share this post


Link to post
Share on other sites
Ok, here's what I'm down to.
In the fragment shader only here are the errors

(18) : error C1020 : invalid operands to "add"
(18) : error C1056 : invalid initialization
(27) : warning C7506 : Opengl does not define the global function saturate


varying vec3 normal, lightVector, halfVector, viewVector, texCoord;
uniform sampler2D decalMap, heightMap, normalMap;

void main()
{
vec4 diffuseLight, specularLight;
float shine = 64.0;
float scale = 0.5;
float bias = 0.25;

normal = normalize(normal);
lightVector = normalize(lightVector);
viewVector = normalize(viewVector);

// Get the height value and calculate the new texture coord.
float height = scale * texture2D(heightMap, gl_TexCoord[0]).r - bias;
vec2 newTexCoord = height * viewVector + gl_TexCoord[0];

// Get the bump map normal.
vec3 normalTex = texture2D(normalMap, newTexCoord).xyz;

// Convert from 0 to 1 range to -1 to 1.
normalTex = normalize(2.0 * normalTex + 1.0);

// Calculate the bump value as n dot l.
float dp = saturate(dot(normalMap, lightVector));

// Get the decal texture color with the new tex coords.
vec4 decalCol = texture2D(decalMap, newTexCoord);

float lightIntensity = max(dot(normal, lightVector), 0.0);

diffuseLight = lightIntensity * gl_LightSource[0].diffuse;
diffuseLight = diffuseLight * dp;
specularLight = pow(max(dot(n, normalize(halfVector)), 0.0), shine) * gl_LightSource[0].specular;

vec4 lightColor = diffuseLight + specularLight + gl_LightSource[0].ambient;

vec4 texColor = texture2D(decalMap,newTexCoord);

vec4 color = texColor * lightColor;
// vec4 color = texture2D(decalMap, texCoord) * 1.0;
gl_FragColor = color;
}



Share this post


Link to post
Share on other sites
I had to count to find the right lines - but anyway here's what you should do:

Quote:
Original post by Enalis
(18) : error C1020 : invalid operands to "add"
(18) : error C1056 : invalid initialization

You are doing a vec2 = vec3 + vec4. If you want to ignore that latter components, what you want is something like:
vec2 newTexCoord = height * viewVector.xy + gl_TexCoord[0].st;

Quote:
(27) : warning C7506 : Opengl does not define the global function saturate

As it says, GLSL doesn't have a function called saturate(). I think HLSL's saturate() clamps the value to a [0, 1] range (not sure) and if that's the case you need:
float dp = clamp(dot(normalMap, lightVector), 0.0, 1.0);

Share this post


Link to post
Share on other sites
Quote:
Original post by Enalis
(27) : warning C7506 : Opengl does not define the global function saturate

#27 is a warning. If you remove the two previous errors, it should run ok, if you are using NVidia. If you're on an ATI, then you need to use clamp.

Share this post


Link to post
Share on other sites
Ok, thank you all for your help so far. But now here's the new problem, shit is what the shader looks like and it's not good.
Broken Parallax Shader

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!