mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0027925: Visualization - implement order-independent transparency algorithm within rasterization rendering
Weighted, Blended Order-Independent Transparency algorithm has been added rasterization pipeline. In contrast to classical blending transparency it makes transparent objects look independent from point of view. It also gives better depth occlusion when being used together with a weight factor based on value of a GL depth buffer. The feature supports desktop OpenGL, OpenGL ES 3.0, ANGLE and can be used together with MSAA on desktop GL. To be used it require availability of: 1) Shaders pipeline. 2) Floating point color format for framebuffer (GL_ARB_color_buffer_float). 3) Multiple render targets (GL_ARB_draw_buffers). Patch does not modify API and does not require application porting. It adds new rendering options to Graphic3d_RenderingParams structure: a) Transparency method from enumeration. b) Scalar factor [0-1] controlling influence of a fragment's depth to its visibility. Patch also simplifies processing of transparent objects for standard method: rendering priority of transparent graphical structures is managed automatically, therefore there is no need to care about it at application's side.
This commit is contained in:
@@ -249,6 +249,12 @@ const char THE_FRAG_CLIP_PLANES_2[] =
|
||||
EOL" discard;"
|
||||
EOL" }";
|
||||
|
||||
//! Output color and coverage for accumulation by OIT algorithm.
|
||||
const char THE_FRAG_write_oit_buffers[] =
|
||||
EOL" float aWeight = occFragColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);"
|
||||
EOL" occFragCoverage.r = occFragColor.a * aWeight;"
|
||||
EOL" occFragColor = vec4 (occFragColor.rgb * occFragColor.a * aWeight, occFragColor.a);";
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
|
||||
static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
@@ -1069,6 +1075,35 @@ void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : PushOitState
|
||||
// purpose : Pushes state of OIT uniforms to the specified program
|
||||
// =======================================================================
|
||||
void OpenGl_ShaderManager::PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
|
||||
{
|
||||
if (!theProgram->IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (myOitState.Index() == theProgram->ActiveState (OpenGL_OIT_STATE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const GLint aLocOutput = theProgram->GetStateLocation (OpenGl_OCCT_OIT_OUTPUT);
|
||||
if (aLocOutput != OpenGl_ShaderProgram::INVALID_LOCATION)
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocOutput, myOitState.ToEnableWrite());
|
||||
}
|
||||
|
||||
const GLint aLocDepthFactor = theProgram->GetStateLocation (OpenGl_OCCT_OIT_DEPTH_FACTOR);
|
||||
if (aLocDepthFactor != OpenGl_ShaderProgram::INVALID_LOCATION)
|
||||
{
|
||||
theProgram->SetUniform (myContext, aLocDepthFactor, myOitState.DepthFactor());
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : PushState
|
||||
// purpose : Pushes state of OCCT graphics parameters to the program
|
||||
@@ -1082,6 +1117,7 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
|
||||
PushProjectionState (aProgram);
|
||||
PushLightSourceState (aProgram);
|
||||
PushMaterialState (aProgram);
|
||||
PushOitState (aProgram);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -1124,6 +1160,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
@@ -1208,6 +1249,94 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : prepareStdProgramOitCompositing
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const Standard_Boolean theMsaa)
|
||||
{
|
||||
Handle(OpenGl_ShaderProgram)& aProgram = myOitCompositingProgram[theMsaa ? 1 : 0];
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
TCollection_AsciiString aSrcVert, aSrcFrag;
|
||||
|
||||
aSrcVert =
|
||||
EOL"THE_SHADER_OUT vec2 TexCoord;"
|
||||
EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" TexCoord = occVertex.zw;"
|
||||
EOL" gl_Position = vec4 (occVertex.x, occVertex.y, 0.0, 1.0);"
|
||||
EOL"}";
|
||||
|
||||
if (!theMsaa)
|
||||
{
|
||||
aSrcFrag =
|
||||
EOL"uniform sampler2D uAccumTexture;"
|
||||
EOL"uniform sampler2D uWeightTexture;"
|
||||
EOL
|
||||
EOL"THE_SHADER_IN vec2 TexCoord;"
|
||||
EOL
|
||||
EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" vec4 aAccum = occTexture2D (uAccumTexture, TexCoord);"
|
||||
EOL" float aWeight = occTexture2D (uWeightTexture, TexCoord).r;"
|
||||
EOL" occFragColor = vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a);"
|
||||
EOL"}";
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->IsGlGreaterEqual (3, 2))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
aSrcFrag =
|
||||
EOL"uniform sampler2DMS uAccumTexture;"
|
||||
EOL"uniform sampler2DMS uWeightTexture;"
|
||||
EOL
|
||||
EOL"THE_SHADER_IN vec2 TexCoord;"
|
||||
EOL
|
||||
EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" ivec2 aTexel = ivec2 (textureSize (uAccumTexture) * TexCoord);"
|
||||
EOL" vec4 aAccum = texelFetch (uAccumTexture, aTexel, gl_SampleID);"
|
||||
EOL" float aWeight = texelFetch (uWeightTexture, aTexel, gl_SampleID).r;"
|
||||
EOL" occFragColor = vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a);"
|
||||
EOL"}";
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->IsGlGreaterEqual (4, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 400");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
if (!Create (aProgramSrc, aKey, aProgram))
|
||||
{
|
||||
aProgram = new OpenGl_ShaderProgram(); // just mark as invalid
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
myContext->BindProgram (aProgram);
|
||||
aProgram->SetSampler (myContext, "uAccumTexture", 0);
|
||||
aProgram->SetSampler (myContext, "uWeightTexture", 1);
|
||||
myContext->BindProgram (Handle(OpenGl_ShaderProgram)());
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : pointSpriteAlphaSrc
|
||||
// purpose :
|
||||
@@ -1249,7 +1378,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
const Standard_Integer theBits)
|
||||
{
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
|
||||
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha;
|
||||
TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain, aSrcFragWriteOit;
|
||||
TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
|
||||
TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();";
|
||||
if ((theBits & OpenGl_PO_Point) != 0)
|
||||
@@ -1351,6 +1481,10 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
|
||||
}
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0)
|
||||
{
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
}
|
||||
|
||||
TCollection_AsciiString aSrcVertEndMain;
|
||||
if ((theBits & OpenGl_PO_StippleLine) != 0)
|
||||
@@ -1359,7 +1493,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
hasGlslBitOps = true;
|
||||
}
|
||||
#else
|
||||
@@ -1421,6 +1554,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
EOL"{"
|
||||
+ aSrcFragExtraMain
|
||||
+ aSrcFragMainGetColor
|
||||
+ aSrcFragWriteOit
|
||||
+ EOL"}";
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
@@ -1428,6 +1562,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
@@ -1572,7 +1711,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
const Standard_Integer theBits)
|
||||
{
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
|
||||
TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraOut, aSrcVertExtraMain;
|
||||
TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain, aSrcFragWriteOit;
|
||||
TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
|
||||
if ((theBits & OpenGl_PO_Point) != 0)
|
||||
{
|
||||
@@ -1640,6 +1780,10 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
|
||||
}
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0)
|
||||
{
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
|
||||
aSrcVert = TCollection_AsciiString()
|
||||
@@ -1673,13 +1817,19 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
EOL"{"
|
||||
+ aSrcFragExtraMain
|
||||
+ EOL" occFragColor = getColor();"
|
||||
EOL"}";
|
||||
+ aSrcFragWriteOit
|
||||
+ EOL"}";
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->core32 != NULL)
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
@@ -1702,7 +1852,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
#define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
|
||||
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
|
||||
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain;
|
||||
TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain, aSrcFragWriteOit;
|
||||
TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
|
||||
if ((theBits & OpenGl_PO_Point) != 0)
|
||||
{
|
||||
@@ -1763,6 +1914,10 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
|
||||
}
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0)
|
||||
{
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
}
|
||||
|
||||
aSrcVert = TCollection_AsciiString()
|
||||
+ THE_FUNC_transformNormal
|
||||
@@ -1799,13 +1954,19 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
EOL"{"
|
||||
+ aSrcFragExtraMain
|
||||
+ EOL" occFragColor = getColor();"
|
||||
EOL"}";
|
||||
+ aSrcFragWriteOit
|
||||
+ EOL"}";
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->core32 != NULL)
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
@@ -2022,6 +2183,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#else
|
||||
if (myContext->IsGlGreaterEqual (3, 0))
|
||||
{
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
|
Reference in New Issue
Block a user