Hello all, hello Art :-)

I have been experimenting with osgPPU's HDR example, and it looks and works great for my purposes, and was even easy to integrate into my own app as a test. It's interesting how easy the code is to understand, given what it would have been without osgPPU (i.e. using OSG and all the render targets that the effect would have required).

I have one weird problem though. When looking around in my scene, at some camera angles the image stops updating and seems to just alternate between the two last rendered frames continuously. I still have control though, and if I rotate the camera again at one point it starts updating like normal again.

When the camera is positioned at different places, it takes different camera orientations for this to happen. But looking up towards the sky (+Z) always makes it happen. So it kind of looks like something is being culled in the scene graph which is causing this. I can't figure out what though, since I've looked through osgPPU's code and it looks to me that all the nodes (Units, Processor, etc.) have culling disabled (using setCullingActive(false) ).

I can't reproduce this in the osgPPU HDR example itself, of course. :-( So I'm not looking for a precise fix, but more some hints as to what to look for. I dumped the scene and the Processor to files, and can't see anything wrong - I've attached the ppu file for reference, but it's really just the one from the HDR example, minus the text PPUs.

Thanks in advance,

J-S
--
______________________________________________________
Jean-Sebastien Guay    [email protected]
                               http://www.cm-labs.com/
                        http://whitestar02.webhop.org/
osgPPU::Processor {
  osgPPU::UnitBypass {
    UniqueID UnitBypass_0
    name "HDRBypass"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInResampleOut_1
      PPU UnitInOut_2
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_3
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
  }
  osgPPU::UnitInResampleOut {
    UniqueID UnitInResampleOut_1
    name "Resample"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInOut_4
      PPU UnitInOut_5
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_6
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
    factorX 0.25
    factorY 0.25
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_4
    name "ComputePixelLuminance"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInMipmapOut_7
    }

    osgPPU::ShaderAttribute {
      name "LuminanceShader"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 1
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Compute luminance values of the input texture."
          " * So result will contain only luminance values per pixel."
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          "uniform sampler2D texUnit0;"
          ""
          ""
          "/**"
          " **/"
          "void main(void)"
          "{"
          "     // get color from the texture"
          "    // JSG: Mult by 2.0 since our scene is normally rendered in LDR 
so it "
          "    // didn't come out bright enough"
          "     vec4 texColor0 = texture2D(texUnit0, gl_TexCoord[0].st) * 2.0;"
          ""
          "     // compute luminance and output"
          "     gl_FragColor.xyz = vec3( texColor0.r * 0.2125 + texColor0.g * 
0.7154 + texColor0.b * 0.0721 );"
          "     gl_FragColor.a = texColor0.a;"
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "texUnit0"
          type sampler2D 1 IntArray 1
          {
            0 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_8
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  osgPPU::UnitInMipmapOut {
    UniqueID UnitInMipmapOut_7
    name "ComputeSceneLuminance"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInOut_5
      PPU UnitInOut_2
      PPU UnitInOut_9
    }

    osgPPU::ShaderAttribute {
      name "LuminanceShaderMipmap"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 1
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Compute logarithmic luminance for next mipmap level."
          " * see http://msdn2.microsoft.com/en-us/library/bb173484(VS.85).aspx"
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          "// just input texture from the previous stage"
          "uniform sampler2D texUnit0;"
          ""
          "// width of the input texture "
          "uniform float osgppu_ViewportWidth;"
          ""
          "// height of the input texture "
          "uniform float osgppu_ViewportHeight;"
          ""
          "// current mipmap level where we render the output"
          "uniform float osgppu_MipmapLevel;"
          ""
          "// number of mipmap levels available (needed for Shader Model 3.0 
hardware)"
          "uniform float osgppu_MipmapLevelNum;"
          ""
          ""
          "/**"
          " * Do compute current luminance value. If we are in the last mipmap 
level"
          " * then do compute the exponent and adapted luminance value."
          " **/"
          "void main(void)"
          "{"
          "    // just some variables"
          "    const float epsilon = 0.001;"
          "    float res = 0.0;"
          "    float c[4];"
          "    "
          "    // get texture sizes of the previous level"
          "    vec2 size = vec2(osgppu_ViewportWidth, osgppu_ViewportHeight) * 
2.0;"
          ""
          "    // this is our starting sampling coordinate "
          "    vec2 iCoord = gl_TexCoord[0].st;"
          ""
          "    // this represent the step size to sample the pixels from 
previous mipmap level"
          "    vec2 texel = vec2(1.0, 1.0) / (size);"
          "    vec2 halftexel = vec2(0.5, 0.5) / size;"
          ""
          "    // create offset for the texel sampling (TODO check why -1 seems 
to be correct)    "
          "    vec2 st[4];"
          "    st[0] = iCoord - halftexel + vec2(0,0);"
          "    st[1] = iCoord - halftexel + vec2(texel.x,0);"
          "    st[2] = iCoord - halftexel + vec2(0,texel.y);"
          "    st[3] = iCoord - halftexel + vec2(texel.x,texel.y);"
          "    "
          "    // retrieve 4 texels from the previous mipmap level"
          "    for (int i=0; i < 4; i++)"
          "    {"
          "        // map texels coordinates, such that they do stay in defined 
space"
          "        st[i] = clamp(st[i], vec2(0,0), vec2(1,1));"
          "        "
          "        // get texel from the previous mipmap level"
          "        //c[i] = texelFetch2D(texUnit0, ivec2(size * st[i]), 
(int)osgppu_MipmapLevel - 1).r;"
          "        // JSG: Mult by 2.0 since our scene is normally rendered in 
