/*========================================================================= Program: Visualization Toolkit Module: vtkDepthPeelingPass.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkDepthPeelingPass * @brief Implement Depth Peeling for use within a framebuffer pass * * Note that this implementation is used as a fallback for drivers that * don't support floating point textures. Most renderings will use the subclass * vtkDualDepthPeelingPass instead. * * Render the translucent polygonal geometry of a scene without sorting * polygons in the view direction. * * This pass expects an initialized depth buffer and color buffer. * Initialized buffers means they have been cleared with farest z-value and * background color/gradient/transparent color. * An opaque pass may have been performed right after the initialization. * * The depth peeling algorithm works by rendering the translucent polygonal * geometry multiple times (once for each peel). The actually rendering of * the translucent polygonal geometry is performed by its delegate * TranslucentPass. This delegate is therefore used multiple times. * * Its delegate is usually set to a vtkTranslucentPass. * * This implementation makes use of textures and is suitable for ES3 * For ES3 it must be embedded within a pass that makes use of framebuffers * so that the required OpaqueZTexture and OpaqueRGBATexture can be * passed from the outer framebuffer pass. For OpenGL ES3 be aware the * occlusion ratio test is not supported. The maximum number of peels * is used instead so set it to a reasonable value. For many scenes * a value of 4 or 5 will work well. * * @sa * vtkRenderPass, vtkTranslucentPass, vtkFramebufferPass */ #ifndef vtkDepthPeelingPass_h #define vtkDepthPeelingPass_h #include "vtkOpenGLRenderPass.h" #include "vtkRenderingOpenGL2Module.h" // For export macro #include // STL Header class vtkOpenGLFramebufferObject; class vtkTextureObject; class vtkOpenGLRenderWindow; class vtkOpenGLState; class vtkOpenGLQuadHelper; class VTKRENDERINGOPENGL2_EXPORT vtkDepthPeelingPass : public vtkOpenGLRenderPass { public: static vtkDepthPeelingPass* New(); vtkTypeMacro(vtkDepthPeelingPass, vtkOpenGLRenderPass); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Perform rendering according to a render state \p s. * \pre s_exists: s!=0 */ void Render(const vtkRenderState* s) override; /** * Release graphics resources and ask components to release their own * resources. * \pre w_exists: w!=0 */ void ReleaseGraphicsResources(vtkWindow* w) override; //@{ /** * Delegate for rendering the translucent polygonal geometry. * If it is NULL, nothing will be rendered and a warning will be emitted. * It is usually set to a vtkTranslucentPass. * Initial value is a NULL pointer. */ vtkGetObjectMacro(TranslucentPass, vtkRenderPass); virtual void SetTranslucentPass(vtkRenderPass* translucentPass); //@} //@{ /** * In case of use of depth peeling technique for rendering translucent * material, define the threshold under which the algorithm stops to * iterate over peel layers. This is the ratio of the number of pixels * that have been touched by the last layer over the total number of pixels * of the viewport area. * Initial value is 0.0, meaning rendering have to be exact. Greater values * may speed-up the rendering with small impact on the quality. */ vtkSetClampMacro(OcclusionRatio, double, 0.0, 0.5); vtkGetMacro(OcclusionRatio, double); //@} //@{ /** * In case of depth peeling, define the maximum number of peeling layers. * Initial value is 4. A special value of 0 means no maximum limit. * It has to be a positive value. */ vtkSetMacro(MaximumNumberOfPeels, int); vtkGetMacro(MaximumNumberOfPeels, int); //@} // vtkOpenGLRenderPass virtuals: bool PostReplaceShaderValues(std::string& vertexShader, std::string& geometryShader, std::string& fragmentShader, vtkAbstractMapper* mapper, vtkProp* prop) override; bool SetShaderParameters(vtkShaderProgram* program, vtkAbstractMapper* mapper, vtkProp* prop, vtkOpenGLVertexArrayObject* VAO = nullptr) override; // Set Opaque Z texture, this must be set from the outer FO void SetOpaqueZTexture(vtkTextureObject*); // Set Opaque RGBA texture, this must be set from the outer FO void SetOpaqueRGBATexture(vtkTextureObject*); /** * Set the format to use for the depth texture * e.g. vtkTextureObject::Float32 */ vtkSetMacro(DepthFormat, int); protected: /** * Default constructor. TranslucentPass is set to NULL. */ vtkDepthPeelingPass(); /** * Destructor. */ ~vtkDepthPeelingPass() override; vtkRenderPass* TranslucentPass; vtkTimeStamp CheckTime; //@{ /** * Cache viewport values for depth peeling. */ int ViewportX; int ViewportY; int ViewportWidth; int ViewportHeight; //@} /** * In case of use of depth peeling technique for rendering translucent * material, define the threshold under which the algorithm stops to * iterate over peel layers. This is the ratio of the number of pixels * that have been touched by the last layer over the total number of pixels * of the viewport area. * Initial value is 0.0, meaning rendering have to be exact. Greater values * may speed-up the rendering with small impact on the quality. */ double OcclusionRatio; /** * In case of depth peeling, define the maximum number of peeling layers. * Initial value is 4. A special value of 0 means no maximum limit. * It has to be a positive value. */ int MaximumNumberOfPeels; vtkOpenGLFramebufferObject* Framebuffer; vtkOpenGLQuadHelper* FinalBlend; vtkOpenGLQuadHelper* IntermediateBlend; // obtained from the outer FO, we read from them vtkTextureObject* OpaqueZTexture; vtkTextureObject* OpaqueRGBATexture; bool OwnOpaqueZTexture; bool OwnOpaqueRGBATexture; // each peel merges two color buffers into one result vtkTextureObject* TranslucentRGBATexture[3]; int ColorDrawCount; int PeelCount; // each peel compares a prior Z and writes to next vtkTextureObject* TranslucentZTexture[2]; int DepthFormat; void BlendIntermediatePeels(vtkOpenGLRenderWindow* renWin, bool); void BlendFinalPeel(vtkOpenGLRenderWindow* renWin); // useful to store vtkOpenGLState* State; private: vtkDepthPeelingPass(const vtkDepthPeelingPass&) = delete; void operator=(const vtkDepthPeelingPass&) = delete; }; #endif