Results 1 to 8 of 8

Thread: Floating point textures and Mipmapping

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    19

    Floating point textures and Mipmapping

    Hello,
    Bit of a simple question here. In general, is mipmapping supported for floating point textures on modern desktop hardware?

    Background:
    I am using a mipmapped texture in a reduction operation to gather the average/max/min scene luminance for tone mapping. I use the standard code for custom generation of mipmaps along with a custom downsampling shader.

    However, the operation fails on ATI hardware, with NaN's cropping up at random in the mipmapped texture. It also appears that my rendering to the texture levels doesn't work (I can't overwrite the NaN's).

    However, if I change the data type back to GL_RGBA the results are sensible but at an unusuble precision.

    The whole implementation works fine on NVidia hardware.

    If requested I can post code.

  2. #2
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,675

    Re: Floating point textures and Mipmapping

    I use the standard code for custom generation of mipmaps along with a custom downsampling shader.
    Which "standard code for custom generation of mipmaps?" Are you using the old GL_GENERATE_MIPMAPS tag, or `glGenerateMipmaps`?

    However, the operation fails on ATI hardware
    Which ATI hardware?

  3. #3
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    19

    Re: Floating point textures and Mipmapping

    The standard code I meant is usage example (5) of GL_EXT_FRAMEBUFFER_OBJECT. The code uses the OpenGL 3.3 core profile.

    Short story is that, on initialisation, I use glGenerateMipmaps to ensure the mipmap chain is available/allocated. Then when I actually want to generate the mipmaps I use rendering-to-texture to fill the next smallest mipmap layer, reading from the previous. I need to use a custom shader for this and not glGenerateMipmaps as I want to store the log avg, the min and the max of the original texture values.

    The AMD hardware I tested it on and had problems is the HD 6850. I confirmed the algorithm works on the Quadro 4000, the 560M and the GTX 260M. The platform is Linux (gentoo/ubuntu) and I'm using the latest binary drivers.

  4. #4
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,675

    Re: Floating point textures and Mipmapping

    There's no way to tell what's going on without actually seeing what you're doing. You're not saying that any attempt to have mipmapped float textures doesn't work. You're saying that something isn't working with the specific code you're running.

    We can't really do anything without seeing what your code is specifically doing. Not just a description of the algorithm, but the shaders themselves.

  5. #5
    Newbie OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,789

    Re: Floating point textures and Mipmapping

    If it's ATI it may be an instance of this: http://www.opengl.org/wiki/Common_Mi...map_generation

    Warning: It has been reported that on some ATI drivers, glGenerateMipmap(GL_TEXTURE_2D) has no effect unless you precede it with a call to glEnable(GL_TEXTURE_2D) in this particular case. Once again, to be clear, bind the texture, glEnable, then glGenerateMipmap. This is a bug and has been in the ATI drivers for a while. Perhaps by the time you read this, it will have been corrected. (glGenerateMipmap doesn't work on ATI as of 2011)

  6. #6
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    19

    Re: Floating point textures and Mipmapping

    Quote Originally Posted by mhagain
    If it's ATI it may be an instance of this: http://www.opengl.org/wiki/Common_Mi...map_generation
    Thanks for the heads up, I tried adding glEnable(GL_TEXTURE_2D); after my context was set up and it did not fix the problems I'm having.

    Quote Originally Posted by Alfonse Reinheart
    There's no way to tell what's going on without actually seeing what you're doing.
    I can appreciate that, but my question is more general than my code. Is mipmapping of floating point textures well supported on modern ATI hardware? This article on the wiki states that it is not available for x300 and above, but this article is quite old. I just want to know if the article is still correct.

    But I'm happy to share my code and I'll paste the relevant sections of it below, but with all of the boilerplate I don't think I can make a minimal example. Full sources are available here.

    Implementation
    I initialise the floating point buffer like so.
    Code :
    {
      std::tr1::shared_ptr<magnet::GL::Texture2D> 
        colorTexture(new magnet::GL::Texture2D);
     
      colorTexture->init(_camera.getWidth(), _camera.getHeight(), GL_RGB16F);
      colorTexture->parameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
      colorTexture->parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      colorTexture->genMipmaps(); //Ensure the mipmap chain is built/available for writing into
     
      _luminanceBuffer.init();
      _luminanceBuffer.attachTexture(colorTexture, 0);
    }

    I then fill it with luminance data using the following shader
    Code :
    void main()
    {
      vec4 color = texture(colorTex, screenCoord).rgba;
      float L = dot(color.rgb, vec3(0.265068,  0.67023428, 0.06409157));
      //Prevent negative logarithms
      L_out = vec4(log(max(10.0e-8, L)), L, L, 1.0);
    }

    I generate mipmaps using this code
    Code :
    //Now we need to generate the mipmaps containing the scene
    //average, minimum and maximum luminances
    magnet::GL::Texture2D&amp; tex = *_luminanceBuffer.getColorTexture();
    GLsizei currentWidth = tex.getWidth();
    GLsizei currentHeight = tex.getHeight();
    GLint numLevels = tex.calcMipmapLevels();
     
    //Ensure the luminance buffer is both attached and its color
    //texture bound
    _luminanceBuffer.attach();
    tex.bind(0);
     
    //Attach the mipmapping shader
    _luminanceMipMapShader.attach();
    _luminanceMipMapShader["inputTex"] = 0;
    for (int i=1; i < numLevels; ++i)
    	{
    	  GLsizei oldWidth = currentWidth;
    	  GLsizei oldHeight = currentHeight;
    	  //Halve the size of the textures, ensuring they never drop below 1
    	  currentWidth /= 2; currentWidth += !currentWidth;
    	  currentHeight /= 2; currentHeight += !currentHeight;
    	  _glContext->setViewport(0, 0, currentWidth, currentHeight);
     
    	  tex.parameter(GL_TEXTURE_BASE_LEVEL, i - 1);
    	  tex.parameter(GL_TEXTURE_MAX_LEVEL, i - 1);
    	  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
    				    tex.getGLType(), tex.getGLHandle(), i);
     
    	  //Now generate the mipmap level using a shader
    	  std::tr1::array<GLfloat, 2> oldInvDimensions = {{1.0 / oldWidth, 
    							   1.0 / oldHeight}};
    	  _luminanceMipMapShader["oldInvDimensions"] = oldInvDimensions;
    	  std::tr1::array<GLint,2> oldDimensions = {{oldWidth, oldHeight}};
    	  _luminanceMipMapShader["oldDimensions"] = oldDimensions;
    	  _luminanceMipMapShader.invoke();
    	}
     
    //Rebind mipmap 0 to the framebuffer
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
    				tex.getGLType(), tex.getGLHandle(), 0);
    _glContext->setViewport(0, 0, tex.getWidth(), tex.getHeight());
     
    tex.parameter(GL_TEXTURE_BASE_LEVEL, 0);
    tex.parameter(GL_TEXTURE_MAX_LEVEL, numLevels - 1);
    _luminanceMipMapShader.detach();
    _luminanceBuffer.detach();

    And this shader
    Code :
    layout (location = 0) out vec4 L_out;
    uniform sampler2D inputTex;
    uniform ivec2 oldDimensions;
    uniform vec2 oldInvDimensions;
    uniform float downscale = 2.0;
     
    vec3 data = vec3(0.0);
    float divider = 0.0;
     
    void combine(in vec4 sample)
    {
      //If this is the first sample, just copy the min max values.
      if (divider == 0)
        {
          data.r = 0.0;
          data.g = sample.g;
          data.b = sample.b;
        }
     
      //Store the value for averaging
      data.r += sample.r;
      divider += 1.0;
     
      //Store the maximum value
      data.g = max(sample.g, data.g);
     
      //Store the maximum value
      data.b = min(sample.b, data.b);
    }
     
    vec4 output_frag()
    {
      return vec4(data.r / divider, data.g, data.b, 1.0);
    }
     
    void main()
    {
      vec2 oldPixelOrigin = (downscale * gl_FragCoord.xy - vec2(0.5, 0.5)) * oldInvDimensions;
     
      combine(textureOffset(inputTex, oldPixelOrigin, ivec2(0,0)));
      combine(textureOffset(inputTex, oldPixelOrigin, ivec2(0,1)));
      combine(textureOffset(inputTex, oldPixelOrigin, ivec2(1,0)));
      combine(textureOffset(inputTex, oldPixelOrigin, ivec2(1,1)));
     
      //Now determine if we need to add extra samples in case of
      //non-power of two textures
      bool extraXSamples = (2 * (int(gl_FragCoord.x) + 1) == oldDimensions.x - 1);
      bool extraYSamples = (2 * (int(gl_FragCoord.y) + 1) == oldDimensions.y - 1);
     
      if (extraXSamples)
        {
          combine(textureOffset(inputTex, oldPixelOrigin, ivec2(2,0)));
          combine(textureOffset(inputTex, oldPixelOrigin, ivec2(2,1)));
        }
     
      if (extraYSamples)
        {
          combine(textureOffset(inputTex, oldPixelOrigin, ivec2(0,2)));
          combine(textureOffset(inputTex, oldPixelOrigin, ivec2(1,2)));
        }
     
      if (extraXSamples &amp;&amp; extraYSamples)
        combine(textureOffset(inputTex, oldPixelOrigin, ivec2(2,2)));
     
      L_out = output_frag();
    }

  7. #7
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,675

    Re: Floating point textures and Mipmapping

    This article on the wiki states that it is not available for x300 and above, but this article is quite old. I just want to know if the article is still correct.
    The page has been given an enema. Accurate information can now be found there.

    And yes, ATI hardware from the HD-era should be fine with floating-point mipmaps and filtering.

  8. #8
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    19

    Re: Floating point textures and Mipmapping

    Right, thanks for the updates to the wiki page and the clarification. I'll have to make a minimal example after all just to find out what I'm doing wrong.

Similar Threads

  1. Floating point texture extensions and mipmapping
    By bobdobbs in forum OpenGL: Advanced Coding
    Replies: 0
    Last Post: 12-04-2007, 12:46 AM
  2. Floating point textures and FBO
    By christl in forum OpenGL: Advanced Coding
    Replies: 5
    Last Post: 05-09-2006, 06:19 PM
  3. Floating point mipmapping performance
    By -NiCo- in forum OpenGL: Advanced Coding
    Replies: 4
    Last Post: 08-06-2004, 07:49 AM
  4. Floating Point textures in Cg
    By Zeross in forum OpenGL: GLSL
    Replies: 1
    Last Post: 05-20-2004, 08:58 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean