Thread: Parallax mapping woes.

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071

    Parallax mapping woes.

    I've been spending the last couple of nights trying to get a nice parallax mapping shader working.

    I've had some sucesss - in most cases, it works and looks pretty good.

    I'm using a cube as a test object. On some sides of the cube, the offset may not be quite in the right direction, and on others, at certain angles the parallax offset effect because far greater than normal, and at a different angle much less than normal.

    The screenshot I'm posting is just one case. If you need more to illustrate the problem I'm trying to describe, just ask.

    I think it might be the way I'm calculating the
    tangent space view vector, but I don't know for sure.

    I also have a similar problem with the lighting (inconsistancy accross the faces/angles/directions).

    Vertex Program (GLSL):
    Code:
    attribute vec3 tangent;
    uniform vec4 viewPos; //object space
    uniform vec4 lightPos; //object space - not used
    
    varying vec3 normal;
    varying vec3 lightVec;
    varying vec3 eyeVec;
    varying vec2 texCoords;
    
    void main(void)
    {
    	vec3 vertex = (gl_ModelViewMatrix*gl_Vertex).xyz;
    	vec3 vertexInv = (gl_ModelViewMatrixInverse*gl_Vertex).xyz;
    	normal = normalize(gl_NormalMatrix*gl_Normal);
    	vec3 bitangent = cross(normal, tangent);
    	mat3 tbn = mat3(tangent, bitangent, normal);
    
    	vec3 L = normalize(gl_LightSource[0].position.xyz-vertex);
    	lightVec = L*tbn;
    
    	vec3 E = viewPos.xyz-gl_Vertex.xyz;
    	eyeVec = E*tbn;
    	eyeVec *= vec3(1,-1,1);
    
    	texCoords = gl_MultiTexCoord0.xy;
    	gl_Position = ftransform();
    }
    Fragment Shader (GLSL - parallax shifting code highlighted)
    Code:
    uniform sampler2D baseMap;
    uniform sampler2D bumpMap; //requires 32-bit texture - parallax map in alpha channel
    
    varying vec3 normal;
    varying vec3 lightVec;
    varying vec3 eyeVec;
    varying vec2 texCoords;
    
    const float scale = 0.05;
    const float bias = -scale/2.0;
    
    vec3 unpackVec(vec4 v)
    {
    	return v.xyz * 2.0 - 1.0;
    }
    
    void main(void)
    {
    	vec3 L = normalize(lightVec);
    	vec3 E = normalize(eyeVec);
    
    	float height = texture2D(bumpMap, texCoords).a*scale+bias;
    	vec2 parallax = texCoords + height * E.xy;
    
    	vec3 bump = texture2D(bumpMap, parallax).xyz*2.0 - 1.0;
    	bump = normalize(bump);
    
    	vec3 reflVec = (2.0*dot(bump, L))*bump - L;
    
    	vec4 ambient = gl_LightSource[0].ambient*gl_FrontMaterial.ambient;
    	vec4 diffuse = (texture2D(baseMap, parallax)*gl_LightSource[0].diffuse*gl_FrontMaterial.diffuse)*max(dot(bump, L), 0.0);
    	vec4 specular = gl_LightSource[0].specular*gl_FrontMaterial.specular*pow(max(dot(reflVec, E), 0.0), gl_FrontMaterial.shininess);
    
    	gl_FragColor = ambient+diffuse+specular;
    }
    Last edited by psychopath; 07-19-2007 at 04:47 PM. Reason: Forgot screenshot
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    The top portion of the cube does not have the illusion of depth because of the angle of the surface in respect to the camera.

    Notice the right side and left sides of the cube. The right side looks nearly perfect and flawless and the left side looks very good but obviously something is wrong with the tangent vectors. The brick depth should be facing in towards the right, not out towards the left. The top surface problem is probably because parallax mapping cannot account for the angle.

    All this is probably due to the angle of the surface with respect to the camera. Part of the problem to is that you go to great extents to make the sides look perfect and mess the illusion up by using the incorrect texture for the top. The brick at the top should have a top to it, yet it does not. It has good looking sides but when you get to the top the texture does not line up and looks very odd. No matter what pains you go through to create the illusion of depth, it will always be lost with the top texture.

    Looks very good though. Excellent work. My guess is your tangent vectors are somehow incorrect at some point.

    On a side note how are you texturing everything in the scene? Are you unwrapping U'V's or using something simpler?
    Last edited by VirtualAce; 07-19-2007 at 11:00 PM.

  3. #3
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    For the cube I just used (sloppy) planar mapping for each side. The scene in the background is a map made with GTKRadiant, so I didn't do any UV mapping there really.

    I don't think the tangent vectors themselves are being caculated wrong - I'm using OGRE as my rendering sub-system now, so I'm assuming if there was a problem there, it would've been caught before now.

    But since the tangents are caculated based on UVs, could it just be the texture mapping as you mentioned throwing everything off? That would account for the problem varying by model and face.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  4. #4
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Well, I tried as an experiment flipping the texture horizontally on the floor of a BSP mesh. It fixed my "backwards lighting" issue, but It's not doing much for the parallax.

    For example, on one wall, the lighting vertically is backwards - if the light is over top of one of the bricks, the bottom of that brick will be lit. But the parallax mapping on that wall works fine, so fipping the texture to fix the lighting will kill the parallax mapping.

    On another wall, the lighting is fine, but the parallax is backwards.

    The floor seems fine as far as the vertical shift goes, but looking accross the floor horizontal to the texture doesn't seem to work - it just shifts the vertical coord more.

    The ceiling shifts opposite of the floor.

    On another wall, I can look straight at it, and the parallax will be shifted to the left.

    There's also a weird issue in some cases where the lighting on the bumps will "flip" depending on the view direction.

    Is there some way I can correct this stuff based on the normal or something?
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OpenGL texture mapping with texCoordArray
    By nempo in forum Game Programming
    Replies: 1
    Last Post: 08-24-2008, 04:00 AM
  2. MapServer and other mapping tools
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 12-29-2007, 02:27 AM
  3. OpenGL Shadow Mapping Issues
    By animeaholic in forum Game Programming
    Replies: 0
    Last Post: 06-05-2007, 09:49 AM
  4. Mapping network drives
    By Morgan in forum Windows Programming
    Replies: 4
    Last Post: 07-19-2004, 04:07 AM
  5. Texture mapping in OpenGL
    By Dragon in forum Game Programming
    Replies: 5
    Last Post: 10-19-2003, 09:47 AM