# GLSL Parallax Mapping

This topic is 4555 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## 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();

}

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 on other sites
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 on other sites
How does one check said shader log?

##### Share on other sites
Quote:
 Original post by EnalisHow 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 on other sites
That function seems to crash the program, I even got the correct length to feed it.

##### 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 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 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 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 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.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 13
• 9
• 9
• 15
• ### Forum Statistics

• Total Topics
634076
• Total Posts
3015353
×