Sign in to follow this  
Ingrater

OpenGL [partly solved]Error pixels in Parralax occulsion shader

Recommended Posts

Ingrater    187
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
Farfadet    175
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
Ingrater    187
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
Ingrater    187
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  

  • Similar Content

    • By povilaslt2
      Hello. I'm Programmer who is in search of 2D game project who preferably uses OpenGL and C++. You can see my projects in GitHub. Project genre doesn't matter (except MMO's :D).
    • By ZeldaFan555
      Hello, My name is Matt. I am a programmer. I mostly use Java, but can use C++ and various other languages. I'm looking for someone to partner up with for random projects, preferably using OpenGL, though I'd be open to just about anything. If you're interested you can contact me on Skype or on here, thank you!
      Skype: Mangodoor408
    • By tyhender
      Hello, my name is Mark. I'm hobby programmer. 
      So recently,I thought that it's good idea to find people to create a full 3D engine. I'm looking for people experienced in scripting 3D shaders and implementing physics into engine(game)(we are going to use the React physics engine). 
      And,ye,no money =D I'm just looking for hobbyists that will be proud of their work. If engine(or game) will have financial succes,well,then maybe =D
      Sorry for late replies.
      I mostly give more information when people PM me,but this post is REALLY short,even for me =D
      So here's few more points:
      Engine will use openGL and SDL for graphics. It will use React3D physics library for physics simulation. Engine(most probably,atleast for the first part) won't have graphical fron-end,it will be a framework . I think final engine should be enough to set up an FPS in a couple of minutes. A bit about my self:
      I've been programming for 7 years total. I learned very slowly it as "secondary interesting thing" for like 3 years, but then began to script more seriously.  My primary language is C++,which we are going to use for the engine. Yes,I did 3D graphics with physics simulation before. No, my portfolio isn't very impressive. I'm working on that No,I wasn't employed officially. If anybody need to know more PM me. 
       
    • By Zaphyk
      I am developing my engine using the OpenGL 3.3 compatibility profile. It runs as expected on my NVIDIA card and on my Intel Card however when I tried it on an AMD setup it ran 3 times worse than on the other setups. Could this be a AMD driver thing or is this probably a problem with my OGL code? Could a different code standard create such bad performance?
    • By Kjell Andersson
      I'm trying to get some legacy OpenGL code to run with a shader pipeline,
      The legacy code uses glVertexPointer(), glColorPointer(), glNormalPointer() and glTexCoordPointer() to supply the vertex information.
      I know that it should be using setVertexAttribPointer() etc to clearly define the layout but that is not an option right now since the legacy code can't be modified to that extent.
      I've got a version 330 vertex shader to somewhat work:
      #version 330 uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ModelViewMatrix; layout(location = 0) in vec4 Vertex; layout(location = 2) in vec4 Normal; // Velocity layout(location = 3) in vec3 TexCoord; // TODO: is this the right layout location? out VertexData { vec4 color; vec3 velocity; float size; } VertexOut; void main(void) { vec4 p0 = Vertex; vec4 p1 = Vertex + vec4(Normal.x, Normal.y, Normal.z, 0.0f); vec3 velocity = (osg_ModelViewProjectionMatrix * p1 - osg_ModelViewProjectionMatrix * p0).xyz; VertexOut.velocity = velocity; VertexOut.size = TexCoord.y; gl_Position = osg_ModelViewMatrix * Vertex; } What works is the Vertex and Normal information that the legacy C++ OpenGL code seem to provide in layout location 0 and 2. This is fine.
      What I'm not getting to work is the TexCoord information that is supplied by a glTexCoordPointer() call in C++.
      Question:
      What layout location is the old standard pipeline using for glTexCoordPointer()? Or is this undefined?
       
      Side note: I'm trying to get an OpenSceneGraph 3.4.0 particle system to use custom vertex, geometry and fragment shaders for rendering the particles.
  • Popular Now