/*========================================================================= 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 frambuffer 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 frambuffer 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 "vtkRenderingOpenGL2Module.h" // For export macro #include "vtkOpenGLRenderPass.h" #include // STL Header class vtkOpenGLFramebufferObject; class vtkTextureObject; class vtkOpenGLRenderWindow; class vtkOpenGLHelper; 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; vtkOpenGLHelper *FinalBlendProgram; vtkOpenGLHelper *IntermediateBlendProgram; // 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); private: vtkDepthPeelingPass(const vtkDepthPeelingPass&) = delete; void operator=(const vtkDepthPeelingPass&) = delete; }; #endif