LDR so it "
          "        // didn't come out bright enough"
          "        c[i] = texture2D(texUnit0, st[i], osgppu_MipmapLevel - 
1.0).r * 2.0;"
          "    }"
          ""
          "    // if we compute the first mipmap level, then just compute the 
sum"
          "    // of the log values"
          "    if (abs(osgppu_MipmapLevel - 1.0) < 0.00001)"
          "    {"
          "        res += log(epsilon + c[0]);"
          "        res += log(epsilon + c[1]);"
          "        res += log(epsilon + c[2]);"
          "        res += log(epsilon + c[3]);"
          ""
          "    // for the rest we just compute the sum of underlying values"
          "    }else"
          "    {"
          "        res += c[0];"
          "        res += c[1];"
          "        res += c[2];"
          "        res += c[3];"
          "    }"
          ""
          "    // normalize result"
          "    res *= 0.25;"
          ""
          "    // if we are in the last mipmap level"
          "    if (osgppu_MipmapLevelNum - osgppu_MipmapLevel < 2.0)"
          "    {"
          "        // exponentiate"
          "        res = exp(res);"
          "    }"
          ""
          "    // result"
          "    gl_FragData[0].rgba = vec4( min(res, 65504.0) );"
          "    //gl_FragData[0].a = 1.0;"
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "texUnit0"
          type sampler2D 1 IntArray 1
          {
            0 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_10
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
    inputIndex 0
    useShader 1
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_5
    name "Brightpass"
    isActive 1
    inputTextureIndexForViewportReference 0

    InputToUniformMap {
      UnitInOut_9 texAdaptedLuminance
      UnitInResampleOut_1 hdrInput
      UnitInMipmapOut_7 lumInput
    }

    PPUOutput {
      PPU UnitInOut_11
    }

    osgPPU::ShaderAttribute {
      name "BrightpassShader"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 1
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Pass only values which are over a bright treshold."
          " * see http://msdn2.microsoft.com/en-us/library/bb173484(VS.85).aspx"
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          ""
          "// Original hdr input "
          "uniform sampler2D hdrInput;"
          ""
          "// Luminance input containing luminance values (mipmapped)"
          "uniform sampler2D lumInput;"
          ""
          "// input texture containing the adpted luminance"
          "uniform sampler2D texAdaptedLuminance;"
          ""
          "// this gives us middle gray value "
          "uniform float g_fMiddleGray;"
          ""
          "/**"
          " * Scale luminance value according to the settings"
          " * @param lum Current luminance value "
          " * @param avg Acerage luminance value"
          "**/"
          "float computeScaledLuminance(float avg, float lum)"
          "{"
          "    // compute scaled luminance"
          "    float scaledLum = lum * (g_fMiddleGray / (avg + 0.001));"
          "    "
          "    // clamp to fp16 value "
          "    scaledLum = min(scaledLum, 65504.0);"
          "    "
          "    // compute new luminance for the color"
          "    return scaledLum / (1.0 + scaledLum);    "
          "}"
          ""
          "/**"
          " * Perform passing of bright values. The bright values"
          " * will then be scaled according to the adapted luminance."
          " **/"
          "void main(void)"
          "{"
          "     const float BRIGHT_PASS_THRESHOLD = 0.9;"
          "     const float BRIGHT_PASS_OFFSET = 1.0;"
          "             "
          "     // get luminance and average (adapted) luminance value "
          "     float fLuminance = texture2D(lumInput, gl_TexCoord[0].st).r;"
          "     float fAdaptedLum = texture2D(texAdaptedLuminance, 
vec2(0.5,0.5)).w;"
          "    float fScaledLum = computeScaledLuminance(fAdaptedLum, 
fLuminance);"
          ""
          "    // get color of the pixel "
          "    // JSG: Mult by 2.0 since our scene is normally rendered in LDR 
