PDA

View Full Version : relief mapping: artifacts at polygon boundaries



Neelix8472
08-10-2008, 03:51 AM
Hi,
I've been trying to implement the Relief Mapping algorithm found in GPUGems3, which works quite well. However, I've encountered some strange artifacts. When I enable mipmapping, I get wrong pixels at the boundaries between the two triangles as seen in the picture.
I've also tried a simple linear search which yields the same results.
With disabled mip-mapping the result is correct and without relief mapping and enabled mipmapping the result is also correct.
The resulting texture coords are correct, it's just that sampling these coords in a mipmapped texture leads to wrong results.

Has anyone encountered such a problem before?
Thanks,
http://img225.imageshack.us/img225/433/reliefbugqy5.jpg

arekkusu
08-10-2008, 10:51 AM
Is your sample inside of a conditional?

Derivatives are undefined inside conditionals. That's why we have texture*Grad().

Neelix8472
08-10-2008, 11:40 AM
The texture is not sampled inside a conditional.
I don't quite understand what you mean by texture*Grad(). As far as I understand it, mipmapping needs the derivative to work, but I don't see how I can influence this process at all.
Maybe I'm doing something else wrong in the shader?
vertex shader:


varying vec2 vTexCoord;
varying vec3 lightDir, vEyeVec, vTangent, vBinormal, vNormal, vPos;

uniform vec3 vPlayerPosition;

void main()
{
vTangent = gl_MultiTexCoord0.rgb;
vBinormal = gl_MultiTexCoord1.rgb;
vNormal = gl_Normal.rgb;


mat3 TBNMatrix = mat3(vTangent, vBinormal, vNormal);
vEyeVec = vPlayerPosition - gl_Vertex.rgb;
vEyeVec *= TBNMatrix;

vTexCoord = gl_MultiTexCoord2.rg;

gl_Position = ftransform();
}

fragment shader:


varying vec2 vTexCoord;
varying vec3 lightDir, vEyeVec, vTangent, vBinormal, vNormal, vPos;

uniform vec3 vPlayerPosition;
uniform sampler2D oDiffuse;
uniform sampler2D oHeight;


void main (void)
{
const float fDepthScale = 0.1;
const int iNumSteps = 50;

int iStep = 0;
float fStep = (1.0 / float(iNumSteps));

vec2 vDelta = (vEyeVec.xy * fDepthScale / (float(iNumSteps) * vEyeVec.z));
vec2 vCoord = vTexCoord.xy;

float fHeight = 1.0;
vec4 vNormal = vec4(0.0);

//linear search
while (iStep < iNumSteps)
{
vNormal = (1.0 - texture2D (oHeight, vCoord));
iStep++;
fHeight -= fStep;
vCoord -= vDelta;

if(vNormal.r > fHeight)
{
break;
}
}

gl_FragColor.rgb = texture2D (oDiffuse, vCoord.xy).rgb;
}

Neelix8472
08-10-2008, 12:55 PM
Now I understand you^^
I actually didn't know there was a texture2DGrad function.
By using
vec2 dPdx = dFdx(vTexCoord);
vec2 dPdy = dFdy(vTexCoord);
and
gl_FragColor.rgb = texture2DGrad(oDiffuse, vCoord, dPdx, dPdy).rgb;
to sample the texture I did solve the problem.

Thank you very much for your help!

NULL_PTR
08-10-2008, 01:25 PM
On ATI, you have to use texture2DdP_ARB or texture2DGradARB