1

I'm working on a volumetric rendering application where I have to cut planes of my volumetric data. The problem is that, given a limited resolution, I get some artifacts on the borders of the white zones.

The volume is a GLubyte M[depth][width][height] where there are 255s and 0s. As you can see there are evident problems on the borders when I rotate my model.

I have the following settings of OpenGL already:

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glEnable(GL_TEXTURE_3D);
glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE, iWidth, iHeight, iDepth, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, M);
gluBuild3DMipmaps(texName,GL_LUMINANCE,iWidth,iHeight,iDepth, GL_LUMINANCE, GL_UNSIGNED_BYTE, M);

I'm wondering if is possible to write a bilinear filter in GLSL for texture3D using sampler3D that helps to smooth out the grainy borders or those annoying artifacts.

There are many examples of bilinear filtering for texture2D but I can't find one for 3D textures.

Is it possible to adapt this code to a 3D sampler?

const float textureSize = 512.0; //size of the texture
const float texelSize = 1.0 / textureSize; //size of one texel
vec4 texture2DBilinear( sampler2D textureSampler, vec2 uv )
{
    // in vertex shaders you should use texture2DLod instead of texture2D
    vec4 tl = texture2D(textureSampler, uv);
    vec4 tr = texture2D(textureSampler, uv + vec2(texelSize, 0));
    vec4 bl = texture2D(textureSampler, uv + vec2(0, texelSize));
    vec4 br = texture2D(textureSampler, uv + vec2(texelSize , texelSize));
    vec2 f = fract( uv.xy * textureSize ); // get the decimal part
    vec4 tA = mix( tl, tr, f.x ); // will interpolate the red dot in the image
    vec4 tB = mix( bl, br, f.x ); // will interpolate the blue dot in the image
    return mix( tA, tB, f.y ); // will interpolate the green dot in the image
}

or is it possible to have a better interpolation without increasing the size of the volume data (it's actually 512x512x512 GLubyte)

linello
  • 8,451
  • 18
  • 63
  • 109
  • What was wrong with regular 'ole `GL_LINEAR` filtering? – genpfault Jun 20 '13 at 14:42
  • When you say "cut planes", you simply want to render a plane textured by the 3D texture, right? Are those artifacts around the border actually present in the volume data? Why do you use mipmaps? Why don't you post your shader? Which OpenGL version do you use (`texture2D`/`texture3D` have been deprecated in 3.3 and replaced by `texture`)? – Andreas Haferburg Jun 20 '13 at 19:48
  • I've replaced texture3D with texture and removed gluBuildMipMaps: My shader is very simple, I'm rendering a paraboloid of which i control the 2nd order coefficient: ` varying vec3 texture_coordinate; uniform float curvature; void main() { vec4 v=gl_Vertex; v.z = curvature*(v.x*v.x+v.y*v.y)-curvature; texture_coordinate = vec3(((v.x+1.0)*0.5),((v.y+1.0)*0.5),-v.z); gl_Position = gl_ModelViewProjectionMatrix*v; }` – linello Jul 02 '13 at 14:43
  • `GL_CLAMP` is not a valid parameter in the `glTexParameteri` call. Did you mean to use `GL_CLAMP_TO_EDGE` or `GL_CLAMP_TO_BORDER`? – Yun Sep 30 '22 at 12:19

0 Answers0