2
votes

I success to generate the height map using texture in openGL. The full picture of this data is shown in the figure below. However, when I'm using GL_LINEAR option in my glTexParameteri (MinMag) it give me outer artifacts.

this is my glTexParameter

if (interpolate) {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Here is my fragment shader code

    "varying vec2 tex;\n"
    "uniform int colorSizeI;\n"
    "uniform vec4 colorTable[512];\n"
    "uniform vec2 minmaxZ;\n"
    "uniform vec3 backgroundColor;\n"
    "uniform sampler2D diffuse;\n"
    "uniform float transparency;\n"
    "void main() {\n"
    "   float color = texture2D(diffuse, tex).r;\n"
    "   float h = (color - minmaxZ[0])/(minmaxZ[1] - minmaxZ[0]);\n"
    "   float colorSizeF = float(colorSizeI);\n"
    "   int i = 0;\n"
    "   float j = 0.0f;\n"
    "   vec3 base;\n"
    "   if (color == 0.0f) {\n"
    "       base = vec3(0.0f, 0.0f, 0.0f);}\n"
    "   else if (color <= minmaxZ[0]) {\n"
    "       base = colorTable[0].xyz;}\n"
    "   else if (color >= minmaxZ[1]) {\n"
    "       base = colorTable[colorSizeI - 1].xyz;}\n"
    "   else { \n"
    "       while (h >= (j + 1.0f)/colorSizeF) {\n"
    "           i += 1;\n"
    "           j += 1.0f;}\n"
    "       base = mix(colorTable[i].xyz, colorTable[i+1].xyz, colorSizeF*(h - (j/colorSizeF)));}\n"
    "   gl_FragColor = vec4(base, transparency);\n"
    "}\n";

Here is the image when using GL_Nearest (everything is OK) using GL Nearest

Here is the image when using GL_Linear (outer interpolated artifacts comes out) using GL Linear

So, anyone know how to remove this artifacts ?

NB: The outer black color is consider the data also when color = 0.

3
clamp the edges GL_CLAMP_TO_EDGE or GL_CLAMP - keith
I used GL_CLAMP_TO_EDGE, I forgot to mention, the outer black color outside the square actually data also when the z = 0; So I don't believe it's because the texturewrap. - zufryy
you're going to have to provide all the ::glTexParameteri calls so we can see what you're doing - keith
what happens if you do gl_FragColor = texture2D(diffuse, tex) - keith
I'm using texture to avoid using the vertices & indices (reduces memory). In the texture (red) data is contain the heightmap that will be show in color based on the calculation in fragment shader. So if I do gl_FragColor = texture2D(diffuse, tex) it won't display the data that I want to show. - zufryy

3 Answers

1
votes

I assume your wrapping for the texture is currently GL_REPEAT. You should try another one.

GL_MIRRORED_REPEAT or GL_CLAMP_TO_EDGE should work.

1
votes

The error is because of interpolating from "null color" to actual colors in the colr table. To put it short: you can't do that. The concept is broken. Back to the drawing board.

The simplest solution is not having null color, limiting the quad to only the valid area, and doing GL_CLAMP_TO_EDGE as others suggested.

A trickier way is setting GL_NEAREST and then writing the linear sampling yourself in the shader, sampling the texture with tex plus some offsets (manhattan distance should be fine) and skip the null color when blending (the skip part is what is missing from your original concept). The tricky part is getting the offsets right.

1
votes

I managed to fixed it with making an outer boundary with the value of interpolation of nearest pixels and put alpha = 0 for that.

It worked nicely, however it cost 2 times of original memory consumption since I need to store the alpha map also.

final