Chris Weaver

03-04-2008, 02:07 AM

I'm trying to do parallax bump mapping and environment mapping but there seems to be something wrong with the transformations or vectors in my shaders. I'm fairly sure the tangent space vectors and the world transform are correct, but when using the following code I get two problems:

a. The parallax effect is not 3d and is 'swimming' over the surface with different viewing angles and distorting where it should be offset.

b. The reflections are all incorrect as if the cube map is rotated 90deg and distort/stretch off to infinity at shallow viewing angles.

Can anyone see what I maybe doing wrong?

Vertex Shader

#version 120

attribute vec3 Normal; // Object space normal

attribute vec3 Tangent; // Object space tangent

attribute vec3 Binormal; // Object space binormal

attribute vec3 BumpMultiTexCoord; // Using instead of gl_MultiTexCoord1

uniform mat4 View2World; // View space to world matrix

varying vec3 view;

varying vec3 normal;

varying mat3 tbnWorldMatrix; // Tangent to world space matrix

varying vec2 bumpTexCoord;

void main(void)

{

gl_TexCoord[0] = gl_MultiTexCoord0; // Base Texture coords

gl_Position = ftransform();

bumpTexCoord.xy = BumpMultiTexCoord.xy; // Bump map coords

// Calculate view to tangent space matrix

vec3 t = normalize(gl_NormalMatrix * Tangent);// Tangent object -> view space

vec3 b = normalize(gl_NormalMatrix * Binormal); // Binormal object -> view

vec3 n = normalize(gl_NormalMatrix * Normal); // Normal object -> view space

mat3 tbnMatrix = mat3(t, b, n);

// Calculate tangent space normal

normal = normalize(gl_NormalMatrix * Normal); // View space normal

normal = normalize(normal) * tbnMatrix;

// Calculate view space view vector

vec4 vert = gl_ModelViewMatrix * gl_Vertex;

vec3 viewVec = vec3(-vert);

// Calculate tangent space view vector

// ** Reflections work better without the normalize here for some reason? **

view = normalize(viewVec) * tbnMatrix;

// Calculate tangent to world matrix

tbnWorldMatrix = transpose(tbnMatrix) * mat3(Cam2World);

}

Fragment Shader

#version 120

uniform sampler2D BaseTexture;

uniform samplerCube CubeMap;

uniform sampler2D BumpMap;

uniform mat4 View2World;

varying vec4 col;

varying vec3 view;

varying vec3 normal;

varying mat3 tbnWorldMatrix;

varying vec2 bumpTexCoord;

void main(void)

{

vec2 cBumpSize;

cBumpSize.x = 0.04200002;

cBumpSize.y = -0.0299999;

// Find parallax offset

float height = texture2D(BumpMap, bumpTexCoord.xy).a;

height = height * cBumpSize.x + cBumpSize.y;

vec3 viewVec = normalize(view);

vec2 newBaseUV = gl_TexCoord[0].xy + viewVec.xy * height;

// View vector in tangent space for fragment

vec3 V = normalize(view);

// Calculate reflection vector of view vector around normal

vec3 N = normalize(normal);

vec3 R = reflect(V, N);

// Transform reflected vector back into world space

R = tbnWorldMatrix * normalize(R);

// Look up into the env_map after transforming into world coordinates

gl_FragColor.rgb = textureCube(CubeMap, R).rgb;

// Apply parallax mapping

// gl_FragColor.rgb = texture2D(BaseTexture, newBaseUV).rgb;

gl_FragColor.a = 1.0;

}

Some of this code is from the Shader Designer examples, but I seem to be doing something wrong.

Thanks in advance.

a. The parallax effect is not 3d and is 'swimming' over the surface with different viewing angles and distorting where it should be offset.

b. The reflections are all incorrect as if the cube map is rotated 90deg and distort/stretch off to infinity at shallow viewing angles.

Can anyone see what I maybe doing wrong?

Vertex Shader

#version 120

attribute vec3 Normal; // Object space normal

attribute vec3 Tangent; // Object space tangent

attribute vec3 Binormal; // Object space binormal

attribute vec3 BumpMultiTexCoord; // Using instead of gl_MultiTexCoord1

uniform mat4 View2World; // View space to world matrix

varying vec3 view;

varying vec3 normal;

varying mat3 tbnWorldMatrix; // Tangent to world space matrix

varying vec2 bumpTexCoord;

void main(void)

{

gl_TexCoord[0] = gl_MultiTexCoord0; // Base Texture coords

gl_Position = ftransform();

bumpTexCoord.xy = BumpMultiTexCoord.xy; // Bump map coords

// Calculate view to tangent space matrix

vec3 t = normalize(gl_NormalMatrix * Tangent);// Tangent object -> view space

vec3 b = normalize(gl_NormalMatrix * Binormal); // Binormal object -> view

vec3 n = normalize(gl_NormalMatrix * Normal); // Normal object -> view space

mat3 tbnMatrix = mat3(t, b, n);

// Calculate tangent space normal

normal = normalize(gl_NormalMatrix * Normal); // View space normal

normal = normalize(normal) * tbnMatrix;

// Calculate view space view vector

vec4 vert = gl_ModelViewMatrix * gl_Vertex;

vec3 viewVec = vec3(-vert);

// Calculate tangent space view vector

// ** Reflections work better without the normalize here for some reason? **

view = normalize(viewVec) * tbnMatrix;

// Calculate tangent to world matrix

tbnWorldMatrix = transpose(tbnMatrix) * mat3(Cam2World);

}

Fragment Shader

#version 120

uniform sampler2D BaseTexture;

uniform samplerCube CubeMap;

uniform sampler2D BumpMap;

uniform mat4 View2World;

varying vec4 col;

varying vec3 view;

varying vec3 normal;

varying mat3 tbnWorldMatrix;

varying vec2 bumpTexCoord;

void main(void)

{

vec2 cBumpSize;

cBumpSize.x = 0.04200002;

cBumpSize.y = -0.0299999;

// Find parallax offset

float height = texture2D(BumpMap, bumpTexCoord.xy).a;

height = height * cBumpSize.x + cBumpSize.y;

vec3 viewVec = normalize(view);

vec2 newBaseUV = gl_TexCoord[0].xy + viewVec.xy * height;

// View vector in tangent space for fragment

vec3 V = normalize(view);

// Calculate reflection vector of view vector around normal

vec3 N = normalize(normal);

vec3 R = reflect(V, N);

// Transform reflected vector back into world space

R = tbnWorldMatrix * normalize(R);

// Look up into the env_map after transforming into world coordinates

gl_FragColor.rgb = textureCube(CubeMap, R).rgb;

// Apply parallax mapping

// gl_FragColor.rgb = texture2D(BaseTexture, newBaseUV).rgb;

gl_FragColor.a = 1.0;

}

Some of this code is from the Shader Designer examples, but I seem to be doing something wrong.

Thanks in advance.