mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0029337: Visualization, TKOpenGl - visual artifacts on Intel Broadwell GPU
Enable multiple draw buffers in shader program only if its required by specific application. occSetFragColor() - a new GLSL function has been introduced as an alternative to setting occFragColor/occFragCoverage variables.
This commit is contained in:
parent
12d71ad6a5
commit
b17e5bae1a
@ -78,7 +78,9 @@ const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
|
||||
// =======================================================================
|
||||
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
|
||||
: myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
|
||||
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT)
|
||||
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
|
||||
myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
|
||||
myHasWeightOitOutput (false)
|
||||
{
|
||||
myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
|
||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
|
||||
|
@ -43,6 +43,9 @@ public:
|
||||
//! Default value of THE_MAX_CLIP_PLANES macros within GLSL program (see Declarations.glsl).
|
||||
static const Standard_Integer THE_MAX_CLIP_PLANES_DEFAULT = 8;
|
||||
|
||||
//! Default value of THE_NB_FRAG_OUTPUTS macros within GLSL program (see Declarations.glsl).
|
||||
static const Standard_Integer THE_NB_FRAG_OUTPUTS = 1;
|
||||
|
||||
public:
|
||||
|
||||
//! Creates new empty program object.
|
||||
@ -115,6 +118,21 @@ public:
|
||||
//! Should be done before GLSL program initialization.
|
||||
Standard_EXPORT void SetVertexAttributes (const Graphic3d_ShaderAttributeList& theAttributes);
|
||||
|
||||
//! Returns the number (1+) of Fragment Shader outputs to be written to
|
||||
//! (more than 1 can be in case of multiple draw buffers); 1 by default.
|
||||
Standard_Integer NbFragmentOutputs() const { return myNbFragOutputs; }
|
||||
|
||||
//! Sets the number of Fragment Shader outputs to be written to.
|
||||
//! Should be done before GLSL program initialization.
|
||||
void SetNbFragmentOutputs (const Standard_Integer theNbOutputs) { myNbFragOutputs = theNbOutputs; }
|
||||
|
||||
//! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
|
||||
Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
|
||||
|
||||
//! Set if Fragment Shader color should output the weighted OIT coverage.
|
||||
//! Note that weighted OIT also requires at least 2 Fragment Outputs (color + coverage).
|
||||
void SetWeightOitOutput (Standard_Boolean theOutput) { myHasWeightOitOutput = theOutput; }
|
||||
|
||||
//! Pushes custom uniform variable to the program.
|
||||
//! The list of pushed variables is automatically cleared after applying to GLSL program.
|
||||
//! Thus after program recreation even unchanged uniforms should be pushed anew.
|
||||
@ -164,6 +182,8 @@ private:
|
||||
TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions
|
||||
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
|
||||
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
|
||||
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
|
||||
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
|
||||
|
||||
};
|
||||
|
||||
|
@ -441,18 +441,13 @@ void OpenGl_Context::SetDrawBuffers (const Standard_Integer theNb, const Standar
|
||||
Standard_Boolean useDefaultFbo = Standard_False;
|
||||
for (Standard_Integer anI = 0; anI < theNb; ++anI)
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
const Standard_Integer aDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffers[anI]) : theDrawBuffers[anI];
|
||||
#else
|
||||
const Standard_Integer aDrawBuffer = theDrawBuffers[anI];
|
||||
#endif
|
||||
if (aDrawBuffer < GL_COLOR_ATTACHMENT0 && aDrawBuffer != GL_NONE)
|
||||
if (theDrawBuffers[anI] < GL_COLOR_ATTACHMENT0 && theDrawBuffers[anI] != GL_NONE)
|
||||
{
|
||||
useDefaultFbo = Standard_True;
|
||||
}
|
||||
else if (aDrawBuffer != GL_NONE)
|
||||
else if (theDrawBuffers[anI] != GL_NONE)
|
||||
{
|
||||
myDrawBuffers.SetValue (anI, aDrawBuffer);
|
||||
myDrawBuffers.SetValue (anI, theDrawBuffers[anI]);
|
||||
}
|
||||
}
|
||||
if (arbFBO != NULL && useDefaultFbo)
|
||||
|
@ -265,12 +265,6 @@ 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 };
|
||||
@ -1194,7 +1188,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
|
||||
EOL" vec4 aColor = occColor;"
|
||||
EOL" aColor.a *= getAlpha();"
|
||||
EOL" if (aColor.a <= 0.285) discard;"
|
||||
EOL" occFragColor = aColor;"
|
||||
EOL" occSetFragColor (aColor);"
|
||||
EOL"}";
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
@ -1245,7 +1239,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
|
||||
EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
|
||||
EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
|
||||
EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
|
||||
EOL"}";
|
||||
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
@ -1268,7 +1262,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
|
||||
EOL
|
||||
EOL"void main()"
|
||||
EOL"{"
|
||||
EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
|
||||
EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
|
||||
EOL"}";
|
||||
}
|
||||
#else
|
||||
@ -1325,7 +1319,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
|
||||
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" occSetFragColor (vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a));"
|
||||
EOL"}";
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->IsGlGreaterEqual (3, 2))
|
||||
@ -1352,7 +1346,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
|
||||
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" occSetFragColor (vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a));"
|
||||
EOL"}";
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (myContext->IsGlGreaterEqual (4, 0))
|
||||
@ -1429,7 +1423,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
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();";
|
||||
TCollection_AsciiString aSrcFragMainGetColor = EOL" occSetFragColor (getColor());";
|
||||
if ((theBits & OpenGl_PO_Point) != 0)
|
||||
{
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
@ -1458,14 +1452,14 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
EOL" vec4 aColor = getColor();"
|
||||
EOL" aColor.a = getAlpha();"
|
||||
EOL" if (aColor.a <= 0.1) discard;"
|
||||
EOL" occFragColor = aColor;";
|
||||
EOL" occSetFragColor (aColor);";
|
||||
}
|
||||
else
|
||||
{
|
||||
aSrcFragMainGetColor =
|
||||
EOL" vec4 aColor = getColor();"
|
||||
EOL" if (aColor.a <= 0.1) discard;"
|
||||
EOL" occFragColor = aColor;";
|
||||
EOL" occSetFragColor (aColor);";
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1536,7 +1530,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0)
|
||||
{
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
aProgramSrc->SetNbFragmentOutputs (2);
|
||||
aProgramSrc->SetWeightOitOutput (true);
|
||||
}
|
||||
|
||||
TCollection_AsciiString aSrcVertEndMain;
|
||||
@ -1578,7 +1573,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
|
||||
EOL" vec4 aColor = getColor();"
|
||||
EOL" if (aColor.a <= 0.1) discard;"
|
||||
EOL" occFragColor = aColor;";
|
||||
EOL" occSetFragColor (aColor);";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1888,7 +1883,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0)
|
||||
{
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
aProgramSrc->SetNbFragmentOutputs (2);
|
||||
aProgramSrc->SetWeightOitOutput (true);
|
||||
}
|
||||
|
||||
Standard_Integer aNbLights = 0;
|
||||
@ -1923,7 +1919,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
+ EOL"void main()"
|
||||
EOL"{"
|
||||
+ aSrcFragExtraMain
|
||||
+ EOL" occFragColor = getColor();"
|
||||
+ EOL" occSetFragColor (getColor());"
|
||||
+ aSrcFragWriteOit
|
||||
+ EOL"}";
|
||||
|
||||
@ -2037,7 +2033,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
}
|
||||
if ((theBits & OpenGl_PO_WriteOit) != 0)
|
||||
{
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
aProgramSrc->SetNbFragmentOutputs (2);
|
||||
aProgramSrc->SetWeightOitOutput (true);
|
||||
}
|
||||
|
||||
aSrcVert = TCollection_AsciiString()
|
||||
@ -2082,7 +2079,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
+ (isFlatNormal
|
||||
? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
|
||||
: "")
|
||||
+ EOL" occFragColor = getColor();"
|
||||
+ EOL" occSetFragColor (getColor());"
|
||||
+ aSrcFragWriteOit
|
||||
+ EOL"}";
|
||||
|
||||
@ -2163,7 +2160,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
|
||||
EOL" aColorR = pow (aColorR, THE_POW_UP);"
|
||||
EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
|
||||
EOL" occFragColor = pow (aColor, THE_POW_DOWN);"
|
||||
EOL" occSetFragColor (pow (aColor, THE_POW_DOWN));"
|
||||
EOL"}";
|
||||
break;
|
||||
}
|
||||
@ -2181,11 +2178,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
|
||||
EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorL;"
|
||||
EOL" occSetFragColor (aColorL);"
|
||||
EOL" }"
|
||||
EOL" else"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorR;"
|
||||
EOL" occSetFragColor (aColorR);"
|
||||
EOL" }"
|
||||
EOL"}";
|
||||
break;
|
||||
@ -2204,11 +2201,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
|
||||
EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorL;"
|
||||
EOL" occSetFragColor (aColorL);"
|
||||
EOL" }"
|
||||
EOL" else"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorR;"
|
||||
EOL" occSetFragColor (aColorR);"
|
||||
EOL" }"
|
||||
EOL"}";
|
||||
break;
|
||||
@ -2229,11 +2226,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
|
||||
EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorL;"
|
||||
EOL" occSetFragColor (aColorL);"
|
||||
EOL" }"
|
||||
EOL" else"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorR;"
|
||||
EOL" occSetFragColor (aColorR);"
|
||||
EOL" }"
|
||||
EOL"}";
|
||||
break;
|
||||
@ -2257,11 +2254,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
|
||||
EOL" if (TexCoord.x <= 0.5)"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorL;"
|
||||
EOL" occSetFragColor (aColorL);"
|
||||
EOL" }"
|
||||
EOL" else"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorR;"
|
||||
EOL" occSetFragColor (aColorR);"
|
||||
EOL" }"
|
||||
EOL"}";
|
||||
break;
|
||||
@ -2285,11 +2282,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
|
||||
EOL" if (TexCoord.y <= 0.5)"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorL;"
|
||||
EOL" occSetFragColor (aColorL);"
|
||||
EOL" }"
|
||||
EOL" else"
|
||||
EOL" {"
|
||||
EOL" occFragColor = aColorR;"
|
||||
EOL" occSetFragColor (aColorR);"
|
||||
EOL" }"
|
||||
EOL"}";
|
||||
break;
|
||||
@ -2316,7 +2313,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
EOL" aColorL.b = 0.0;"
|
||||
EOL" aColorL.g = 0.0;"
|
||||
EOL" aColorR.r = 0.0;"
|
||||
EOL" occFragColor = aColorL + aColorR;"
|
||||
EOL" occSetFragColor (aColorL + aColorR);"
|
||||
EOL"}";
|
||||
break;
|
||||
}
|
||||
|
@ -151,6 +151,8 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
|
||||
myShareCount(1),
|
||||
myNbLightsMax (0),
|
||||
myNbClipPlanesMax (0),
|
||||
myNbFragOutputs (1),
|
||||
myHasWeightOitOutput (false),
|
||||
myHasTessShader (false)
|
||||
{
|
||||
memset (myCurrentState, 0, sizeof (myCurrentState));
|
||||
@ -180,6 +182,8 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
aShaderMask |= anIter.Value()->Type();
|
||||
}
|
||||
myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0;
|
||||
myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1;
|
||||
myHasWeightOitOutput = !myProxy.IsNull() ? myProxy->HasWeightOitOutput() && myNbFragOutputs >= 2 : 1;
|
||||
|
||||
// detect the minimum GLSL version required for defined Shader Objects
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
@ -275,10 +279,23 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
}
|
||||
|
||||
TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n";
|
||||
if (myNbFragOutputs > 1)
|
||||
{
|
||||
if (theCtx->hasDrawBuffers)
|
||||
{
|
||||
anExtensions += "#define OCC_ENABLE_draw_buffers\n";
|
||||
if (myHasWeightOitOutput)
|
||||
{
|
||||
anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Error! Multiple draw buffers required by the program, but aren't supported by OpenGL");
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions)
|
||||
{
|
||||
if (theCtx->arbDrawBuffers)
|
||||
@ -290,6 +307,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
anExtensions += "#extension GL_EXT_draw_buffers : enable\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions)
|
||||
{
|
||||
@ -334,6 +352,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
|
||||
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
|
||||
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
|
||||
aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
|
||||
|
||||
const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
|
||||
+ (!aHeaderVer.IsEmpty() ? "\n" : "")
|
||||
|
@ -226,6 +226,13 @@ public:
|
||||
//! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS).
|
||||
Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
|
||||
|
||||
//! Return the length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS),
|
||||
//! to be used for initialization occFragColorArray/occFragColorN.
|
||||
Standard_Integer NbFragmentOutputs() const { return myNbFragOutputs; }
|
||||
|
||||
//! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
|
||||
Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
|
||||
|
||||
private:
|
||||
|
||||
//! Returns index of last modification of variables of specified state type.
|
||||
@ -569,6 +576,8 @@ protected:
|
||||
Standard_Integer myShareCount; //!< program users count, initialized with 1 (already shared by one user)
|
||||
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
|
||||
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
|
||||
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
|
||||
Standard_Boolean myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
|
||||
Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage
|
||||
|
||||
protected:
|
||||
|
@ -24,6 +24,10 @@
|
||||
//! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager.
|
||||
// #define THE_MAX_CLIP_PLANES 8
|
||||
|
||||
//! @def THE_NB_FRAG_OUTPUTS
|
||||
//! Specifies the length of array of Fragment Shader outputs, which is 1 by default. Defined by Shader Manager.
|
||||
// #define THE_NB_FRAG_OUTPUTS 1
|
||||
|
||||
// compatibility macros
|
||||
#if (__VERSION__ >= 130)
|
||||
#define THE_ATTRIBUTE in
|
||||
@ -58,20 +62,43 @@
|
||||
#elif defined(FRAGMENT_SHADER)
|
||||
#if (__VERSION__ >= 130)
|
||||
#ifdef OCC_ENABLE_draw_buffers
|
||||
out vec4 occFragColorArray[2];
|
||||
#define occFragColor occFragColorArray[0]
|
||||
#define occFragCoverage occFragColorArray[1]
|
||||
out vec4 occFragColorArray[THE_NB_FRAG_OUTPUTS];
|
||||
#define occFragColorArrayAlias occFragColorArray
|
||||
#define occFragColor0 occFragColorArray[0]
|
||||
#else
|
||||
out vec4 occFragColor;
|
||||
out vec4 occFragColor0;
|
||||
#endif
|
||||
#else
|
||||
#ifdef OCC_ENABLE_draw_buffers
|
||||
#define occFragColor gl_FragData[0]
|
||||
#define occFragCoverage gl_FragData[1]
|
||||
#define occFragColorArrayAlias gl_FragData
|
||||
#define occFragColor0 gl_FragData[0]
|
||||
#else
|
||||
#define occFragColor gl_FragColor
|
||||
#define occFragColor0 gl_FragColor
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (THE_NB_FRAG_OUTPUTS >= 2)
|
||||
#define occFragColor1 occFragColorArrayAlias[1]
|
||||
#else
|
||||
vec4 occFragColor1;
|
||||
#endif
|
||||
#if (THE_NB_FRAG_OUTPUTS >= 3)
|
||||
#define occFragColor2 occFragColorArrayAlias[2]
|
||||
#else
|
||||
vec4 occFragColor2;
|
||||
#endif
|
||||
#if (THE_NB_FRAG_OUTPUTS >= 4)
|
||||
#define occFragColor3 occFragColorArrayAlias[3]
|
||||
#else
|
||||
vec4 occFragColor3;
|
||||
#endif
|
||||
|
||||
// Built-in outputs notation
|
||||
#define occFragColor occFragColor0
|
||||
#define occFragCoverage occFragColor1
|
||||
|
||||
//! Define the main Fragment Shader output - color value.
|
||||
void occSetFragColor (in vec4 theColor);
|
||||
#endif
|
||||
|
||||
// Matrix state
|
||||
|
@ -15,6 +15,21 @@
|
||||
|
||||
// This file includes implementation of common functions and properties accessors
|
||||
|
||||
#if defined(FRAGMENT_SHADER)
|
||||
#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)
|
||||
//! Output color and coverage for accumulation by OIT algorithm.
|
||||
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);
|
||||
}
|
||||
#else
|
||||
//! Output color.
|
||||
void occSetFragColor (in vec4 theColor) { occFragColor = theColor; }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)
|
||||
// arrays of light sources
|
||||
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
|
||||
|
@ -186,14 +186,6 @@ void main()
|
||||
}
|
||||
}
|
||||
|
||||
occFragColor = computeLighting (normalize (Normal),
|
||||
normalize (View),
|
||||
Position);
|
||||
|
||||
if (occOitOutput != 0)
|
||||
{
|
||||
float aWeight = occFragColor.a * clamp (1e+2 * pow (1.0 - gl_FragCoord.z * occOitDepthFactor, 3.0), 1e-2, 1e+2);
|
||||
occFragCoverage.r = occFragColor.a * aWeight;
|
||||
occFragColor = vec4 (occFragColor.rgb * occFragColor.a * aWeight, occFragColor.a);
|
||||
}
|
||||
vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position);
|
||||
occSetFragColor (aColor);
|
||||
}
|
||||
|
@ -18,6 +18,21 @@ static const char Shaders_DeclarationsImpl_glsl[] =
|
||||
"\n"
|
||||
"// This file includes implementation of common functions and properties accessors\n"
|
||||
"\n"
|
||||
"#if defined(FRAGMENT_SHADER)\n"
|
||||
"#if defined(OCC_WRITE_WEIGHT_OIT_COVERAGE)\n"
|
||||
"//! Output color and coverage for accumulation by OIT algorithm.\n"
|
||||
"void occSetFragColor (in vec4 theColor)\n"
|
||||
"{\n"
|
||||
" 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"
|
||||
"}\n"
|
||||
"#else\n"
|
||||
"//! Output color.\n"
|
||||
"void occSetFragColor (in vec4 theColor) { occFragColor = theColor; }\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n"
|
||||
"// arrays of light sources\n"
|
||||
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
|
||||
|
@ -27,6 +27,10 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"//! Specifies the length of array of clipping planes, which is 8 by default. Defined by Shader Manager.\n"
|
||||
"// #define THE_MAX_CLIP_PLANES 8\n"
|
||||
"\n"
|
||||
"//! @def THE_NB_FRAG_OUTPUTS\n"
|
||||
"//! Specifies the length of array of Fragment Shader outputs, which is 1 by default. Defined by Shader Manager.\n"
|
||||
"// #define THE_NB_FRAG_OUTPUTS 1\n"
|
||||
"\n"
|
||||
"// compatibility macros\n"
|
||||
"#if (__VERSION__ >= 130)\n"
|
||||
" #define THE_ATTRIBUTE in\n"
|
||||
@ -61,20 +65,43 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"#elif defined(FRAGMENT_SHADER)\n"
|
||||
" #if (__VERSION__ >= 130)\n"
|
||||
" #ifdef OCC_ENABLE_draw_buffers\n"
|
||||
" out vec4 occFragColorArray[2];\n"
|
||||
" #define occFragColor occFragColorArray[0]\n"
|
||||
" #define occFragCoverage occFragColorArray[1]\n"
|
||||
" out vec4 occFragColorArray[THE_NB_FRAG_OUTPUTS];\n"
|
||||
" #define occFragColorArrayAlias occFragColorArray\n"
|
||||
" #define occFragColor0 occFragColorArray[0]\n"
|
||||
" #else\n"
|
||||
" out vec4 occFragColor;\n"
|
||||
" out vec4 occFragColor0;\n"
|
||||
" #endif\n"
|
||||
" #else\n"
|
||||
" #ifdef OCC_ENABLE_draw_buffers\n"
|
||||
" #define occFragColor gl_FragData[0]\n"
|
||||
" #define occFragCoverage gl_FragData[1]\n"
|
||||
" #define occFragColorArrayAlias gl_FragData\n"
|
||||
" #define occFragColor0 gl_FragData[0]\n"
|
||||
" #else\n"
|
||||
" #define occFragColor gl_FragColor\n"
|
||||
" #define occFragColor0 gl_FragColor\n"
|
||||
" #endif\n"
|
||||
" #endif\n"
|
||||
"\n"
|
||||
" #if (THE_NB_FRAG_OUTPUTS >= 2)\n"
|
||||
" #define occFragColor1 occFragColorArrayAlias[1]\n"
|
||||
" #else\n"
|
||||
" vec4 occFragColor1;\n"
|
||||
" #endif\n"
|
||||
" #if (THE_NB_FRAG_OUTPUTS >= 3)\n"
|
||||
" #define occFragColor2 occFragColorArrayAlias[2]\n"
|
||||
" #else\n"
|
||||
" vec4 occFragColor2;\n"
|
||||
" #endif\n"
|
||||
" #if (THE_NB_FRAG_OUTPUTS >= 4)\n"
|
||||
" #define occFragColor3 occFragColorArrayAlias[3]\n"
|
||||
" #else\n"
|
||||
" vec4 occFragColor3;\n"
|
||||
" #endif\n"
|
||||
"\n"
|
||||
" // Built-in outputs notation\n"
|
||||
" #define occFragColor occFragColor0\n"
|
||||
" #define occFragCoverage occFragColor1\n"
|
||||
"\n"
|
||||
" //! Define the main Fragment Shader output - color value.\n"
|
||||
" void occSetFragColor (in vec4 theColor);\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// Matrix state\n"
|
||||
|
@ -736,7 +736,8 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
|
||||
const TCollection_AsciiString& aShaderSrc = aShader->Source();
|
||||
|
||||
const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1;
|
||||
const bool hasFragColor = aShaderSrc.Search ("occFragColor") != -1
|
||||
const bool hasFragColor = aShaderSrc.Search ("occSetFragColor") != -1
|
||||
|| aShaderSrc.Search ("occFragColor") != -1
|
||||
|| aShaderSrc.Search ("gl_FragColor") != -1
|
||||
|| aShaderSrc.Search ("gl_FragData") != -1;
|
||||
Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg;
|
||||
@ -768,6 +769,13 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
|
||||
}
|
||||
}
|
||||
|
||||
if (!aProgram.IsNull()
|
||||
&& ViewerTest::CurrentView()->RenderingParams().TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
|
||||
{
|
||||
aProgram->SetNbFragmentOutputs (2);
|
||||
aProgram->SetWeightOitOutput (true);
|
||||
}
|
||||
|
||||
ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS());
|
||||
NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList);
|
||||
const bool isGlobalList = aPrsList.IsEmpty();
|
||||
|
Loading…
x
Reference in New Issue
Block a user