so it "
          "    // didn't come out bright enough"
          "    vec3 vSample = texture2D(hdrInput, gl_TexCoord[0].st).rgb * 2.0;"
          ""
          "     // Determine what the pixel's value will be after tone mapping 
occurs"
          "    vSample *= fScaledLum;"
          "    //vSample.rgb *= g_fMiddleGray/(fScaledLum + 0.001);"
          "     "
          "     // Subtract out dark pixels"
          "     vSample -= BRIGHT_PASS_THRESHOLD;"
          "     "
          "     // Clamp to 0"
          "     vSample = max(vSample, vec3(0.0, 0.0, 0.0));"
          "     "
          "     // Map the resulting value into the 0 to 1 range. Higher values 
for"
          "     // BRIGHT_PASS_OFFSET will isolate lights from illuminated 
scene "
          "     // objects."
          "     vSample /= (BRIGHT_PASS_OFFSET + vSample);"
          ""
          "     // resulting color"
          "     gl_FragColor.rgb = vSample;"
          "    gl_FragColor.a = fAdaptedLum;"
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "g_fMiddleGray"
          type float 1 FloatArray 1
          {
            0.75 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_12
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_11
    name "BlurHorizontal"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInOut_13
    }

    osgPPU::ShaderAttribute {
      name "BlurHorizontalShader"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 2
      Shader {
        UniqueID Shader_14
        type VERTEX
        code {
          ""
          "/*"
          " * Reimplement fixed function pipeline of OpenGL"
          " * So bypass all the data."
          " * Precompute some constants which are needed for the convolution 
computation"
          " */"
          ""
          "//! Sigma value for the gaussian kernel"
          "uniform float sigma;"
          ""
          "const float PI = 3.1415926535897;"
          ""
          "// Varyings"
          "varying float sigma2;"
          "varying float c;"
          ""
          "/**"
          " * Reimplement fixed pipeline"
          " **/"
          "void main(void)"
          "{"
          "     // bypass the texture coordinate data"
          "     gl_TexCoord[0] = gl_MultiTexCoord0;"
          "     "
          "     // compute position of the pixel "
          "     gl_Position = ftransform();"
          "     "
          "     // bypass color data"
          "     gl_FrontColor = gl_Color;"
          "     "
          "     // precompute constants"
          "     sigma2 = 2.0 * sigma * sigma;"
          "     c = sqrt((1.0 / (sigma2 * PI)));"
          "}"
          ""
        }
      }
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Apply convolution of variable size onto the pixels."
          " * The convolution is done in 1D"
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          "uniform sampler2D texUnit0;"
          ""
          "//! Size of the gaussian kernel (size = radius * 2)"
          "uniform float radius;"
          ""
          "//! Sigam value for the gaussian kernel"
          "uniform float sigma;"
          ""
          "// Varyings"
          "varying float sigma2;"
          "varying float c;"
          ""
          "// width of the input texture "
          "uniform float osgppu_ViewportWidth;"
          ""
          "// height of the input texture "
          "uniform float osgppu_ViewportHeight;"
          ""
          "/**"
          " **/"
          "void main(void)"
          "{"
          "     // store here resulting color"
          "     vec4 color = vec4(0.0);"
          "     float totalWeigth = 0.0;"
          "     float inputTexTexelWidth = 1.0 / osgppu_ViewportWidth;"
          "     "
          "     // convolve by applying nsamples-time the texture lookup"
          "     for (float i=-radius; i < radius; i += 1.0) "
          "     {"
          "             // compute weight for the pixel "
          "             float weight = c * exp((i*i) / (-sigma2));"
          "             totalWeigth += weight;"
          "             "
          "             // combine now the sum as all values multiplied by the 
weight"
          "             color += texture2D(texUnit0, gl_TexCoord[0].xy +  
vec2(i * inputTexTexelWidth, 0) ) * weight;"
          "     }"
          "     color /= totalWeigth;"
          "     "
          "     gl_FragColor = color;"
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "radius"
          type float 1 FloatArray 1
          {
            7 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "sigma"
          type float 1 FloatArray 1
          {
            4 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "texUnit0"
          type sampler2D 1 IntArray 1
          {
            0 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_15
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_13
    name "BlurVertical"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInOut_2
    }

    osgPPU::ShaderAttribute {
      name "BlurVerticalShader"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 2
      Use Shader_14
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Apply convolution of variable size onto the pixels."
          " * The convolution is done in 1D"
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          "uniform sampler2D texUnit0;"
          ""
          "//! Size of the gaussian kernel (size = radius * 2)"
          "uniform float radius;"
          ""
          "//! Sigam value for the gaussian kernel"
          "uniform float sigma;"
          ""
          "// Varyings"
          "varying float sigma2;"
          "varying float c;"
          ""
          "// width of the input texture "
          "uniform float osgppu_ViewportWidth;"
          ""
          "// height of the input texture "
          "uniform float osgppu_ViewportHeight;"
          ""
          "/**"
          " **/"
          "void main(void)"
          "{"
          ""
          "     // store here resulting color"
          "     vec4 color = vec4(0.0);"
          "     float totalWeigth = 0.0;"
          "     float inputTexTexelWidth = 1.0 / osgppu_ViewportHeight;"
          ""
          "     // convolve by applying nsamples-time the texture lookup"
          "     for (float i=-radius; i < radius; i += 1.0) "
          "     {"
          "             // compute weight for the pixel "
          "             float weight = c * exp((i*i) / (-sigma2));"
          "             totalWeigth += weight;"
          "             "
          "             // combine now the sum as all values multiplied by the 
weight"
          "             color += texture2D(texUnit0, gl_TexCoord[0].xy +  
vec2(0, i * inputTexTexelWidth) ) * weight;"
          "     }"
          "     color /= totalWeigth;"
          "     "
          "     gl_FragColor = color;"
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "radius"
          type float 1 FloatArray 1
          {
            7 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "sigma"
          type float 1 FloatArray 1
          {
            4 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "texUnit0"
          type sampler2D 1 IntArray 1
          {
            0 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_16
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_2
    name "HDR-Result"
    isActive 1
    inputTextureIndexForViewportReference 0

    InputToUniformMap {
      UnitInOut_13 blurInput
      UnitInOut_9 texAdaptedLuminance
      UnitBypass_0 hdrInput
      UnitInMipmapOut_7 lumInput
    }

    PPUOutput {
      PPU UnitOut_17
    }

    osgPPU::ShaderAttribute {
      name "HDRResultShader"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 1
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Combine input texture with a given hdr texture by applying"
          " * tonemapping algorithm found in"
          " * 
http://www.mpi-inf.mpg.de/resources/hdr/peffects/krawczyk05sccg.pdf";
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          "// blurred texture of the brightpassed data"
          "uniform sampler2D blurInput;"
          ""
          "// hdr texture containing the scene"
          "uniform sampler2D hdrInput;"
          ""
          "// Luminance input "
          "uniform sampler2D lumInput;"
          ""
          "// input texture containing the adpted luminance"
          "uniform sampler2D texAdaptedLuminance;"
          ""
          "// how much to use blurred "
          "uniform float fBlurFactor;"
          ""
          "// this gives us middle gray value "
          "uniform float g_fMiddleGray;"
          ""
          ""
          "/**"
          " * Scale luminance value according to the settings"
          " * @param lum Current luminance value "
          " * @param avg Acerage luminance value"
          "**/"
          "float computeScaledLuminance(float avg, float lum)"
          "{"
          "    // compute scaled luminance"
          "    float scaledLum = lum * (g_fMiddleGray / (avg + 0.001));"
          "    "
          "    // clamp to fp16 value "
          "    scaledLum = min(scaledLum, 65504.0);"
          "    "
          "    // compute new luminance for the color"
          "    return scaledLum / (1.0 + scaledLum);    "
          "}"
          ""
          ""
          "/**"
          " **/"
          "void main(void)"
          "{"
          "     vec2 inTex = gl_TexCoord[0].st;"
          "     "
          "     // get color from the texture blurred texture"
          "     vec4 blurColor = texture2D(blurInput, inTex);"
          "     "
          "     // get color from the input texture "
          "    // JSG: Mult by 2.0 since our scene is normally rendered in LDR 
so it "
          "    // didn't come out bright enough"
          "     vec4 hdrColor = texture2D(hdrInput, inTex) * 2.0;"
          ""
          "     // get adapted, normal and scaled luminance"
          "    float fLuminance = texture2D(lumInput, inTex).r;"
          "     float fAdaptedLum = texture2D(texAdaptedLuminance, 
vec2(0.5,0.5)).w;"
          "    float fScaledLum = computeScaledLuminance(fAdaptedLum, 
fLuminance);"
          ""
          "     // resulting color is the hdr color multiplied by the scaled 
luminance"
          "     vec4 color = hdrColor * fScaledLum;"
          ""
          "     // gamma correction"
          "     gl_FragColor.rgb = blurColor.rgb * fBlurFactor + color.rgb;"
          "    gl_FragColor.a = hdrColor.a;   "
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "fBlurFactor"
          type float 1 FloatArray 1
          {
            2.5 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "g_fMiddleGray"
          type float 1 FloatArray 1
          {
            0.75 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_18
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  osgPPU::UnitOut {
    UniqueID UnitOut_17
    name "PipelineResult"
    isActive 1
    inputTextureIndexForViewportReference -1

    PPUOutput {
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_19
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_9
    name "AdaptedLuminance"
    isActive 1
    inputTextureIndexForViewportReference -1

    PPUOutput {
      PPU UnitInOut_20
      PPU UnitInOut_5
      PPU UnitInOut_2
    }

    Viewport {
      UniqueID Viewport_21
      x 0
      y 0
      width 1
      height 1
    }

    osgPPU::ShaderAttribute {
      name "AdaptLuminanceShader"
      GeometryVerticesOut 1
      GeometryInputType TRIANGLES
      GeometryOutputType TRIANGLE_STRIP
      num_shaders 1
      Shader {
        type FRAGMENT
        code {
          "/*"
          " * Compute adapted luminance based on the data from the previous 
frames."
          " * see http://msdn2.microsoft.com/en-us/library/bb173484(VS.85).aspx"
          " */"
          ""
          "// -------------------------------------------------------"
          "// Texture units used for texturing"
          "// -------------------------------------------------------"
          "// input texture containing the average luminance"
          "uniform sampler2D texLuminance;"
          ""
          "// input texture containing the current adapted luminance"
          "uniform sampler2D texAdaptedLuminance;"
          ""
          "// max and min possible luminance"
          "uniform float maxLuminance;"
          "uniform float minLuminance;"
          ""
          "// time interval between two frames"
          "uniform float invFrameTime;"
          ""
          "// scaling factor which decides how fast to adapt for new luminance"
          "uniform float adaptScaleFactor;"
          ""
          "const float TauCone = 0.01;"
          "const float TauRod = 0.04;"
          ""
          "/**"
          " * Compute adapted luminance value."
          " * @param current Is the current luminance value "
          " * @param old Adapted luminance value from the previous frame"
          " **/"
          "void main(void)"
          "{"
          "    // get current luminance, this one is stored in the last mipmap 
level"
          "    float current = texture2D(texLuminance, vec2(0.5,0.5), 100.0).x;"
          "    "
          "    // get old adapted luminance value"
          "    float old = texture2D(texAdaptedLuminance, vec2(0.5,0.5)).w;"
          ""
          "    //determin if rods or cones are active"
          "    //Perceptual Effects in Real-time Tone Mapping: Equ(7)    "
          "    float sigma = clamp(0.4/(0.04+current),0.0,1.0);"
          ""
          "    //interpolate tau from taurod and taucone depending on lum"
          "    //Perceptual Effects in Real-time Tone Mapping: Equ(12)"
          "    float Tau = mix(TauCone,TauRod,sigma) / adaptScaleFactor;"
          ""
          "    // compute new adapted value"
          "    //float lum = old + (current - old) * (1.0 - pow(0.98, 
adaptScaleFactor * invFrameTime));"
          ""
          "    // clamp and return back"
          "    //gl_FragData[0].xyzw = lum;//clamp(lum, minLuminance, 
maxLuminance);"
          "    //gl_FragData[0].a = 1.0;"
          ""
          ""
          ""
          ""
          ""
          "    //calculate adaption"
          "    //Perceptual Effects in Real-time Tone Mapping: Equ(5)"
          "    float lum  = old + (current - old) * (1.0 - 
exp(-(invFrameTime)/Tau));"
          "    //gl_FragData[0].x = current;"
          "    //gl_FragData[0].y = old;"
          "    //gl_FragData[0].z = (1.0 - exp(-(invFrameTime)/Tau));"
          "    gl_FragData[0].xyzw = vec4( clamp(lum, minLuminance, 
maxLuminance) );"
          "}"
        }
      }
      maximalSupportedTextureUnits 8
      RefUniformPair {
        Uniform {
          name "adaptScaleFactor"
          type float 1 FloatArray 1
          {
            0.025 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "maxLuminance"
          type float 1 FloatArray 1
          {
            5 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "minLuminance"
          type float 1 FloatArray 1
          {
            0.2 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "texAdaptedLuminance"
          type sampler2D 1 IntArray 1
          {
            1 
          }
        }
        StateAttribute ON
      }
      RefUniformPair {
        Uniform {
          name "texLuminance"
          type sampler2D 1 IntArray 1
          {
            0 
          }
        }
        StateAttribute ON
      }
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_22
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  osgPPU::UnitInOut {
    UniqueID UnitInOut_20
    name "AdaptedLuminanceCopy"
    isActive 1
    inputTextureIndexForViewportReference 0

    PPUOutput {
      PPU UnitInOut_9
    }

    osgPPU::ColorAttribute {
      UniqueID ColorAttribute_23
      UpdateCallback {
      }
      startTime 0
      endTime 0
      startColor 1 1 1 1
      endColor 1 1 1 1
    }
    inputBypass -1
    outputInternalFormat GL_RGBA16F_ARB
    outputTextureType TEXTURE_2D
    outputFace 0
    outputDepth 1
  }
  name Processor
  PPUOutput {
    PPU UnitBypass_0
  }
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to