VTK/Depth Peeling: Difference between revisions
(35 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
= Definition = | = Definition = | ||
Depth peeling is a multipass technique to render translucent polygonal geometry without sorting polygons. | Depth peeling is a multipass technique to render translucent polygonal geometry without sorting polygons. | ||
The algorithm peels the translucent geometry from front to back until there is no more geometry to render. The iteration loop stops either if it reaches the maximum number of iterations set by the user or if the number of pixels modified by the last peel is less than some ratio of the area of the window (this ratio is set by the user, if the ratio is set to 0.0, it means the user wants | |||
the exact result. A ratio of 0.2 will render faster than a ratio of 0.1). | |||
= Date of Implementation = | |||
* November 27th 2006: added to VTK. | |||
* January 9th 2007: added texturing. | |||
* March 5th 2007: Improvement with volumetric dataset and polygonal translucent geometry. | |||
* April 28th 2007: Improvement of OpenGL extensions check to cover more configurations. | |||
* October 27th 2007: Fixed bug with ImageActor (used by TextActor3D), fixed bug with translucent vtkLookupTable. In general, fixed compositing in VTK (premultiplied alpha) | |||
* January 25th 2008: Fixed bug with stereo rendering in crystal eyes mode. | |||
* Implemented by (any question to) François Bertel. | |||
= Pros = | = Pros = | ||
Line 10: | Line 23: | ||
* The algorithm is inherently slow due to rendering the geometry multiple times. | * The algorithm is inherently slow due to rendering the geometry multiple times. | ||
* The implementation based on OpenGL API requires a couple of extensions, restricting its usage to recent GPU. | * The implementation based on OpenGL API requires a couple of extensions, restricting its usage to recent GPU. It works fine with the current CVS version of Mesa (2006/12/01) | ||
= Usage = | = Usage = | ||
== Required OpenGL extensions == | == Required OpenGL extensions == | ||
Check [[VTK FAQ#How_do_I_check_which_OpenGL_versions_or_extensions_are_supported_by_my_graphic_card_or_OpenGL_implementation.3F|here]] if your OpenGL implementation supports the following extensions: | |||
* <tt>GL_ARB_depth_texture</tt> | * <tt>GL_ARB_depth_texture</tt> or OpenGL>=1.4 | ||
* <tt>GL_ARB_shadow</tt> | * <tt>GL_ARB_shadow</tt> or OpenGL>=1.4 | ||
* <tt>GL_EXT_shadow_funcs</tt> | * <tt>GL_EXT_shadow_funcs</tt> or OpenGL>=1.5 | ||
* <tt>GL_ARB_vertex_shader</tt> | * <tt>GL_ARB_vertex_shader</tt> or OpenGL>=2.0 | ||
* <tt>GL_ARB_fragment_shader</tt> | * <tt>GL_ARB_fragment_shader</tt> or OpenGL>=2.0 | ||
* <tt>GL_ARB_shader_objects</tt> | * <tt>GL_ARB_shader_objects</tt> or OpenGL>=2.0 | ||
* <tt>GL_ARB_occlusion_query</tt> | * <tt>GL_ARB_occlusion_query</tt> or OpenGL>=1.5 | ||
* <tt>GL_ARB_multitexture</tt> | * <tt>GL_ARB_multitexture</tt> or OpenGL>=1.3 | ||
* <tt>GL_ARB_texture_rectangle</tt> | * <tt>GL_ARB_texture_rectangle</tt> | ||
* <tt>GL_SGIS_texture_edge_clamp</tt> or <tt>GL_EXT_texture_edge_clamp</tt> or OpenGL 1.2 | * <tt>GL_SGIS_texture_edge_clamp</tt> or <tt>GL_EXT_texture_edge_clamp</tt> or OpenGL>=1.2 | ||
== OpenGL context requirement == | == OpenGL context requirement == | ||
* at least 8 alpha bits (by default vtkRenderWindow does not ask for alpha bit planes, make sure to call <tt>vtkRenderWindow::SetAlphaBitPlanes(1)</tt>) | * at least 8 alpha bits (by default vtkRenderWindow does not ask for alpha bit planes, make sure to call <tt>vtkRenderWindow::SetAlphaBitPlanes(1)</tt>) | ||
Rational: the algorithm has two main stages: first it renders peels from front to back in the framebuffer. each peel is saved in a 2D RGBA texture by grabbing the contents of the framebuffer. So the framebuffer is <b>required</b> to have an alpha channel in order to save it into an RGBA texture. The second part is doing compositing from back to front into the framebuffer by drawing quads on which each peel texture is applied. The compositing stage is drawing into the framebuffer but does not require alpha channel on it (the blending function used at this stage only use the alpha channel from the textures). | |||
== Linux Nvidia driver == | |||
Make sure to install a driver newer than 9500. For older drivers, there is a bug with <tt>GL_ARB_texture_rectangle</tt> and GLSL that prevents to use GLSL for depth peeling. | |||
http://www.gpgpu.org/forums/viewtopic.php?p=11843&sid=9069e02401e2acf53dedf61349fc8431 . In order to use rectangle textures in GLSL, we are supposed to used <tt>sampler2DRectShadow</tt> in the | |||
shader and starts the shader source code with "<tt>#extension GL_ARB_texture_rectangle: enable</tt>". But with a driver like 8776, it returns: | |||
warning C7508: extension GL_ARB_texture_rectangle not supported | |||
== VTK calls == | == VTK calls == | ||
Line 36: | Line 60: | ||
* 1. Use a render window with alpha bits (as initial value is 0 (false) ): | * 1. Use a render window with alpha bits (as initial value is 0 (false) ): | ||
renderWindow->SetAlphaBitPlanes(1) | renderWindow->SetAlphaBitPlanes(1); | ||
* 2. | * 2. Force to not pick a framebuffer with a multisample buffer ( as initial value is 8): | ||
* | renderWindow->SetMultiSamples(0); | ||
** | * 3. Choose to use depth peeling (if supported) (initial value is 0 (false) ) | ||
renderer->SetUseDepthPeeling(1); | |||
* | * 4. Set depth peeling parameters. | ||
* | ** Set the maximum number of rendering passes (initial value is 4) | ||
renderer->SetMaximumNumberOfPeels(100); | |||
** Set the occlusion ratio (initial value is <tt>0.0</tt>, exact image) | |||
renderer->SetOcclusionRatio(0.1); | |||
* 5. Render | |||
* 6. Check if depth peeling was actually used: | |||
int depthPeelingWasUsed=renderer->GetLastRenderingUsedDepthPeeling(); | |||
== Driver bugs and workarounds == | |||
=== Linux Nvidia driver === | |||
Make sure to install a driver newer than 9500. For older drivers, there is a bug with <tt>GL_ARB_texture_rectangle</tt> and GLSL that prevents to use GLSL for depth peeling. | |||
http://www.gpgpu.org/forums/viewtopic.php?p=11843&sid=9069e02401e2acf53dedf61349fc8431 . In order to use rectangle textures in GLSL, we are supposed to used <tt>sampler2DRectShadow</tt> in the | |||
shader and starts the shader source code with "<tt>#extension GL_ARB_texture_rectangle: enable</tt>". But with a driver like 8776, it returns: | |||
warning C7508: extension GL_ARB_texture_rectangle not supported | |||
= Implementation notes = | = Implementation notes = | ||
Line 51: | Line 93: | ||
<pre> | <pre> | ||
vtkOpenGLActor.cxx | vtkOpenGLActor.cxx | ||
vtkOpenGLProperty.cxx | |||
vtkOpenGLRenderer.cxx | vtkOpenGLRenderer.cxx | ||
vtkOpenGLRenderer.h | vtkOpenGLRenderer.h | ||
vtkOpenGLTexture.cxx | |||
vtkRenderer.cxx | vtkRenderer.cxx | ||
vtkRenderer.h | vtkRenderer.h | ||
Testing/Cxx/CMakeLists.txt | Testing/Cxx/CMakeLists.txt | ||
Testing/Cxx/TestOpacity.cxx | Testing/Cxx/TestOpacity.cxx | ||
Testing/Tcl/CMakeLists.txt | |||
Testing/Tcl/TestOpacity2.tcl | |||
</pre> | </pre> | ||
== VTK changes == | == VTK changes == | ||
Before the changes, Render of vtkRenderer used to iterate over all props and call RenderTranslucentGeometry on each of them. Now, it calls a virtual method <tt>DeviceRenderTranslucentGeometry()</tt>. By default this method call <tt>UpdateTranslucentGeometry()</tt>. And <tt>UpdateTranslucentGeometry()</tt> do exactly what <tt>Render()</tt> used to do. | Before the changes, <tt>Render()</tt> of <tt>vtkRenderer</tt> used to iterate over all props and call <tt>RenderTranslucentGeometry</tt> on each of them. Now, it calls a virtual method <tt>DeviceRenderTranslucentGeometry()</tt>. By default this method call <tt>UpdateTranslucentGeometry()</tt>. And <tt>UpdateTranslucentGeometry()</tt> do exactly what <tt>Render()</tt> used to do. | ||
In <tt>vtkOpenGLRenderer</tt>, <tt>DeviceRenderTranslucentGeometry()</tt> is overridden to use depth peeling flags and implement depth peeling technique. For each peel it will call <tt>UpdateTranslucentGeometry()</tt>. | In <tt>vtkOpenGLRenderer</tt>, <tt>DeviceRenderTranslucentGeometry()</tt> is overridden to use depth peeling flags and implement depth peeling technique. For each peel it will call <tt>UpdateTranslucentGeometry()</tt>. | ||
It uses a lot of GPU RAM because each rgba buffer of each peel have to be saved. The last step | It uses a lot of GPU RAM because each rgba buffer of each peel have to be saved. The last step perfoms compositing with each layer, back-to-front order ( if it was possible to do front-to-back compositing, we | ||
could perform compositing on the fly and we would not need to store each peel.) Compositing is done by rendering each layer as a texture on a quad. | could perform compositing on the fly and we would not need to store each peel.) Compositing is done by rendering each layer as a texture on a quad. | ||
As we first render opaque geometry, we use it to cull transparent geometry, limiting the number of required layers. | As we first render opaque geometry, we use it to cull transparent geometry, limiting the number of required layers. | ||
= Comments on references = | |||
* The original depth peeling algorithm is described in [1]. | |||
* [2] first render opaque geometry and use depth peeling only for none-opaque geometry which can reduce drastically the number of depth peeling passes. | |||
* To stop the iteration, follow [2], page 9, section 4. Transparency: "an occlusion query test on each pass indicates whether that layer was empty; if it was, the algorithm halts.". This kind of query is possible with openGL with BeginQuery/EndQuery (section 4.1.7 Occlusion Queries in page 207/221 spec 2.1). This is part of core OpenGL 1.5, promoted from extension <tt>GL_ARB_occlusion_query</tt> http://www.opengl.org/registry/specs/ARB/occlusion_query.txt. | |||
* More on query: as the extension can count the number of pixels that changed, the stop condition can be a percentage of the screen size instead of a complete unmodified screen ([5]) | |||
* GLSL and Nvidia specific notes about shadow textures: [8] | |||
= References = | = References = | ||
* [1] Interactive Order-Independent Transparency Cass Everitt NVIDIA (technical paper 05/15/2001 developer.nvidia.com/attach/6545 and slides developer.nvidia.com/attach/6402) | * [1] Interactive Order-Independent Transparency Cass Everitt NVIDIA (technical paper 05/15/2001 http://developer.nvidia.com/attach/6545 and slides http://developer.nvidia.com/attach/6402) | ||
* [2] GPU-Accelerated High-Quality Hidden Surface Removal Daniel Wexler, Larry Gritz, Eric Enderton, Jonathan Rice, Graphics Hardware 2005, 30-31 July 2005, Los Angeles CA, ACM | * [2] GPU-Accelerated High-Quality Hidden Surface Removal Daniel Wexler, Larry Gritz, Eric Enderton, Jonathan Rice, Graphics Hardware 2005, 30-31 July 2005, Los Angeles CA, ACM | ||
* [3] GPU-based Tiled Ray Casting using Depth Peeling Fábio F. Bernardon Christian A. Pagot João L. Comba Cládio T. Silva www.inf.ufrgs.br/~comba/papers/2006/gpu_volume_ray_casting.pdf | * [3] GPU-based Tiled Ray Casting using Depth Peeling Fábio F. Bernardon Christian A. Pagot João L. Comba Cládio T. Silva http://www.inf.ufrgs.br/~comba/papers/2006/gpu_volume_ray_casting.pdf | ||
* [4] GPU-based Transparent Polygonal Geometry in Volume Rendering home.dataparty.no/kristian/school/ntnu/masterthesis/embedded-geometry-paper.pdf (extension 297 GL_EXT_depth_bounds_test www.opengl.org/registry/specs/EXT/depth_bounds_test.txt) | * [4] GPU-based Transparent Polygonal Geometry in Volume Rendering http://home.dataparty.no/kristian/school/ntnu/masterthesis/embedded-geometry-paper.pdf (extension 297 GL_EXT_depth_bounds_test http://www.opengl.org/registry/specs/EXT/depth_bounds_test.txt) | ||
* [5] Occlusion slides from Nvidia at Game Developer Conference 2002: developer.nvidia.com/attach/6715 | * [5] Occlusion slides from Nvidia at Game Developer Conference 2002: http://developer.nvidia.com/attach/6715 | ||
* [6] Thomas Porter and Tom Duff, "Compositing Digital Images", Computer Graphics, Volume 18, Number 3, July 1984 (ACM Siggraph). Pretty good reference about compositing/alpha arithmetic. | * [6] Thomas Porter and Tom Duff, "Compositing Digital Images", Computer Graphics, Volume 18, Number 3, July 1984 (ACM Siggraph). Pretty good reference about compositing/alpha arithmetic. | ||
* [7] Multi-Layer Depth Peeling via Fragment Sort research.microsoft.com/research/pubs/view.aspx?tr_id=1125 | * [7] Multi-Layer Depth Peeling via Fragment Sort http://research.microsoft.com/research/pubs/view.aspx?tr_id=1125 | ||
* [8] Release Notes for NVIDIA OpenGL Shading Language Support download.nvidia.com/developer/GLSL/GLSL%20Release%20Notes%20for%20Release%2060.pdf (from developer.nvidia.com/object/nvemulate.html ) | * [8] Release Notes for NVIDIA OpenGL Shading Language Support http://download.nvidia.com/developer/GLSL/GLSL%20Release%20Notes%20for%20Release%2060.pdf (from http://developer.nvidia.com/object/nvemulate.html ) | ||
= Glossary = | |||
*OIT: Order Independent Transparency | |||
*MRT: Multiple Rendering Targets | |||
{{VTK/Template/Footer}} |
Latest revision as of 14:58, 10 March 2010
Definition
Depth peeling is a multipass technique to render translucent polygonal geometry without sorting polygons.
The algorithm peels the translucent geometry from front to back until there is no more geometry to render. The iteration loop stops either if it reaches the maximum number of iterations set by the user or if the number of pixels modified by the last peel is less than some ratio of the area of the window (this ratio is set by the user, if the ratio is set to 0.0, it means the user wants the exact result. A ratio of 0.2 will render faster than a ratio of 0.1).
Date of Implementation
- November 27th 2006: added to VTK.
- January 9th 2007: added texturing.
- March 5th 2007: Improvement with volumetric dataset and polygonal translucent geometry.
- April 28th 2007: Improvement of OpenGL extensions check to cover more configurations.
- October 27th 2007: Fixed bug with ImageActor (used by TextActor3D), fixed bug with translucent vtkLookupTable. In general, fixed compositing in VTK (premultiplied alpha)
- January 25th 2008: Fixed bug with stereo rendering in crystal eyes mode.
- Implemented by (any question to) François Bertel.
Pros
- Translucent geometry does not have to be sorted.
Cons
- The algorithm is inherently slow due to rendering the geometry multiple times.
- The implementation based on OpenGL API requires a couple of extensions, restricting its usage to recent GPU. It works fine with the current CVS version of Mesa (2006/12/01)
Usage
Required OpenGL extensions
Check here if your OpenGL implementation supports the following extensions:
- GL_ARB_depth_texture or OpenGL>=1.4
- GL_ARB_shadow or OpenGL>=1.4
- GL_EXT_shadow_funcs or OpenGL>=1.5
- GL_ARB_vertex_shader or OpenGL>=2.0
- GL_ARB_fragment_shader or OpenGL>=2.0
- GL_ARB_shader_objects or OpenGL>=2.0
- GL_ARB_occlusion_query or OpenGL>=1.5
- GL_ARB_multitexture or OpenGL>=1.3
- GL_ARB_texture_rectangle
- GL_SGIS_texture_edge_clamp or GL_EXT_texture_edge_clamp or OpenGL>=1.2
OpenGL context requirement
- at least 8 alpha bits (by default vtkRenderWindow does not ask for alpha bit planes, make sure to call vtkRenderWindow::SetAlphaBitPlanes(1))
Rational: the algorithm has two main stages: first it renders peels from front to back in the framebuffer. each peel is saved in a 2D RGBA texture by grabbing the contents of the framebuffer. So the framebuffer is required to have an alpha channel in order to save it into an RGBA texture. The second part is doing compositing from back to front into the framebuffer by drawing quads on which each peel texture is applied. The compositing stage is drawing into the framebuffer but does not require alpha channel on it (the blending function used at this stage only use the alpha channel from the textures).
Linux Nvidia driver
Make sure to install a driver newer than 9500. For older drivers, there is a bug with GL_ARB_texture_rectangle and GLSL that prevents to use GLSL for depth peeling.
http://www.gpgpu.org/forums/viewtopic.php?p=11843&sid=9069e02401e2acf53dedf61349fc8431 . In order to use rectangle textures in GLSL, we are supposed to used sampler2DRectShadow in the shader and starts the shader source code with "#extension GL_ARB_texture_rectangle: enable". But with a driver like 8776, it returns:
warning C7508: extension GL_ARB_texture_rectangle not supported
VTK calls
The interface is in vtkRenderer.
- 1. Use a render window with alpha bits (as initial value is 0 (false) ):
renderWindow->SetAlphaBitPlanes(1);
- 2. Force to not pick a framebuffer with a multisample buffer ( as initial value is 8):
renderWindow->SetMultiSamples(0);
- 3. Choose to use depth peeling (if supported) (initial value is 0 (false) )
renderer->SetUseDepthPeeling(1);
- 4. Set depth peeling parameters.
- Set the maximum number of rendering passes (initial value is 4)
renderer->SetMaximumNumberOfPeels(100);
- Set the occlusion ratio (initial value is 0.0, exact image)
renderer->SetOcclusionRatio(0.1);
- 5. Render
- 6. Check if depth peeling was actually used:
int depthPeelingWasUsed=renderer->GetLastRenderingUsedDepthPeeling();
Driver bugs and workarounds
Linux Nvidia driver
Make sure to install a driver newer than 9500. For older drivers, there is a bug with GL_ARB_texture_rectangle and GLSL that prevents to use GLSL for depth peeling.
http://www.gpgpu.org/forums/viewtopic.php?p=11843&sid=9069e02401e2acf53dedf61349fc8431 . In order to use rectangle textures in GLSL, we are supposed to used sampler2DRectShadow in the shader and starts the shader source code with "#extension GL_ARB_texture_rectangle: enable". But with a driver like 8776, it returns:
warning C7508: extension GL_ARB_texture_rectangle not supported
Implementation notes
Modified files
in VTK/Rendering:
vtkOpenGLActor.cxx vtkOpenGLProperty.cxx vtkOpenGLRenderer.cxx vtkOpenGLRenderer.h vtkOpenGLTexture.cxx vtkRenderer.cxx vtkRenderer.h Testing/Cxx/CMakeLists.txt Testing/Cxx/TestOpacity.cxx Testing/Tcl/CMakeLists.txt Testing/Tcl/TestOpacity2.tcl
VTK changes
Before the changes, Render() of vtkRenderer used to iterate over all props and call RenderTranslucentGeometry on each of them. Now, it calls a virtual method DeviceRenderTranslucentGeometry(). By default this method call UpdateTranslucentGeometry(). And UpdateTranslucentGeometry() do exactly what Render() used to do.
In vtkOpenGLRenderer, DeviceRenderTranslucentGeometry() is overridden to use depth peeling flags and implement depth peeling technique. For each peel it will call UpdateTranslucentGeometry().
It uses a lot of GPU RAM because each rgba buffer of each peel have to be saved. The last step perfoms compositing with each layer, back-to-front order ( if it was possible to do front-to-back compositing, we could perform compositing on the fly and we would not need to store each peel.) Compositing is done by rendering each layer as a texture on a quad.
As we first render opaque geometry, we use it to cull transparent geometry, limiting the number of required layers.
Comments on references
- The original depth peeling algorithm is described in [1].
- [2] first render opaque geometry and use depth peeling only for none-opaque geometry which can reduce drastically the number of depth peeling passes.
- To stop the iteration, follow [2], page 9, section 4. Transparency: "an occlusion query test on each pass indicates whether that layer was empty; if it was, the algorithm halts.". This kind of query is possible with openGL with BeginQuery/EndQuery (section 4.1.7 Occlusion Queries in page 207/221 spec 2.1). This is part of core OpenGL 1.5, promoted from extension GL_ARB_occlusion_query http://www.opengl.org/registry/specs/ARB/occlusion_query.txt.
- More on query: as the extension can count the number of pixels that changed, the stop condition can be a percentage of the screen size instead of a complete unmodified screen ([5])
- GLSL and Nvidia specific notes about shadow textures: [8]
References
- [1] Interactive Order-Independent Transparency Cass Everitt NVIDIA (technical paper 05/15/2001 http://developer.nvidia.com/attach/6545 and slides http://developer.nvidia.com/attach/6402)
- [2] GPU-Accelerated High-Quality Hidden Surface Removal Daniel Wexler, Larry Gritz, Eric Enderton, Jonathan Rice, Graphics Hardware 2005, 30-31 July 2005, Los Angeles CA, ACM
- [3] GPU-based Tiled Ray Casting using Depth Peeling Fábio F. Bernardon Christian A. Pagot João L. Comba Cládio T. Silva http://www.inf.ufrgs.br/~comba/papers/2006/gpu_volume_ray_casting.pdf
- [4] GPU-based Transparent Polygonal Geometry in Volume Rendering http://home.dataparty.no/kristian/school/ntnu/masterthesis/embedded-geometry-paper.pdf (extension 297 GL_EXT_depth_bounds_test http://www.opengl.org/registry/specs/EXT/depth_bounds_test.txt)
- [5] Occlusion slides from Nvidia at Game Developer Conference 2002: http://developer.nvidia.com/attach/6715
- [6] Thomas Porter and Tom Duff, "Compositing Digital Images", Computer Graphics, Volume 18, Number 3, July 1984 (ACM Siggraph). Pretty good reference about compositing/alpha arithmetic.
- [7] Multi-Layer Depth Peeling via Fragment Sort http://research.microsoft.com/research/pubs/view.aspx?tr_id=1125
- [8] Release Notes for NVIDIA OpenGL Shading Language Support http://download.nvidia.com/developer/GLSL/GLSL%20Release%20Notes%20for%20Release%2060.pdf (from http://developer.nvidia.com/object/nvemulate.html )
Glossary
- OIT: Order Independent Transparency
- MRT: Multiple Rendering Targets