1
0
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:
kgv
2020-05-19 10:47:25 +03:00
committed by bugmaster
parent 9f45d35b6b
commit 78c4e836b1
31 changed files with 1160 additions and 171 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"