Sign in to follow this  
Ingrater

OpenGL [partly solved]Error pixels in Parralax occulsion shader

Recommended Posts

I tried to write a parrallax occulsion shader in ATI's Rendermonkey and GLSL. It does work so far but unfortunately some Error pixels show up in some cases and I have no clue why. A screen can be found here: http://stuff.benjamin-thaut.de/opengl/parallax.jpg Vertex Shader:
uniform vec3 fvLightPosition;
uniform vec3 fvEyePosition;

varying vec2 Texcoord;
varying vec3 ViewDirection;
varying vec3 LightDirection;
   
attribute vec3 rm_Binormal;
attribute vec3 rm_Tangent;
   
void main( void )
{
   gl_Position = ftransform();
   Texcoord    = gl_MultiTexCoord0.xy * 2.0;
    
   vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
   
   vec3 fvViewDirection  = normalize(fvObjectPosition.xyz);
   vec3 fvLightDirection = normalize( fvLightPosition - fvObjectPosition.xyz );
     
   vec3 fvNormal         = gl_NormalMatrix * gl_Normal;
   vec3 fvBinormal       = gl_NormalMatrix * rm_Binormal;
   vec3 fvTangent        = gl_NormalMatrix * rm_Tangent;
      
   ViewDirection.x  = dot( fvTangent, fvViewDirection );
   ViewDirection.y  = dot( fvBinormal, fvViewDirection );
   ViewDirection.z  = dot( fvNormal, fvViewDirection );
   
   LightDirection.x  = dot( fvTangent, fvLightDirection.xyz );
   LightDirection.y  = dot( fvBinormal, fvLightDirection.xyz );
   LightDirection.z  = dot( fvNormal, fvLightDirection.xyz );
   
}

Fragment Shader
uniform vec4 fvAmbient;
uniform vec4 fvSpecular;
uniform vec4 fvDiffuse;
uniform float fSpecularPower;

uniform sampler2D baseMap;
uniform sampler2D bumpMap;
uniform sampler2D heightMap;

varying vec2 Texcoord;
varying vec3 ViewDirection;
varying vec3 LightDirection;

vec4 TraceRay(in float height, in float start, in float stop, in float steps, in vec2 coords, in vec3 dir){
  float diff = (start - stop) / steps;
  vec4 CurrentPoint = vec4(coords.x, coords.y, 0.0,0.0);
  float CurrentHeight = texture2D(heightMap,CurrentPoint.xy).r;
  float f;
  for(f=start;f>=stop;f-=diff){
    if(f <= CurrentHeight)
      break;
    CurrentPoint.xy += -dir.xy * diff * height;
    CurrentHeight = texture2D(heightMap,CurrentPoint.xy).r;
  }
  CurrentPoint.xy -= -dir.xy * diff * height;
  CurrentPoint.z = f + diff;
  CurrentPoint.w = f;
  return CurrentPoint;
}

void main( void )
{
   vec3  fvLightDirection = normalize( LightDirection );
   vec3  fvViewDirection  = normalize( ViewDirection );
   
   vec4  NewCoord = TraceRay(0.2,1.0,0.0,10.0,Texcoord,fvViewDirection);
   NewCoord = TraceRay(0.2,NewCoord.z,NewCoord.w,5.0,NewCoord.xy,fvViewDirection);
   
   vec3  fvNormal         = normalize( ( texture2D( bumpMap, NewCoord.xy ).xyz * 2.0 ) - 1.0 );
   float fNDotL           = dot( fvNormal, fvLightDirection ); 
   
   vec3  fvReflection     = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); 
   float fRDotV           = max( 0.0, dot( fvReflection, fvViewDirection ) );
   
   vec4  fvBaseColor      = texture2D( baseMap, NewCoord.xy );
   
   vec4  fvTotalAmbient   = fvAmbient * fvBaseColor; 
   vec4  fvTotalDiffuse   = fvDiffuse * fNDotL * fvBaseColor; 
   vec4  fvTotalSpecular  = fvSpecular * ( pow( fRDotV, fSpecularPower ) );
  
   gl_FragColor = ( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular );
       
}

This shader is a modification of the default textured bump sample and because of that the transformation of the vectors into tangent space should be correct. Why do those error pixels appear? [Edited by - Ingrater on March 26, 2008 10:59:55 AM]

Share this post


Link to post
Share on other sites
Hi,

I'm not sure, but my guess is that this is not due to the shader, that looks fine, but rather to the UV map. The "error pixels" are clearly at the edges of the polygons (or not ?), and this is the kind of artefact you get when polygons are just scattered on the texture instead of nicely unfold. If I am right, then the background color of your texture should be the light grey color of your "error pixels".

Share this post


Link to post
Share on other sites
I've checked that. It indeed seems to be only on the edge pixels but not due to an error in the UV coordinates. I tried out every example mesh avibale with RenderMonkey. The errors occured on every mesh. Additionally I tested the dx9 parallax occulsion example from RenderMonkey with the same meshes and no error pixels appeared, so there has to be an mistake somewhere in my shader.

Edit: Found out that the error pixels disappear if I disable the second searching step, still trying to find out why...

Edit2: I changed the TraceRay function to

vec4 TraceRay(in float height, in float start, in float stop, in float steps, in vec2 coords, in vec3 dir){
float diff = (start - stop) / steps;
vec4 CurrentPoint = vec4(coords.x, coords.y,0.0,0.0);
float CurrentHeight = texture2D(heightMap,CurrentPoint.xy).r;
float f;
//added
if(start < CurrentHeight){
CurrentPoint.z = start;
CurrentPoint.w = stop;
return CurrentPoint;
}
//added end
for(f=start;f>=stop;f-=diff){
CurrentPoint.xy += dir.xy * diff * height;
if(f < CurrentHeight)
break;
CurrentHeight = texture2D(heightMap,CurrentPoint.xy).r;
}
CurrentPoint.xy -= dir.xy * diff * height;
CurrentPoint.z = f + diff;
CurrentPoint.w = f;
return CurrentPoint;
}


Now the error pixels accour on every edge pixel and also already in the first searching step, do I remove the added code no error pixels accour in the first searching step, but in the second. The question is now what exactly happens on the edges that start is always smaller than the starting height?
For me this is not even possible because the higehst value of the texture can be 1.0 and the startvalue of the first search step is also 1.0?

[Edited by - Ingrater on March 24, 2008 4:58:49 PM]

Share this post


Link to post
Share on other sites
Still searching for the cause. The RenderMonkey project can be found here:

http://stuff.benjamin-thaut.de/opengl/parallax.rfx

Edit: Figured out that is a commom issue of using a texture sampler inside of an flow control. Because of some error in the mipmap-calculasions a wrong mipmap is selected and due to the fact that the mipmap levels are calculated on a 2x2 pixel basis, those error pixels accour. The Problem can be solved by using the texture2DGrad function and calculating the ddx and ddy factors manually using the GLSL dFdx() and dFdy() functions. Unfortunately I don't have a clue what to pass to this functions to get the correct values, so I would appreciate it if someone could explain that to me.

[Edited by - Ingrater on March 26, 2008 10:30:54 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this