mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-03 14:10:33 +03:00
0031571: Visualization, TKOpenGl - provide depth peeling OIT option
Graphic3d_RenderTransparentMethod has been extended by Graphic3d_RTM_DEPTH_PEELING_OIT, which is handled by OpenGl_LayerList::renderTransparent(). OpenGl_FrameBuffer::Init() now does not silently ignore unknown color attachment format and return failure. OpenGl_FrameBuffer::InitWrapper() - added constructor wrapping existing color textures. v3d/transparency/oit: test case added
This commit is contained in:
@@ -89,6 +89,13 @@
|
||||
#define occFragColor occFragColor0
|
||||
#define occFragCoverage occFragColor1
|
||||
|
||||
#define occPeelDepth occFragColor0
|
||||
#define occPeelFrontColor occFragColor1
|
||||
#define occPeelBackColor occFragColor2
|
||||
|
||||
//! Define the main Fragment Shader early return procedure.
|
||||
bool occFragEarlyReturn();
|
||||
|
||||
//! Define the main Fragment Shader output - color value.
|
||||
void occSetFragColor (in vec4 theColor);
|
||||
#endif
|
||||
|
@@ -1,7 +1,41 @@
|
||||
|
||||
//! @file DeclarationsImpl.glsl includes implementation of common functions and properties accessors
|
||||
#if defined(FRAGMENT_SHADER)
|
||||
//! Output color (and coverage for accumulation by OIT algorithm).
|
||||
|
||||
#if defined(OCC_DEPTH_PEEL_OIT)
|
||||
uniform sampler2D occDepthPeelingDepth;
|
||||
uniform sampler2D occDepthPeelingFrontColor;
|
||||
int IsFrontPeelLayer = -1;
|
||||
bool occFragEarlyReturn()
|
||||
{
|
||||
#define THE_DEPTH_CLEAR_VALUE -1e15f
|
||||
ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);
|
||||
vec2 aLastDepth = texelFetch (occDepthPeelingDepth, aFragCoord, 0).rg;
|
||||
occPeelFrontColor = texelFetch (occDepthPeelingFrontColor, aFragCoord, 0);
|
||||
occPeelDepth.rg = vec2 (THE_DEPTH_CLEAR_VALUE); // depth value always increases, so that MAX blend equation can be used
|
||||
occPeelBackColor = vec4 (0.0); // back color is blend after each peeling pass
|
||||
|
||||
float aNearDepth = -aLastDepth.x;
|
||||
float aFarDepth = aLastDepth.y;
|
||||
float aFragDepth = gl_FragCoord.z; // 0 - 1
|
||||
if (aFragDepth < aNearDepth || aFragDepth > aFarDepth)
|
||||
{
|
||||
return true; // skip peeled depth
|
||||
}
|
||||
else if (aFragDepth > aNearDepth && aFragDepth < aFarDepth)
|
||||
{
|
||||
// to be rendered at next peeling pass
|
||||
occPeelDepth.rg = vec2 (-aFragDepth, aFragDepth);
|
||||
return true;
|
||||
}
|
||||
|
||||
IsFrontPeelLayer = (gl_FragCoord.z == aNearDepth) ? 1 : 0;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
bool occFragEarlyReturn() { return false; }
|
||||
#endif
|
||||
|
||||
void occSetFragColor (in vec4 theColor)
|
||||
{
|
||||
#if defined(OCC_ALPHA_TEST)
|
||||
@@ -11,6 +45,18 @@ void occSetFragColor (in vec4 theColor)
|
||||
float aWeight = theColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);
|
||||
occFragCoverage.r = theColor.a * aWeight;
|
||||
occFragColor = vec4 (theColor.rgb * theColor.a * aWeight, theColor.a);
|
||||
#elif defined(OCC_DEPTH_PEEL_OIT)
|
||||
if (IsFrontPeelLayer == 1) // front is blended directly
|
||||
{
|
||||
vec4 aLastColor = occPeelFrontColor;
|
||||
float anAlphaMult = 1.0 - aLastColor.a;
|
||||
occPeelFrontColor.rgb = aLastColor.rgb + theColor.rgb * theColor.a * anAlphaMult;
|
||||
occPeelFrontColor.a = 1.0 - anAlphaMult * (1.0 - theColor.a);
|
||||
}
|
||||
else if (IsFrontPeelLayer == 0) // back is blended afterwards
|
||||
{
|
||||
occPeelBackColor = theColor;
|
||||
}
|
||||
#else
|
||||
occFragColor = theColor;
|
||||
#endif
|
||||
|
@@ -4,7 +4,41 @@ static const char Shaders_DeclarationsImpl_glsl[] =
|
||||
"\n"
|
||||
"//! @file DeclarationsImpl.glsl includes implementation of common functions and properties accessors\n"
|
||||
"#if defined(FRAGMENT_SHADER)\n"
|
||||
"//! Output color (and coverage for accumulation by OIT algorithm).\n"
|
||||
"\n"
|
||||
"#if defined(OCC_DEPTH_PEEL_OIT)\n"
|
||||
"uniform sampler2D occDepthPeelingDepth;\n"
|
||||
"uniform sampler2D occDepthPeelingFrontColor;\n"
|
||||
"int IsFrontPeelLayer = -1;\n"
|
||||
"bool occFragEarlyReturn()\n"
|
||||
"{\n"
|
||||
" #define THE_DEPTH_CLEAR_VALUE -1e15f\n"
|
||||
" ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);\n"
|
||||
" vec2 aLastDepth = texelFetch (occDepthPeelingDepth, aFragCoord, 0).rg;\n"
|
||||
" occPeelFrontColor = texelFetch (occDepthPeelingFrontColor, aFragCoord, 0);\n"
|
||||
" occPeelDepth.rg = vec2 (THE_DEPTH_CLEAR_VALUE); // depth value always increases, so that MAX blend equation can be used\n"
|
||||
" occPeelBackColor = vec4 (0.0); // back color is blend after each peeling pass\n"
|
||||
"\n"
|
||||
" float aNearDepth = -aLastDepth.x;\n"
|
||||
" float aFarDepth = aLastDepth.y;\n"
|
||||
" float aFragDepth = gl_FragCoord.z; // 0 - 1\n"
|
||||
" if (aFragDepth < aNearDepth || aFragDepth > aFarDepth)\n"
|
||||
" {\n"
|
||||
" return true; // skip peeled depth\n"
|
||||
" }\n"
|
||||
" else if (aFragDepth > aNearDepth && aFragDepth < aFarDepth)\n"
|
||||
" {\n"
|
||||
" // to be rendered at next peeling pass\n"
|
||||
" occPeelDepth.rg = vec2 (-aFragDepth, aFragDepth);\n"
|
||||
" return true;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" IsFrontPeelLayer = (gl_FragCoord.z == aNearDepth) ? 1 : 0;\n"
|
||||
" return false;\n"
|
||||
"}\n"
|
||||
"#else\n"
|
||||
"bool occFragEarlyReturn() { return false; }\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"void occSetFragColor (in vec4 theColor)\n"
|
||||
"{\n"
|
||||
"#if defined(OCC_ALPHA_TEST)\n"
|
||||
@@ -14,6 +48,18 @@ static const char Shaders_DeclarationsImpl_glsl[] =
|
||||
" float aWeight = theColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);\n"
|
||||
" occFragCoverage.r = theColor.a * aWeight;\n"
|
||||
" occFragColor = vec4 (theColor.rgb * theColor.a * aWeight, theColor.a);\n"
|
||||
"#elif defined(OCC_DEPTH_PEEL_OIT)\n"
|
||||
" if (IsFrontPeelLayer == 1) // front is blended directly\n"
|
||||
" {\n"
|
||||
" vec4 aLastColor = occPeelFrontColor;\n"
|
||||
" float anAlphaMult = 1.0 - aLastColor.a;\n"
|
||||
" occPeelFrontColor.rgb = aLastColor.rgb + theColor.rgb * theColor.a * anAlphaMult;\n"
|
||||
" occPeelFrontColor.a = 1.0 - anAlphaMult * (1.0 - theColor.a);\n"
|
||||
" }\n"
|
||||
" else if (IsFrontPeelLayer == 0) // back is blended afterwards\n"
|
||||
" {\n"
|
||||
" occPeelBackColor = theColor;\n"
|
||||
" }\n"
|
||||
"#else\n"
|
||||
" occFragColor = theColor;\n"
|
||||
"#endif\n"
|
||||
|
@@ -92,6 +92,13 @@ static const char Shaders_Declarations_glsl[] =
|
||||
" #define occFragColor occFragColor0\n"
|
||||
" #define occFragCoverage occFragColor1\n"
|
||||
"\n"
|
||||
" #define occPeelDepth occFragColor0\n"
|
||||
" #define occPeelFrontColor occFragColor1\n"
|
||||
" #define occPeelBackColor occFragColor2\n"
|
||||
"\n"
|
||||
" //! Define the main Fragment Shader early return procedure.\n"
|
||||
" bool occFragEarlyReturn();\n"
|
||||
"\n"
|
||||
" //! Define the main Fragment Shader output - color value.\n"
|
||||
" void occSetFragColor (in vec4 theColor);\n"
|
||||
"#endif\n"
|
||||
|
Reference in New Issue
Block a user