Screen-space ambient occlusion for volume rendering

As I probably won’t have time to go further before tonight, and can’t wait to see if this performs well on your side. Here is a quick way to try it:

  1. VTK changes required: This commit from the volume-ssao branch
  2. The following shader replacement on the mapper:
  volume->GetProperty()->ShadeOn();

  volume->GetShaderProperty()->AddFragmentShaderReplacement("//VTK::ComputeLighting::Dec", true,
    "vec3 g_dataNormal; \n"\
    "//VTK::ComputeLighting::Dec\n",
    false);
  volume->GetShaderProperty()->AddFragmentShaderReplacement("//VTK::RenderToImage::Dec", true,
    "vec3 l_opaqueFragNormal;\n"
    "vec3 l_opaqueFragPos;\n"
    "bool l_updateDepth;\n",
    false);

  volume->GetShaderProperty()->AddFragmentShaderReplacement("//VTK::RenderToImage::Init", true,
    "\
    \n  l_opaqueFragPos = vec3(-1.0);\
    \n  l_updateDepth = true;",
    false);

  volume->GetShaderProperty()->AddFragmentShaderReplacement("//VTK::RenderToImage::Impl", true,
    "\
    \n    if(!g_skip && g_srcColor.a > 0.0 && l_updateDepth)\
    \n      {\
    \n      l_opaqueFragPos = g_dataPos;\
    \n      l_opaqueFragNormal = g_dataNormal;\
    \n      l_updateDepth = false;\
    \n      }",
    false);


  volume->GetShaderProperty()->AddFragmentShaderReplacement("//VTK::RenderToImage::Exit", true,
    "\
    \n  if (l_opaqueFragPos == vec3(-1.0))\
    \n    {\
\n gl_FragDepth = 1.0; \
\n gl_FragData[1] = gl_FragData[1]; \
    \n    }\
    \n  else\
    \n    {\
    \n    vec4 depthValue = in_projectionMatrix * in_modelViewMatrix *\
    \n                      in_volumeMatrix[0] * in_textureDatasetMatrix[0] *\
    \n                      vec4(l_opaqueFragPos, 1.0);\
    \n    depthValue /= depthValue.w;\
    \n    gl_FragDepth = 0.5 * (gl_DepthRange.far - gl_DepthRange.near) * depthValue.z + 0.5 * (gl_DepthRange.far + gl_DepthRange.near);\
    \n    gl_FragData[1] = in_modelViewMatrix * in_volumeMatrix[0] * in_textureDatasetMatrix[0] * vec4(l_opaqueFragPos, 1.0);\
    \n    gl_FragData[2] = vec4(l_opaqueFragNormal, 0.0);\
    \n    }",
    false);

Important:
Shading must be turned ON otherwise the shader fails to compile. Other non-default options have not been tested.
The VTK commit above works around a problem with FBOs when the SSAO pass is activated, by commenting the depth buffer blit that is required for surfaces to occlude the volume. This should be fixed later.

1 Like