1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0032173: Visualization, TKOpenGl - implement simple shadow mapping for a point light source

Modified shadowmap calculations to include multipass for point lights.
Added shader funtions to calculate point light shadows.
Added getter for default znear and zfar values in Graphic3d_Camera.
Added direction and up vector calulations on Graphic3d_CubeMap.
Added logical exception for opengles2.0 lack of support on some key features of cube shadow maps.
Added test case.
This commit is contained in:
drochalo 2024-02-05 15:11:09 +00:00
parent 80705eaf31
commit 48f8f1e6ea
34 changed files with 726 additions and 153 deletions

View File

@ -150,7 +150,8 @@ void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast) void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast)
{ {
if (myType != Graphic3d_TypeOfLightSource_Directional if (myType != Graphic3d_TypeOfLightSource_Directional
&& myType != Graphic3d_TypeOfLightSource_Spot) && myType != Graphic3d_TypeOfLightSource_Spot
&& myType != Graphic3d_TypeOfLightSource_Positional)
{ {
throw Standard_NotImplemented ("Graphic3d_CLight::SetCastShadows() is not implemented for this light type"); throw Standard_NotImplemented ("Graphic3d_CLight::SetCastShadows() is not implemented for this light type");
} }

View File

@ -200,6 +200,24 @@ void Graphic3d_Camera::Copy (const Handle(Graphic3d_Camera)& theOther)
CopyOrientationData (theOther); CopyOrientationData (theOther);
} }
// =======================================================================
// function : GetDefaultZNear
// purpose :
// =======================================================================
Standard_Real Graphic3d_Camera::GetDefaultZNear()
{
return DEFAULT_ZNEAR;
}
// =======================================================================
// function : GetDefaultZFar
// purpose :
// =======================================================================
Standard_Real Graphic3d_Camera::GetDefaultZFar()
{
return DEFAULT_ZFAR;
}
// ======================================================================= // =======================================================================
// function : SetIdentityOrientation // function : SetIdentityOrientation
// purpose : // purpose :

View File

@ -202,6 +202,12 @@ public:
//! @name Public camera properties //! @name Public camera properties
public: public:
//! return default valut for znear.
Standard_EXPORT Standard_Real GetDefaultZNear();
//! return default valut for zfar.
Standard_EXPORT Standard_Real GetDefaultZFar();
//! Get camera look direction. //! Get camera look direction.
//! @return camera look direction. //! @return camera look direction.
const gp_Dir& Direction() const { return myDirection; } const gp_Dir& Direction() const { return myDirection; }

View File

@ -52,3 +52,89 @@ Graphic3d_CubeMap::~Graphic3d_CubeMap()
{ {
// //
} }
// =======================================================================
// function : GetCubeDirection
// purpose :
// =======================================================================
gp_Dir Graphic3d_CubeMap::GetCubeDirection (Graphic3d_CubeMapSide theFace)
{
gp_Dir aResult;
switch (theFace)
{
case (Graphic3d_CMS_POS_X):
{
aResult = gp_Dir(1.0, 0.0, 0.0);
}
break;
case (Graphic3d_CMS_NEG_X):
{
aResult = gp_Dir(-1.0, 0.0, 0.0);
}
break;
case (Graphic3d_CMS_POS_Y):
{
aResult = gp_Dir(0.0, 1.0, 0.0);
}
break;
case (Graphic3d_CMS_NEG_Y):
{
aResult = gp_Dir(0.0, -1.0, 0.0);
}
break;
case (Graphic3d_CMS_POS_Z):
{
aResult = gp_Dir(0.0, 0.0, 1.0);
}
break;
case (Graphic3d_CMS_NEG_Z):
{
aResult = gp_Dir(0.0, 0.0, -1.0);
}
break;
}
return aResult;
}
// =======================================================================
// function : GetCubeUp
// purpose :
// =======================================================================
gp_Dir Graphic3d_CubeMap::GetCubeUp (Graphic3d_CubeMapSide theFace)
{
gp_Dir aResult;
switch (theFace)
{
case (Graphic3d_CMS_POS_X):
{
aResult = -gp_Dir(0.0, -1.0, 0.0);
}
break;
case (Graphic3d_CMS_NEG_X):
{
aResult = -gp_Dir(0.0, -1.0, 0.0);
}
break;
case (Graphic3d_CMS_POS_Y):
{
aResult = gp_Dir(0.0, 0.0, 1.0);
}
break;
case (Graphic3d_CMS_NEG_Y):
{
aResult = gp_Dir(0.0, 0.0, -1.0);
}
break;
case (Graphic3d_CMS_POS_Z):
{
aResult = gp_Dir(0.0, -1.0, 0.0);
}
break;
case (Graphic3d_CMS_NEG_Z):
{
aResult = gp_Dir(0.0, -1.0, 0.0);
}
break;
}
return aResult;
}

View File

@ -15,6 +15,7 @@
#ifndef _Graphic3d_CubeMap_HeaderFile #ifndef _Graphic3d_CubeMap_HeaderFile
#define _Graphic3d_CubeMap_HeaderFile #define _Graphic3d_CubeMap_HeaderFile
#include <gp_Dir.hxx>
#include <Graphic3d_CubeMapOrder.hxx> #include <Graphic3d_CubeMapOrder.hxx>
#include <Graphic3d_TextureMap.hxx> #include <Graphic3d_TextureMap.hxx>
@ -90,6 +91,12 @@ public:
//! Empty destructor. //! Empty destructor.
Standard_EXPORT virtual ~Graphic3d_CubeMap(); Standard_EXPORT virtual ~Graphic3d_CubeMap();
//! Returns direction vector for cubemap's @theFace
Standard_EXPORT gp_Dir static GetCubeDirection (Graphic3d_CubeMapSide theFace);
//! Returns up vector for cubemap's @theFace
Standard_EXPORT gp_Dir static GetCubeUp (Graphic3d_CubeMapSide theFace);
protected: protected:
Graphic3d_CubeMapSide myCurrentSide; //!< Iterator state Graphic3d_CubeMapSide myCurrentSide; //!< Iterator state

View File

@ -86,6 +86,35 @@ Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& the
return Standard_True; return Standard_True;
} }
// =======================================================================
// function : CalculateNbShadows
// purpose :
// =======================================================================
void Graphic3d_LightSet::CalculateNbShadows (Standard_Integer& theNb2DShadows, Standard_Integer& theNbPointShadows)
{
theNb2DShadows = 0;
theNbPointShadows = 0;
for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter(myLights); aLightIter.More(); aLightIter.Next())
{
const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
//if (!aLight->IsEnabled())
//{
// continue;
//}
if (aLight->ToCastShadows())
{
if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
{
++theNbPointShadows;
}
else
{
++theNb2DShadows;
}
}
}
}
// ======================================================================= // =======================================================================
// function : UpdateRevision // function : UpdateRevision
// purpose : // purpose :

View File

@ -143,6 +143,9 @@ public:
//! Returns total amount of lights of specified type. //! Returns total amount of lights of specified type.
Standard_Integer NbLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypes[theType]; } Standard_Integer NbLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypes[theType]; }
//! Calculates total amount of enabled lights castings shadows (point lights and others).
Standard_EXPORT void CalculateNbShadows (Standard_Integer& theNb2DShadows, Standard_Integer& theNbPointShadows);
//! @name cached state of lights set updated by UpdateRevision() //! @name cached state of lights set updated by UpdateRevision()
public: public:

View File

@ -19,6 +19,7 @@
#include <Message.hxx> #include <Message.hxx>
#include "../Shaders/Shaders_LightShadow_glsl.pxx" #include "../Shaders/Shaders_LightShadow_glsl.pxx"
#include "../Shaders/Shaders_LightPointShadow_glsl.pxx"
#include "../Shaders/Shaders_PBRDistribution_glsl.pxx" #include "../Shaders/Shaders_PBRDistribution_glsl.pxx"
#include "../Shaders/Shaders_PBRDirectionalLight_glsl.pxx" #include "../Shaders/Shaders_PBRDirectionalLight_glsl.pxx"
#include "../Shaders/Shaders_PBRGeometry_glsl.pxx" #include "../Shaders/Shaders_PBRGeometry_glsl.pxx"
@ -516,6 +517,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramFont() con
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0); aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@ -645,6 +647,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramFboBlit (S
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0); aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@ -700,6 +703,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramOitComposi
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0); aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@ -1137,6 +1141,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramUnlit (Sta
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes); aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0); aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0; const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
@ -1152,10 +1157,11 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramUnlit (Sta
// ======================================================================= // =======================================================================
TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights, TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
const Handle(Graphic3d_LightSet)& theLights, const Handle(Graphic3d_LightSet)& theLights,
Standard_Boolean theHasVertColor, Standard_Boolean theHasVertColor,
Standard_Boolean theIsPBR, Standard_Boolean theIsPBR,
Standard_Boolean theHasTexColor, Standard_Boolean theHasTexColor,
Standard_Integer theNbShadowMaps) const Standard_Integer theNbShadowMaps,
Standard_Integer theNbShadowCubeMaps) const
{ {
TCollection_AsciiString aLightsFunc, aLightsLoop; TCollection_AsciiString aLightsFunc, aLightsLoop;
theNbLights = 0; theNbLights = 0;
@ -1165,6 +1171,8 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX) if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX)
{ {
Standard_Integer anIndex = 0; Standard_Integer anIndex = 0;
Standard_Integer a2DSamplerIndex = 0;
Standard_Integer aCubeSamplerIndex = 0;
for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
aLightIter.More(); aLightIter.Next()) aLightIter.More(); aLightIter.Next())
{ {
@ -1181,7 +1189,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
{ {
aLightsLoop = aLightsLoop + aLightsLoop = aLightsLoop +
EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront," EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront,"
EOL" occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));"; EOL" occLightShadow (occShadowMapSamplers[" + a2DSamplerIndex++ + "], " + anIndex + ", theNormal));";
} }
else else
{ {
@ -1192,7 +1200,18 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
} }
case Graphic3d_TypeOfLightSource_Positional: case Graphic3d_TypeOfLightSource_Positional:
{ {
aLightsLoop = aLightsLoop + EOL" occPointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);"; if (theNbShadowCubeMaps > 0
&& aLightIter.Value()->ToCastShadows())
{
aLightsLoop = aLightsLoop +
EOL" occPointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront,"
EOL" occLightPointShadow (occShadowCubeMapSamplers[" + aCubeSamplerIndex++ + "],"
EOL" " + anIndex + ", aPoint, theNormal)); ";
}
else
{
aLightsLoop = aLightsLoop + EOL" occPointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront, 1.0);";
}
++anIndex; ++anIndex;
break; break;
} }
@ -1203,7 +1222,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
{ {
aLightsLoop = aLightsLoop + aLightsLoop = aLightsLoop +
EOL" occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront," EOL" occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront,"
EOL" occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));"; EOL" occLightShadow (occShadowMapSamplers[" + a2DSamplerIndex++ + "], " + anIndex + ", theNormal));";
} }
else else
{ {
@ -1242,7 +1261,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
aLightsLoop += aLightsLoop +=
EOL" if (aType == OccLightType_Point)" EOL" if (aType == OccLightType_Point)"
EOL" {" EOL" {"
EOL" occPointLight (anIndex, theNormal, theView, aPoint, theIsFront);" EOL" occPointLight (anIndex, theNormal, theView, aPoint, theIsFront, 1.0);"
EOL" }"; EOL" }";
} }
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0) if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
@ -1271,6 +1290,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
} }
bool isShadowShaderAdded = false; bool isShadowShaderAdded = false;
bool isShadowCubeShaderAdded = false;
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) == 1 if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) == 1
&& theNbLights == 1 && theNbLights == 1
&& !theIsPBR && !theIsPBR
@ -1291,6 +1311,11 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
} }
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Positional) > 0) if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Positional) > 0)
{ {
if (theNbShadowCubeMaps > 0 && !isShadowCubeShaderAdded)
{
aLightsFunc += Shaders_LightPointShadow_glsl;
isShadowCubeShaderAdded = true;
}
aLightsFunc += theIsPBR ? Shaders_PBRPointLight_glsl : Shaders_PhongPointLight_glsl; aLightsFunc += theIsPBR ? Shaders_PBRPointLight_glsl : Shaders_PhongPointLight_glsl;
} }
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0) if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
@ -1475,7 +1500,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramGouraud (c
aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 BackColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT)); aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 BackColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
Standard_Integer aNbLights = 0; Standard_Integer aNbLights = 0;
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcVertColor.IsEmpty(), false, toUseTexColor, 0); const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcVertColor.IsEmpty(), false, toUseTexColor, 0, 0);
aSrcVert = TCollection_AsciiString() aSrcVert = TCollection_AsciiString()
+ THE_FUNC_transformNormal_world + THE_FUNC_transformNormal_world
+ EOL + EOL
@ -1520,6 +1545,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramGouraud (c
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (aNbLights); aProgramSrc->SetNbLightsMax (aNbLights);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes); aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0); aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0; const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
@ -1537,7 +1563,8 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
const Standard_Integer theBits, const Standard_Integer theBits,
const Standard_Boolean theIsFlatNormal, const Standard_Boolean theIsFlatNormal,
const Standard_Boolean theIsPBR, const Standard_Boolean theIsPBR,
const Standard_Integer theNbShadowMaps) const const Standard_Integer theNbShadowMaps,
const Standard_Integer theNbShadowCubeMaps) const
{ {
TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() + TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() +
"computeLighting (normalize (Normal), normalize (View), PositionWorld, gl_FrontFacing)"; "computeLighting (normalize (Normal), normalize (View), PositionWorld, gl_FrontFacing)";
@ -1690,12 +1717,18 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT)); aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 View", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT)); aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 View", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
if (theNbShadowMaps > 0) if (theNbShadowMaps + theNbShadowCubeMaps > 0)
{ {
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 occShadowMapMatrices[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX)); aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 occShadowMapMatrices[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX));
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("sampler2D occShadowMapSamplers[THE_NB_SHADOWMAPS]", Graphic3d_TOS_FRAGMENT)); aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 occShadowMapSizeBias", Graphic3d_TOS_FRAGMENT));
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 occShadowMapSizeBias", Graphic3d_TOS_FRAGMENT)); if (theNbShadowMaps > 0)
{
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("sampler2D occShadowMapSamplers[THE_NB_SHADOWMAPS2D]", Graphic3d_TOS_FRAGMENT));
}
if (theNbShadowCubeMaps > 0)
{
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("samplerCube occShadowCubeMapSamplers[THE_NB_SHADOWMAPSCUBE]", Graphic3d_TOS_FRAGMENT));
}
aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PosLightSpace[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT)); aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PosLightSpace[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
aSrcVertExtraMain += aSrcVertExtraMain +=
EOL" for (int aShadowIter = 0; aShadowIter < THE_NB_SHADOWMAPS; ++aShadowIter)" EOL" for (int aShadowIter = 0; aShadowIter < THE_NB_SHADOWMAPS; ++aShadowIter)"
@ -1729,7 +1762,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
Standard_Integer aNbLights = 0; Standard_Integer aNbLights = 0;
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcFragGetVertColor.IsEmpty(), const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcFragGetVertColor.IsEmpty(),
theIsPBR, toUseTexColor, theNbShadowMaps); theIsPBR, toUseTexColor, theNbShadowMaps, theNbShadowCubeMaps);
aSrcFrag += TCollection_AsciiString() aSrcFrag += TCollection_AsciiString()
+ EOL + EOL
+ aSrcFragGetVertColor + aSrcFragGetVertColor
@ -1745,11 +1778,12 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
+ EOL"}"; + EOL"}";
const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + (theIsPBR ? "pbr-" : "") const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + (theIsPBR ? "pbr-" : "")
+ genLightKey (theLights, theNbShadowMaps > 0) + "-"; + genLightKey (theLights, (theNbShadowMaps + theNbShadowCubeMaps) > 0) + "-";
defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal); defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal);
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (aNbLights); aProgramSrc->SetNbLightsMax (aNbLights);
aProgramSrc->SetNbShadowMaps (theNbShadowMaps); aProgramSrc->SetNbShadowMaps (theNbShadowMaps);
aProgramSrc->SetNbShadowCubeMaps (theNbShadowCubeMaps);
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes); aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0); aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
@ -1944,6 +1978,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramStereo (Gr
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0); aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@ -1980,6 +2015,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramBoundBox()
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0); aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@ -2041,6 +2077,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getPBREnvBakingProgram
aProgramSrc->SetDefaultSampler (false); aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0); aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0); aProgramSrc->SetNbShadowMaps (0);
aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0); aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@ -2107,6 +2144,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getBgCubeMapProgram() c
aProgSrc->SetDefaultSampler (false); aProgSrc->SetDefaultSampler (false);
aProgSrc->SetNbLightsMax (0); aProgSrc->SetNbLightsMax (0);
aProgSrc->SetNbShadowMaps (0); aProgSrc->SetNbShadowMaps (0);
aProgSrc->SetNbShadowCubeMaps (0);
aProgSrc->SetNbClipPlanesMax (0); aProgSrc->SetNbClipPlanesMax (0);
aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts)); aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts)); aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));

View File

@ -134,7 +134,8 @@ protected:
const Standard_Integer theBits, const Standard_Integer theBits,
const Standard_Boolean theIsFlatNormal, const Standard_Boolean theIsFlatNormal,
const Standard_Boolean theIsPBR, const Standard_Boolean theIsPBR,
const Standard_Integer theNbShadowMaps) const; const Standard_Integer theNbShadowMaps,
const Standard_Integer theNbShadowCubeMaps) const;
//! Prepare standard GLSL program for bounding box. //! Prepare standard GLSL program for bounding box.
Standard_EXPORT Handle(Graphic3d_ShaderProgram) getStdProgramBoundBox() const; Standard_EXPORT Handle(Graphic3d_ShaderProgram) getStdProgramBoundBox() const;
@ -207,10 +208,11 @@ protected:
//! @param theNbShadowMaps [in] flag to include shadow map //! @param theNbShadowMaps [in] flag to include shadow map
Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights, Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
const Handle(Graphic3d_LightSet)& theLights, const Handle(Graphic3d_LightSet)& theLights,
Standard_Boolean theHasVertColor, Standard_Boolean theHasVertColor,
Standard_Boolean theIsPBR, Standard_Boolean theIsPBR,
Standard_Boolean theHasTexColor, Standard_Boolean theHasTexColor,
Standard_Integer theNbShadowMaps) const; Standard_Integer theNbShadowMaps,
Standard_Integer theNbShadowCubeMaps) const;
protected: protected:

View File

@ -80,6 +80,7 @@ const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram() Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
: myNbLightsMax (THE_MAX_LIGHTS_DEFAULT), : myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
myNbShadowMaps (0), myNbShadowMaps (0),
myNbShadowCubeMaps (0),
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT), myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
myNbFragOutputs (THE_NB_FRAG_OUTPUTS), myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
myTextureSetBits (Graphic3d_TextureSetBits_NONE), myTextureSetBits (Graphic3d_TextureSetBits_NONE),

View File

@ -96,12 +96,18 @@ public:
//! Specify the length of array of light sources (THE_MAX_LIGHTS). //! Specify the length of array of light sources (THE_MAX_LIGHTS).
void SetNbLightsMax (Standard_Integer theNbLights) { myNbLightsMax = theNbLights; } void SetNbLightsMax (Standard_Integer theNbLights) { myNbLightsMax = theNbLights; }
//! Return the length of array of shadow maps (THE_NB_SHADOWMAPS); 0 by default. //! Return the length of array of 2D shadow maps (THE_NB_SHADOWMAP2D); 0 by default.
Standard_Integer NbShadowMaps() const { return myNbShadowMaps; } Standard_Integer NbShadowMaps() const { return myNbShadowMaps; }
//! Specify the length of array of shadow maps (THE_NB_SHADOWMAPS). //! Specify the length of array of 2D shadow maps (THE_NB_SHADOWMAP2D).
void SetNbShadowMaps (Standard_Integer theNbMaps) { myNbShadowMaps = theNbMaps; } void SetNbShadowMaps (Standard_Integer theNbMaps) { myNbShadowMaps = theNbMaps; }
//! Return the length of array of shadow cube maps (THE_NB_SHADOWMAPCUBE); 0 by default.
Standard_Integer NbShadowCubeMaps() const { return myNbShadowCubeMaps; }
//! Specify the length of array of shadow cube maps (THE_NB_SHADOWMAPCUBE).
void SetNbShadowCubeMaps (Standard_Integer theNbMaps) { myNbShadowCubeMaps = theNbMaps; }
//! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES), //! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
//! to be used for initialization occClipPlaneEquations. //! to be used for initialization occClipPlaneEquations.
//! Default value is THE_MAX_CLIP_PLANES_DEFAULT. //! Default value is THE_MAX_CLIP_PLANES_DEFAULT.
@ -214,20 +220,21 @@ public:
private: private:
TCollection_AsciiString myID; //!< the unique identifier of program object TCollection_AsciiString myID; //!< the unique identifier of program object
Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects
Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables
Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes
TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions 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 myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
Standard_Integer myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPS) Standard_Integer myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAP2D)
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES) Standard_Integer myNbShadowCubeMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPCUBE)
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS) Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
Standard_Integer myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs Standard_Integer myTextureSetBits; //!< texture units declared within the program, @sa Graphic3d_TextureSetBits
Standard_Boolean myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0 Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader performs alpha test Standard_Boolean myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
Standard_Boolean myIsPBR; //!< flag indicating that program defines functions and variables used in PBR pipeline Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader performs alpha test
Standard_Boolean myIsPBR; //!< flag indicating that program defines functions and variables used in PBR pipeline
}; };

View File

@ -67,6 +67,10 @@ enum Graphic3d_TextureUnit
//! Note that it can be overridden to Graphic3d_TextureUnit_0 for FFP fallback on hardware without multi-texturing. //! Note that it can be overridden to Graphic3d_TextureUnit_0 for FFP fallback on hardware without multi-texturing.
Graphic3d_TextureUnit_PointSprite = Graphic3d_TextureUnit_1, Graphic3d_TextureUnit_PointSprite = Graphic3d_TextureUnit_1,
//! samplerCube occShadowCubeMapSampler.
//! Point light source shadowmap texture.
Graphic3d_TextureUnit_ShadowCubeMap = -7,
//! sampler2D occDepthPeelingDepth. //! sampler2D occDepthPeelingDepth.
//! 1st texture unit for Depth Peeling lookups. //! 1st texture unit for Depth Peeling lookups.
Graphic3d_TextureUnit_DepthPeelingDepth = -6, Graphic3d_TextureUnit_DepthPeelingDepth = -6,

View File

@ -227,6 +227,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH), myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH),
myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_PbrIblSpecular), myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_PbrIblSpecular),
myShadowMapTexUnit (Graphic3d_TextureUnit_ShadowMap), myShadowMapTexUnit (Graphic3d_TextureUnit_ShadowMap),
myShadowCubeMapTexUnit (Graphic3d_TextureUnit_ShadowCubeMap),
myDepthPeelingDepthTexUnit (Graphic3d_TextureUnit_DepthPeelingDepth), myDepthPeelingDepthTexUnit (Graphic3d_TextureUnit_DepthPeelingDepth),
myDepthPeelingFrontColorTexUnit (Graphic3d_TextureUnit_DepthPeelingFrontColor), myDepthPeelingFrontColorTexUnit (Graphic3d_TextureUnit_DepthPeelingFrontColor),
myFrameStats (new OpenGl_FrameStats()), myFrameStats (new OpenGl_FrameStats()),
@ -1653,6 +1654,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
} }
} }
myShadowCubeMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowCubeMap); // -7
myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingDepth); // -6 myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingDepth); // -6
myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingFrontColor); // -5 myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingFrontColor); // -5
myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowMap); // -4 myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowMap); // -4
@ -1661,6 +1663,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular); // -1 myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular); // -1
if (!myHasPBR) if (!myHasPBR)
{ {
myShadowCubeMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowCubeMapTexUnit + 3);
myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingDepthTexUnit + 3); myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingDepthTexUnit + 3);
myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingFrontColorTexUnit + 3); myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingFrontColorTexUnit + 3);
myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowMapTexUnit + 3); myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowMapTexUnit + 3);

View File

@ -605,6 +605,9 @@ public:
//! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable. //! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable.
Graphic3d_TextureUnit ShadowMapTexUnit() const { return myShadowMapTexUnit; } Graphic3d_TextureUnit ShadowMapTexUnit() const { return myShadowMapTexUnit; }
//! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable.
Graphic3d_TextureUnit ShadowCubeMapTexUnit() const { return myShadowCubeMapTexUnit; }
//! Returns texture unit for occDepthPeelingDepth within enabled Depth Peeling. //! Returns texture unit for occDepthPeelingDepth within enabled Depth Peeling.
Graphic3d_TextureUnit DepthPeelingDepthTexUnit() const { return myDepthPeelingDepthTexUnit; } Graphic3d_TextureUnit DepthPeelingDepthTexUnit() const { return myDepthPeelingDepthTexUnit; }
@ -1137,6 +1140,7 @@ private: // context info
//! (0 if PBR is not supported) //! (0 if PBR is not supported)
Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit; //!< samplerCube occSpecIBLMap, texture unit where specular IBL map is expected to be binded (0 if PBR is not supported) Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit; //!< samplerCube occSpecIBLMap, texture unit where specular IBL map is expected to be binded (0 if PBR is not supported)
Graphic3d_TextureUnit myShadowMapTexUnit; //!< sampler2D occShadowMapSampler Graphic3d_TextureUnit myShadowMapTexUnit; //!< sampler2D occShadowMapSampler
Graphic3d_TextureUnit myShadowCubeMapTexUnit; //!< samplerCube occShadowCubeMapSampler
Graphic3d_TextureUnit myDepthPeelingDepthTexUnit; //!< sampler2D occDepthPeelingDepth, texture unit for Depth Peeling lookups Graphic3d_TextureUnit myDepthPeelingDepthTexUnit; //!< sampler2D occDepthPeelingDepth, texture unit for Depth Peeling lookups
Graphic3d_TextureUnit myDepthPeelingFrontColorTexUnit; //!< sampler2D occDepthPeelingFrontColor, texture unit for Depth Peeling lookups Graphic3d_TextureUnit myDepthPeelingFrontColorTexUnit; //!< sampler2D occDepthPeelingFrontColor, texture unit for Depth Peeling lookups

View File

@ -330,7 +330,8 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
const Graphic3d_Vec2i& theSize, const Graphic3d_Vec2i& theSize,
const OpenGl_ColorFormats& theColorFormats, const OpenGl_ColorFormats& theColorFormats,
const Standard_Integer theDepthFormat, const Standard_Integer theDepthFormat,
const Standard_Integer theNbSamples) const Standard_Integer theNbSamples,
const Standard_Boolean theIsCubeMap)
{ {
myColorFormats = theColorFormats; myColorFormats = theColorFormats;
@ -423,9 +424,10 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
// extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
// instead of just trying to create such texture // instead of just trying to create such texture
Graphic3d_TypeOfTexture aTypeOfTexture = theIsCubeMap ? Graphic3d_TypeOfTexture_CUBEMAP : Graphic3d_TypeOfTexture_2D;
const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, myDepthFormat); const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, myDepthFormat);
if (aDepthFormat.IsValid() if (aDepthFormat.IsValid()
&& !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TypeOfTexture_2D)) && !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), aTypeOfTexture))
{ {
theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
"Warning! Depth textures are not supported by hardware!"); "Warning! Depth textures are not supported by hardware!");
@ -470,15 +472,42 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
{ {
if (hasDepthStencilAttach (theGlContext)) if (hasDepthStencilAttach (theGlContext))
{ {
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, if (theIsCubeMap)
myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0); {
for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
{
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace),
myDepthStencilTexture->TextureId(), 0);
}
}
else
{
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
}
} }
else else
{ {
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, if (theIsCubeMap)
myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0); {
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0); {
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace),
myDepthStencilTexture->TextureId(), 0);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace),
myDepthStencilTexture->TextureId(), 0);
}
}
else
{
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
}
} }
} }
else if (myGlDepthRBufferId != NO_RENDERBUFFER) else if (myGlDepthRBufferId != NO_RENDERBUFFER)
@ -499,8 +528,17 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
} }
} }
} }
const GLenum aRendImgErr = theGlContext->core11fwd->glGetError();
if (aRendImgErr != GL_NO_ERROR)
{
theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
TCollection_AsciiString("Error: in setup of glFramebufferTexture2D: ") + OpenGl_Context::FormatGlError(aRendImgErr) + ".");
Release (theGlContext.get());
return Standard_False;
}
if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{ {
std::cout << "\n\nIncomplete framebuffer: " << theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) << "\n\n";
Release (theGlContext.operator->()); Release (theGlContext.operator->());
return Standard_False; return Standard_False;
} }
@ -907,6 +945,18 @@ void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId); theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId);
} }
// =======================================================================
// function : BindBufferCube
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::BindBufferCube (const Handle(OpenGl_Context)& theGlCtx, const Standard_Integer theFace)
{
theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId);
theGlCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theFace),
myDepthStencilTexture->TextureId(), 0);
}
// ======================================================================= // =======================================================================
// function : UnbindBuffer // function : UnbindBuffer
// purpose : // purpose :
@ -957,7 +1007,8 @@ inline void convertRowFromRgba (T* theRgbRow,
Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& theGlCtx, Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& theGlCtx,
const Handle(OpenGl_FrameBuffer)& theFbo, const Handle(OpenGl_FrameBuffer)& theFbo,
Image_PixMap& theImage, Image_PixMap& theImage,
Graphic3d_BufferType theBufferType) Graphic3d_BufferType theBufferType,
const Standard_Integer theCubeFace)
{ {
if (theGlCtx.IsNull() if (theGlCtx.IsNull()
|| theImage.IsEmpty()) || theImage.IsEmpty())
@ -1119,6 +1170,38 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
return Standard_False; return Standard_False;
} }
if (theCubeFace >= 0)
{
theGlCtx->core11fwd->glBindTexture (GL_TEXTURE_CUBE_MAP, theFbo->DepthStencilTexture()->TextureId());
theFbo->BindBufferCube (theGlCtx, theCubeFace);
const GLint anAligment = Min(GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
if (theGlCtx->hasPackRowLength)
{
theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0);
}
theGlCtx->core11fwd->glGetTexImage (GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theCubeFace),
0, aFormat, aType, theImage.ChangeData());
const bool hasErrors = theGlCtx->ResetErrors (true);
if (hasErrors)
{
std::cout << "\nError saving cubemap face texture to image.\n";
return Standard_False;
}
theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1);
if (!theFbo.IsNull() && theFbo->IsValid())
{
theFbo->UnbindBuffer(theGlCtx);
}
else if (theGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES)
{
theGlCtx->core11fwd->glReadBuffer(aReadBufferPrev);
}
return Standard_True;
}
// bind FBO if used // bind FBO if used
if (!theFbo.IsNull() && theFbo->IsValid()) if (!theFbo.IsNull() && theFbo->IsValid())
{ {

View File

@ -48,11 +48,13 @@ public:
//! @param theFbo FBO to dump (or window buffer, if NULL) //! @param theFbo FBO to dump (or window buffer, if NULL)
//! @param theImage target image //! @param theImage target image
//! @param theBufferType buffer type (attachment) to dump //! @param theBufferType buffer type (attachment) to dump
//! @param theCubeFace id of the cubemap face (only used for fbo's rendering to cubemaps)
//! @return TRUE on success //! @return TRUE on success
Standard_EXPORT static Standard_Boolean BufferDump (const Handle(OpenGl_Context)& theGlCtx, Standard_EXPORT static Standard_Boolean BufferDump (const Handle(OpenGl_Context)& theGlCtx,
const Handle(OpenGl_FrameBuffer)& theFbo, const Handle(OpenGl_FrameBuffer)& theFbo,
Image_PixMap& theImage, Image_PixMap& theImage,
Graphic3d_BufferType theBufferType); Graphic3d_BufferType theBufferType,
const Standard_Integer theCubeFace = -1);
public: public:
@ -142,12 +144,14 @@ public:
//! @param theColorFormats list of color texture sized format (0 means no color attachment), e.g. GL_RGBA8 //! @param theColorFormats list of color texture sized format (0 means no color attachment), e.g. GL_RGBA8
//! @param theDepthFormat depth-stencil texture sized format (0 means no depth attachment), e.g. GL_DEPTH24_STENCIL8 //! @param theDepthFormat depth-stencil texture sized format (0 means no depth attachment), e.g. GL_DEPTH24_STENCIL8
//! @param theNbSamples MSAA number of samples (0 means normal texture) //! @param theNbSamples MSAA number of samples (0 means normal texture)
//! @param theIsCubeMap flag to setup texture target to cubemap (FALSE by default)
//! @return true on success //! @return true on success
Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx, Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
const Graphic3d_Vec2i& theSize, const Graphic3d_Vec2i& theSize,
const OpenGl_ColorFormats& theColorFormats, const OpenGl_ColorFormats& theColorFormats,
const Standard_Integer theDepthFormat, const Standard_Integer theDepthFormat,
const Standard_Integer theNbSamples = 0); const Standard_Integer theNbSamples = 0,
const Standard_Boolean theIsCubeMap = Standard_False);
//! (Re-)initialize FBO with specified dimensions. //! (Re-)initialize FBO with specified dimensions.
Standard_EXPORT Standard_Boolean InitLazy (const Handle(OpenGl_Context)& theGlCtx, Standard_EXPORT Standard_Boolean InitLazy (const Handle(OpenGl_Context)& theGlCtx,
@ -225,6 +229,9 @@ public:
//! Bind frame buffer for reading GL_READ_FRAMEBUFFER //! Bind frame buffer for reading GL_READ_FRAMEBUFFER
Standard_EXPORT virtual void BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx); Standard_EXPORT virtual void BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx);
//! Bind frame buffer for reading cubemap with the target @theFace.
Standard_EXPORT virtual void BindBufferCube (const Handle(OpenGl_Context)& theGlCtx, const Standard_Integer theFace);
//! Unbind frame buffer. //! Unbind frame buffer.
Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx); Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);

View File

@ -554,9 +554,10 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
// update shadow map variables // update shadow map variables
if (const OpenGl_ShaderUniformLocation aShadowMatLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES)) if (const OpenGl_ShaderUniformLocation aShadowMatLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES))
{ {
if (myShadowMatArray.Size() < theProgram->NbShadowMaps()) Standard_Integer aNbShadowMaps = theProgram->NbShadowMaps() + theProgram->NbShadowCubeMaps();
if (myShadowMatArray.Size() < aNbShadowMaps)
{ {
myShadowMatArray.Resize (0, theProgram->NbShadowMaps() - 1, false); myShadowMatArray.Resize (0, aNbShadowMaps - 1, false);
} }
Graphic3d_Vec2 aSizeBias; Graphic3d_Vec2 aSizeBias;
@ -564,7 +565,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
{ {
aSizeBias.SetValues (1.0f / (float )myLightSourceState.ShadowMaps()->First()->Texture()->SizeX(), aSizeBias.SetValues (1.0f / (float )myLightSourceState.ShadowMaps()->First()->Texture()->SizeX(),
myLightSourceState.ShadowMaps()->First()->ShadowMapBias()); myLightSourceState.ShadowMaps()->First()->ShadowMapBias());
const Standard_Integer aNbShadows = Min (theProgram->NbShadowMaps(), myLightSourceState.ShadowMaps()->Size()); const Standard_Integer aNbShadows = Min (aNbShadowMaps, myLightSourceState.ShadowMaps()->Size());
for (Standard_Integer aShadowIter = 0; aShadowIter < aNbShadows; ++aShadowIter) for (Standard_Integer aShadowIter = 0; aShadowIter < aNbShadows; ++aShadowIter)
{ {
const Handle(OpenGl_ShadowMap)& aShadow = myLightSourceState.ShadowMaps()->Value (aShadowIter); const Handle(OpenGl_ShadowMap)& aShadow = myLightSourceState.ShadowMaps()->Value (aShadowIter);
@ -572,7 +573,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
} }
} }
theProgram->SetUniform (myContext, aShadowMatLoc, theProgram->NbShadowMaps(), &myShadowMatArray.First()); theProgram->SetUniform (myContext, aShadowMatLoc, aNbShadowMaps, &myShadowMatArray.First());
theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS), aSizeBias); theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS), aSizeBias);
} }
} }
@ -1229,10 +1230,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
const Standard_Boolean theIsFlatNormal, const Standard_Boolean theIsFlatNormal,
const Standard_Boolean theIsPBR) const Standard_Boolean theIsPBR)
{ {
Standard_Integer aNbShadowMaps = myLightSourceState.HasShadowMaps() Standard_Integer aNbShadowMaps, aNbShadowCubeMaps;
? myLightSourceState.LightSources()->NbCastShadows() myLightSourceState.LightSources()->CalculateNbShadows (aNbShadowMaps, aNbShadowCubeMaps);
: 0; // point light shadows are not currently supported on opengles 2.0.
Handle(Graphic3d_ShaderProgram) aProgramSrc = getStdProgramPhong (myLightSourceState.LightSources(), theBits, theIsFlatNormal, theIsPBR, aNbShadowMaps); if (myContext->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES
&& myContext->VersionMajor() <= 2)
{
aNbShadowCubeMaps = 0;
}
Handle(Graphic3d_ShaderProgram) aProgramSrc = getStdProgramPhong (myLightSourceState.LightSources(), theBits, theIsFlatNormal,
theIsPBR, aNbShadowMaps, aNbShadowCubeMaps);
TCollection_AsciiString aKey; TCollection_AsciiString aKey;
if (!Create (aProgramSrc, aKey, theProgram)) if (!Create (aProgramSrc, aKey, theProgram))
{ {

View File

@ -50,43 +50,44 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
"occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
"occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
"occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
"occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
"occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
"occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
"occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
"occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
"occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
"occShadowMapSizeBias", // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS "occShadowMapSizeBias", // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS
"occShadowMapSamplers", // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, "occShadowMapSamplers", // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,
"occShadowMapMatrices", // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, "occShadowCubeMapSamplers", // OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS,
"occShadowMapMatrices", // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,
"occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
"occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
"occPbrMaterial", // OpenGl_OCCT_PBR_MATERIAL "occPbrMaterial", // OpenGl_OCCT_PBR_MATERIAL
"occCommonMaterial", // OpenGl_OCCT_COMMON_MATERIAL "occCommonMaterial", // OpenGl_OCCT_COMMON_MATERIAL
"occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
"occColor", // OpenGl_OCCT_COLOR "occColor", // OpenGl_OCCT_COLOR
"occOitOutput", // OpenGl_OCCT_OIT_OUTPUT "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
"occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
"occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
"occPointSize", // OpenGl_OCCT_POINT_SIZE "occPointSize", // OpenGl_OCCT_POINT_SIZE
"occViewport", // OpenGl_OCCT_VIEWPORT "occViewport", // OpenGl_OCCT_VIEWPORT
"occLineWidth", // OpenGl_OCCT_LINE_WIDTH "occLineWidth", // OpenGl_OCCT_LINE_WIDTH
"occLineFeather", // OpenGl_OCCT_LINE_FEATHER "occLineFeather", // OpenGl_OCCT_LINE_FEATHER
"occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN "occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
"occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR "occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
"occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
"occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
"occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
"occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
"occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS "occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
}; };
namespace namespace
@ -165,6 +166,7 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
myShareCount(1), myShareCount(1),
myNbLightsMax (0), myNbLightsMax (0),
myNbShadowMaps (0), myNbShadowMaps (0),
myNbShadowCubeMaps (0),
myNbClipPlanesMax (0), myNbClipPlanesMax (0),
myNbFragOutputs (1), myNbFragOutputs (1),
myTextureSetBits (Graphic3d_TextureSetBits_NONE), myTextureSetBits (Graphic3d_TextureSetBits_NONE),
@ -419,15 +421,24 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
} }
TCollection_AsciiString aHeaderConstants; TCollection_AsciiString aHeaderConstants;
myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0; myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
myNbShadowMaps = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 0; myNbShadowMaps = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 0;
myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0; myNbShadowCubeMaps = !myProxy.IsNull() ? myProxy->NbShadowCubeMaps() : 0;
myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n"; aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n"; aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n"; aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
if (myNbShadowMaps + myNbShadowCubeMaps > 0)
{
aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS ") + (myNbShadowMaps + myNbShadowCubeMaps) + "\n";
}
if (myNbShadowMaps > 0) if (myNbShadowMaps > 0)
{ {
aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS ") + myNbShadowMaps + "\n"; aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS2D ") + myNbShadowMaps + "\n";
}
if (myNbShadowCubeMaps > 0)
{
aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPSCUBE ") + myNbShadowCubeMaps + "\n";
} }
if (theCtx->caps->useZeroToOneDepth if (theCtx->caps->useZeroToOneDepth
&& theCtx->arbClipControl) && theCtx->arbClipControl)
@ -590,7 +601,16 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
} }
SetUniform (theCtx, aLocSampler, myNbShadowMaps, &aShadowSamplers.front()); SetUniform (theCtx, aLocSampler, myNbShadowMaps, &aShadowSamplers.front());
} }
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occShadowCubeMapSamplers"))
{
std::vector<GLint> aShadowSamplers (myNbShadowCubeMaps);
const GLint aSamplFrom = GLint(theCtx->ShadowCubeMapTexUnit()) - myNbShadowCubeMaps + 1;
for (Standard_Integer aSamplerIter = 0; aSamplerIter < myNbShadowCubeMaps; ++aSamplerIter)
{
aShadowSamplers[aSamplerIter] = aSamplFrom + aSamplerIter;
}
SetUniform (theCtx, aLocSampler, myNbShadowCubeMaps, &aShadowSamplers.front());
}
if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDepthPeelingDepth")) if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDepthPeelingDepth"))
{ {
SetUniform (theCtx, aLocSampler, GLint(theCtx->DepthPeelingDepthTexUnit())); SetUniform (theCtx, aLocSampler, GLint(theCtx->DepthPeelingDepthTexUnit()));

View File

@ -57,9 +57,10 @@ enum OpenGl_StateVariable
OpenGl_OCC_LIGHT_SOURCE_TYPES, OpenGl_OCC_LIGHT_SOURCE_TYPES,
OpenGl_OCC_LIGHT_SOURCE_PARAMS, OpenGl_OCC_LIGHT_SOURCE_PARAMS,
OpenGl_OCC_LIGHT_AMBIENT, OpenGl_OCC_LIGHT_AMBIENT,
OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS,// occShadowMapSizeBias OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS, // occShadowMapSizeBias
OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, // occShadowMapSamplers OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, // occShadowMapSamplers
OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, // occShadowMapMatrices OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS, // occShadowCubeMapSamplers
OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, // occShadowMapMatrices
// Material state // Material state
OpenGl_OCCT_TEXTURE_ENABLE, OpenGl_OCCT_TEXTURE_ENABLE,
@ -283,9 +284,12 @@ public:
//! to be used for initialization occLightSources (OpenGl_OCC_LIGHT_SOURCE_PARAMS). //! to be used for initialization occLightSources (OpenGl_OCC_LIGHT_SOURCE_PARAMS).
Standard_Integer NbLightsMax() const { return myNbLightsMax; } Standard_Integer NbLightsMax() const { return myNbLightsMax; }
//! Return the length of array of shadow maps (THE_NB_SHADOWMAPS); 0 by default. //! Return the length of array of 2D shadow maps (THE_NB_SHADOWMAP2D); 0 by default.
Standard_Integer NbShadowMaps() const { return myNbShadowMaps; } Standard_Integer NbShadowMaps() const { return myNbShadowMaps; }
//! Return the length of array of shadow cube maps (THE_NB_SHADOWMAPCUBE); 0 by default.
Standard_Integer NbShadowCubeMaps() const { return myNbShadowCubeMaps; }
//! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES), //! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
//! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS). //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS).
Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; } Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
@ -643,18 +647,19 @@ protected:
protected: protected:
GLuint myProgramID; //!< Handle of OpenGL shader program GLuint myProgramID; //!< Handle of OpenGL shader program
OpenGl_ShaderList myShaderObjects; //!< List of attached shader objects OpenGl_ShaderList myShaderObjects; //!< List of attached shader objects
Handle(Graphic3d_ShaderProgram) myProxy; //!< Proxy shader program (from application layer) Handle(Graphic3d_ShaderProgram) myProxy; //!< Proxy shader program (from application layer)
Standard_Integer myShareCount; //!< program users count, initialized with 1 (already shared by one user) 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 myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
Standard_Integer myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPS) Standard_Integer myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAP2D)
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES) Standard_Integer myNbShadowCubeMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPCUBE)
Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS) Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
Standard_Integer myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits Standard_Integer myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs Standard_Integer myTextureSetBits; //!< texture units declared within the program, @sa Graphic3d_TextureSetBits
Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader should perform alpha-test Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader should perform alpha-test
Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage
protected: protected:

View File

@ -83,7 +83,8 @@ const Handle(OpenGl_Texture)& OpenGl_ShadowMap::Texture() const
// purpose : // purpose :
// ======================================================================= // =======================================================================
bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView, bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView,
const gp_XYZ* theOrigin) const gp_XYZ* theOrigin,
const Standard_Integer theFace)
{ {
const Bnd_Box aMinMaxBox = theOrigin == NULL ? theView.MinMaxValues (false) : Bnd_Box(); // applicative min max boundaries const Bnd_Box aMinMaxBox = theOrigin == NULL ? theView.MinMaxValues (false) : Bnd_Box(); // applicative min max boundaries
const Bnd_Box aGraphicBox = aMinMaxBox; const Bnd_Box aGraphicBox = aMinMaxBox;
@ -134,7 +135,19 @@ bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView,
case Graphic3d_TypeOfLightSource_Positional: case Graphic3d_TypeOfLightSource_Positional:
{ {
// render into cubemap shadowmap texture // render into cubemap shadowmap texture
return false; // not implemented myShadowCamera->SetZeroToOneDepth (theView.Camera()->IsZeroToOneDepth());
myShadowCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
myShadowCamera->SetFOVy (90.0);
const gp_Pnt& aLightPos = myShadowLight->Position();
myShadowCamera->MoveEyeTo (aLightPos);
// calculate direction and up vector for the given cubemap face
myShadowCamera->SetDirectionFromEye (Graphic3d_CubeMap::GetCubeDirection ((Graphic3d_CubeMapSide)theFace));
myShadowCamera->SetUp (Graphic3d_CubeMap::GetCubeUp ((Graphic3d_CubeMapSide)theFace));
// setup znear and zfar (default value)
myShadowCamera->SetZRange (1.0, myShadowCamera->GetDefaultZFar());
myLightMatrix = myShadowCamera->ProjectionMatrixF() * myShadowCamera->OrientationMatrixF();
return true;
} }
case Graphic3d_TypeOfLightSource_Spot: case Graphic3d_TypeOfLightSource_Spot:
{ {

View File

@ -76,8 +76,10 @@ public:
//! Compute camera. //! Compute camera.
//! @param theView [in] active view //! @param theView [in] active view
//! @param theOrigin [in] when not-NULL - displace shadow map camera to specified Z-Layer origin //! @param theOrigin [in] when not-NULL - displace shadow map camera to specified Z-Layer origin
//! @param theFace [in] if light is point light calculate for given cubemap face index
Standard_EXPORT bool UpdateCamera (const Graphic3d_CView& theView, Standard_EXPORT bool UpdateCamera (const Graphic3d_CView& theView,
const gp_XYZ* theOrigin = NULL); const gp_XYZ* theOrigin = NULL,
const Standard_Integer theFace = -1);
private: private:

View File

@ -443,7 +443,6 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
return false; return false;
} }
} }
theCtx->core11fwd->glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat, theCtx->core11fwd->glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
theSizeXYZ.x(), theSizeXYZ.y(), 0, theSizeXYZ.x(), theSizeXYZ.y(), 0,
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
@ -520,9 +519,48 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
} }
case Graphic3d_TypeOfTexture_CUBEMAP: case Graphic3d_TypeOfTexture_CUBEMAP:
{ {
Unbind (theCtx); Bind (theCtx);
Release (theCtx.get()); applyDefaultSamplerParams (theCtx);
return false; if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGL)
{
// use proxy to check texture could be created or not
theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
theSizeXYZ.x(), theSizeXYZ.y(), 0,
theFormat.PixelFormat(), theFormat.DataType(), NULL);
theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestWidth == 0 || aTestHeight == 0)
{
// no memory or broken input parameters
Unbind(theCtx);
Release(theCtx.get());
return false;
}
}
for (Standard_Integer aCubeIndex = 0; aCubeIndex < 6; ++aCubeIndex)
{
theCtx->core11fwd->glTexImage2D (GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeIndex), 0, anIntFormat,
theSizeXYZ.x(), theSizeXYZ.y(), 0,
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
GLenum anErr = theCtx->core11fwd->glGetError();
if (anErr != GL_NO_ERROR)
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
TCollection_AsciiString ("Error: Cubemap texture ") + theSizeXYZ.x() + "x" + theSizeXYZ.y()
+ " IF: " + OpenGl_TextureFormat::FormatFormat (anIntFormat)
+ " PF: " + OpenGl_TextureFormat::FormatFormat (theFormat.PixelFormat())
+ " DT: " + OpenGl_TextureFormat::FormatDataType (theFormat.DataType())
+ " can not be created with error " + OpenGl_Context::FormatGlError (anErr)
+ " [" + myResourceId + "]");
Unbind (theCtx);
Release (theCtx.get());
return false;
}
}
mySize.SetValues (theSizeXYZ.xy(), 1);
break;
} }
} }

View File

@ -1583,31 +1583,73 @@ bool OpenGl_View::prepareFrameBuffers (Graphic3d_Camera::Projection& theProj)
&& myRenderParams.Method != Graphic3d_RM_RAYTRACING; && myRenderParams.Method != Graphic3d_RM_RAYTRACING;
if (toUseShadowMap) if (toUseShadowMap)
{ {
Standard_Integer aNbShadows = 0;
Standard_Integer aNbPointShadows = 0;
Standard_Boolean aToReviewLights = Standard_False;
for (Graphic3d_LightSet::Iterator aLightIter(myLights); aLightIter.More(); aLightIter.Next())
{
Handle(Graphic3d_CLight) aLight = aLightIter.Value();
if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
{
// point lights shadows are not currently supported on opengles 2.0
if (aCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES
&& aCtx->VersionMajor() <= 2)
{
aLight->SetCastShadows (Standard_False);
aToReviewLights = Standard_True;
}
else if (aLight->ToCastShadows())
{
++aNbPointShadows;
}
}
else
{
if (aLight->ToCastShadows())
{
++aNbShadows;
}
}
}
if (aToReviewLights)
{
myLights->UpdateRevision();
}
if (myShadowMaps->Size() != myLights->NbCastShadows()) if (myShadowMaps->Size() != myLights->NbCastShadows())
{ {
myShadowMaps->Release (aCtx.get()); myShadowMaps->Release (aCtx.get());
myShadowMaps->Resize (0, myLights->NbCastShadows() - 1, true); myShadowMaps->Resize (0, myLights->NbCastShadows() - 1, true);
} }
const GLint aSampleFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + aNbPointShadows + 1;
const GLint aSamplFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + 1; const GLint aSampleCubeFrom = GLint(aCtx->ShadowCubeMapTexUnit()) - aNbPointShadows + 1;
for (Standard_Integer aShadowIter = 0; aShadowIter < myShadowMaps->Size(); ++aShadowIter) Standard_Integer aLightIndex = 0;
Standard_Integer a2DShadowIndex = 0;
Standard_Integer aCubeShadowIndex = 0;
for (Graphic3d_LightSet::Iterator aLightIter(myLights); aLightIter.More(); aLightIter.Next())
{ {
Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue (aShadowIter); Handle(Graphic3d_CLight) aLight = aLightIter.Value();
if (aShadow.IsNull()) if (aLight->ToCastShadows())
{ {
aShadow = new OpenGl_ShadowMap(); Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue (aLightIndex++);
} if (aShadow.IsNull())
aShadow->SetShadowMapBias (myRenderParams.ShadowMapBias);
aShadow->Texture()->Sampler()->Parameters()->SetTextureUnit ((Graphic3d_TextureUnit )(aSamplFrom + aShadowIter));
const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer();
if (aShadowFbo->GetVPSizeX() != myRenderParams.ShadowMapResolution
&& toUseShadowMap)
{
OpenGl_ColorFormats aDummy;
if (!aShadowFbo->Init (aCtx, Graphic3d_Vec2i (myRenderParams.ShadowMapResolution), aDummy, myFboDepthFormat, 0))
{ {
toUseShadowMap = false; aShadow = new OpenGl_ShadowMap();
}
aShadow->SetShadowMapBias (myRenderParams.ShadowMapBias);
Standard_Integer aTexUnit = aLight->Type() == Graphic3d_TypeOfLightSource_Positional
? aSampleCubeFrom + aCubeShadowIndex++
: aSampleFrom + a2DShadowIndex++;
aShadow->Texture()->Sampler()->Parameters()->SetTextureUnit ((Graphic3d_TextureUnit)(aTexUnit));
const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer();
if (aShadowFbo->GetVPSizeX() != myRenderParams.ShadowMapResolution
&& toUseShadowMap)
{
OpenGl_ColorFormats aDummy;
if (!aShadowFbo->Init (aCtx, Graphic3d_Vec2i(myRenderParams.ShadowMapResolution), aDummy, myFboDepthFormat, 0,
aLight->Type() == Graphic3d_TypeOfLightSource_Positional))
{
toUseShadowMap = false;
}
} }
} }
} }
@ -1688,7 +1730,22 @@ void OpenGl_View::Redraw()
{ {
const Handle(OpenGl_ShadowMap)& aShadowMap = myShadowMaps->ChangeValue (aShadowIndex); const Handle(OpenGl_ShadowMap)& aShadowMap = myShadowMaps->ChangeValue (aShadowIndex);
aShadowMap->SetLightSource (aLight); aShadowMap->SetLightSource (aLight);
renderShadowMap (aShadowMap); if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
{
// point light shadows are not currently supported on opengles 2.0.
if (aCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES
|| aCtx->VersionMajor() >= 3)
{
for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
{
renderShadowMap (aShadowMap, aCubeFace);
}
}
}
else
{
renderShadowMap (aShadowMap, -1);
}
++aShadowIndex; ++aShadowIndex;
} }
} }
@ -2297,10 +2354,11 @@ bool OpenGl_View::blitSubviews (const Graphic3d_Camera::Projection ,
//function : renderShadowMap //function : renderShadowMap
//purpose : //purpose :
//======================================================================= //=======================================================================
void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap) void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap,
const Standard_Integer theFace)
{ {
const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
if (!theShadowMap->UpdateCamera (*this)) if (!theShadowMap->UpdateCamera (*this, NULL, theFace))
{ {
return; return;
} }
@ -2319,7 +2377,14 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
aCtx->ShaderManager()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit); aCtx->ShaderManager()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
const Handle(OpenGl_FrameBuffer)& aShadowBuffer = theShadowMap->FrameBuffer(); const Handle(OpenGl_FrameBuffer)& aShadowBuffer = theShadowMap->FrameBuffer();
aShadowBuffer->BindBuffer (aCtx); if (theFace < 0)
{
aShadowBuffer->BindBuffer (aCtx);
}
else
{
aShadowBuffer->BindBufferCube (aCtx, theFace);
}
aShadowBuffer->SetupViewport (aCtx); aShadowBuffer->SetupViewport (aCtx);
aCtx->SetColorMask (false); aCtx->SetColorMask (false);
@ -2329,9 +2394,9 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
myWorkspace->UseZBuffer() = true; myWorkspace->UseZBuffer() = true;
myWorkspace->UseDepthWrite() = true; myWorkspace->UseDepthWrite() = true;
aCtx->core11fwd->glDepthFunc (GL_LEQUAL); aCtx->core11fwd->glDepthFunc (GL_LEQUAL);
aCtx->core11fwd->glDepthMask (GL_TRUE);
aCtx->core11fwd->glEnable (GL_DEPTH_TEST); aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
aCtx->core11fwd->glClearDepth (1.0); aCtx->core11fwd->glClearDepth (1.0);
aCtx->core11fwd->glDepthMask (GL_TRUE);
aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT); aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
Graphic3d_Camera::Projection aProjection = theShadowMap->LightSource()->Type() == Graphic3d_TypeOfLightSource_Directional Graphic3d_Camera::Projection aProjection = theShadowMap->LightSource()->Type() == Graphic3d_TypeOfLightSource_Directional
@ -2345,10 +2410,9 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
myWorkspace->ResetAppliedAspect(); myWorkspace->ResetAppliedAspect();
aCtx->BindProgram (Handle(OpenGl_ShaderProgram)()); aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
//Image_AlienPixMap anImage; anImage.InitZero (Image_Format_Gray, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY()); //Image_AlienPixMap anImage; anImage.InitZero (Image_Format_GrayF, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY());
//OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth); //OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth);
//anImage.Save (TCollection_AsciiString ("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png"); //anImage.Save (TCollection_AsciiString("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png");
bindDefaultFbo(); bindDefaultFbo();
} }

View File

@ -354,7 +354,9 @@ protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
//! Renders the graphical contents of the view into the preprepared shadowmap framebuffer. //! Renders the graphical contents of the view into the preprepared shadowmap framebuffer.
//! @param theShadowMap [in] the framebuffer for rendering shadowmap. //! @param theShadowMap [in] the framebuffer for rendering shadowmap.
Standard_EXPORT virtual void renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap); //! @param theFace [in] value for cubemap face.
Standard_EXPORT virtual void renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap,
const Standard_Integer theFace);
//! Renders the graphical contents of the view into the preprepared window or framebuffer. //! Renders the graphical contents of the view into the preprepared window or framebuffer.
//! @param theProjection [in] the projection that should be used for rendering. //! @param theProjection [in] the projection that should be used for rendering.

View File

@ -113,6 +113,10 @@
#define INV_PI 0.318309886 #define INV_PI 0.318309886
#define INV_PI_2 0.159154943 #define INV_PI_2 0.159154943
// Point light depth range values
#define POINTLIGHT_ZNEAR 1.0
#define POINTLIGHT_ZFAR 3000.0
// Matrix state // Matrix state
uniform mat4 occWorldViewMatrix; //!< World-view matrix uniform mat4 occWorldViewMatrix; //!< World-view matrix
uniform mat4 occProjectionMatrix; //!< Projection matrix uniform mat4 occProjectionMatrix; //!< Projection matrix

View File

@ -1,6 +1,7 @@
srcinc:::Declarations.glsl srcinc:::Declarations.glsl
srcinc:::DeclarationsImpl.glsl srcinc:::DeclarationsImpl.glsl
srcinc:::LightShadow.glsl srcinc:::LightShadow.glsl
srcinc:::LightPointShadow.glsl
srcinc:::PBRCookTorrance.glsl srcinc:::PBRCookTorrance.glsl
srcinc:::PBRDirectionalLight.glsl srcinc:::PBRDirectionalLight.glsl
srcinc:::PBRDistribution.glsl srcinc:::PBRDistribution.glsl
@ -28,6 +29,7 @@ srcinc:::SkydomBackground.fs
Shaders_Declarations_glsl.pxx Shaders_Declarations_glsl.pxx
Shaders_DeclarationsImpl_glsl.pxx Shaders_DeclarationsImpl_glsl.pxx
Shaders_LightShadow_glsl.pxx Shaders_LightShadow_glsl.pxx
Shaders_LightPointShadow_glsl.pxx
Shaders_Display_fs.pxx Shaders_Display_fs.pxx
Shaders_PBRCookTorrance_glsl.pxx Shaders_PBRCookTorrance_glsl.pxx
Shaders_PBRDirectionalLight_glsl.pxx Shaders_PBRDirectionalLight_glsl.pxx

View File

@ -0,0 +1,24 @@
//! Function computes point light shadow attenuation (1.0 means no shadow).
float occLightPointShadow (in samplerCube theShadow,
//in vec2 theDepthRange,
in int theId,
in vec3 thePoint,
in vec3 theNormal)
{
vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];
vec3 aLightDir = thePoint - occLight_Position (theId);
// convert light-to-fragment vector to a depth value.
vec3 anAbsVec = abs (aLightDir);
float aLocalZcomp = max (anAbsVec.x, max (anAbsVec.y, anAbsVec.z));
// set znear and zfar
float aNear = POINTLIGHT_ZNEAR;
float aFar = POINTLIGHT_ZFAR;
float aNormZComp = (aFar + aNear) / (aFar - aNear) - (2.0 * aFar * aNear) / (aFar - aNear) / aLocalZcomp;
float aDist = (aNormZComp + 1.0) * 0.5;
// calculate bias and test depth.
aLightDir = normalize (aLightDir);
float aBias = min (occShadowMapSizeBias.y * (1.0 - dot (theNormal, aLightDir)), occShadowMapSizeBias.y * 0.1);
float aClosestDepth = occTextureCube (theShadow, aLightDir).r;
float aShadow = (aDist - aBias) > aClosestDepth ? 1.0 : 0.0;
return 1.0 - aShadow;
}

View File

@ -9,7 +9,8 @@ void occPointLight (in int theId,
in vec3 theNormal, in vec3 theNormal,
in vec3 theView, in vec3 theView,
in vec3 thePoint, in vec3 thePoint,
in bool theIsFront) in bool theIsFront,
in float theShadow)
{ {
vec3 aLight = occLight_Position (theId) - thePoint; vec3 aLight = occLight_Position (theId) - thePoint;
@ -23,5 +24,5 @@ void occPointLight (in int theId,
DirectLighting += occPBRIllumination (theView, aLight, theNormal, DirectLighting += occPBRIllumination (theView, aLight, theNormal,
BaseColor, Metallic, Roughness, IOR, BaseColor, Metallic, Roughness, IOR,
occLight_Specular (theId), occLight_Specular (theId),
occLight_Intensity(theId) * anAtten); occLight_Intensity(theId) * anAtten) * theShadow;
} }

View File

@ -9,7 +9,8 @@ void occPointLight (in int theId,
in vec3 theNormal, in vec3 theNormal,
in vec3 theView, in vec3 theView,
in vec3 thePoint, in vec3 thePoint,
in bool theIsFront) in bool theIsFront,
in float theShadow)
{ {
vec3 aLight = occLight_Position (theId) - thePoint; vec3 aLight = occLight_Position (theId) - thePoint;
@ -31,6 +32,6 @@ void occPointLight (in int theId,
aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront)); aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));
} }
Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten; Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;
Specular += occLight_Specular(theId) * aSpecl * anAtten; Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;
} }

View File

@ -116,6 +116,10 @@ static const char Shaders_Declarations_glsl[] =
"#define INV_PI 0.318309886\n" "#define INV_PI 0.318309886\n"
"#define INV_PI_2 0.159154943\n" "#define INV_PI_2 0.159154943\n"
"\n" "\n"
"// Point light depth range values\n"
"#define POINTLIGHT_ZNEAR 1.0\n"
"#define POINTLIGHT_ZFAR 3000.0\n"
"\n"
"// Matrix state\n" "// Matrix state\n"
"uniform mat4 occWorldViewMatrix; //!< World-view matrix\n" "uniform mat4 occWorldViewMatrix; //!< World-view matrix\n"
"uniform mat4 occProjectionMatrix; //!< Projection matrix\n" "uniform mat4 occProjectionMatrix; //!< Projection matrix\n"

View File

@ -0,0 +1,27 @@
// This file has been automatically generated from resource file src/Shaders/LightShadow.glsl
static const char Shaders_LightPointShadow_glsl[] =
"//! Function computes point light shadow attenuation (1.0 means no shadow).\n"
"float occLightPointShadow (in samplerCube theShadow,\n"
" //in vec2 theDepthRange,\n"
" in int theId,\n"
" in vec3 thePoint,\n"
" in vec3 theNormal)\n"
"{\n"
" vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];\n"
" vec3 aLightDir = thePoint - occLight_Position (theId);\n"
" // convert light-to-fragment vector to a depth value.\n"
" vec3 anAbsVec = abs (aLightDir);\n"
" float aLocalZcomp = max (anAbsVec.x, max (anAbsVec.y, anAbsVec.z));\n"
" // set znear and zfar\n"
" float aNear = POINTLIGHT_ZNEAR;\n"
" float aFar = POINTLIGHT_ZFAR;\n"
" float aNormZComp = (aFar + aNear) / (aFar-aNear) - (2.0 * aFar * aNear) / (aFar - aNear) / aLocalZcomp;\n"
" float aDist = (aNormZComp + 1.0) * 0.5;\n"
" // calculate bias and test depth.\n"
" aLightDir = normalize (aLightDir);\n"
" float aBias = min (occShadowMapSizeBias.y * (1.0 - dot (theNormal, aLightDir)), occShadowMapSizeBias.y * 0.1);\n"
" float aClosestDepth = occTextureCube (theShadow, aLightDir).r;\n"
" float aShadow = (aDist - aBias) > aClosestDepth ? 1.0 : 0.0;\n"
" return 1.0 - aShadow;\n"
"}\n";

View File

@ -12,7 +12,8 @@ static const char Shaders_PBRPointLight_glsl[] =
" in vec3 theNormal,\n" " in vec3 theNormal,\n"
" in vec3 theView,\n" " in vec3 theView,\n"
" in vec3 thePoint,\n" " in vec3 thePoint,\n"
" in bool theIsFront)\n" " in bool theIsFront,\n"
" in float theShadow)\n"
"{\n" "{\n"
" vec3 aLight = occLight_Position (theId) - thePoint;\n" " vec3 aLight = occLight_Position (theId) - thePoint;\n"
"\n" "\n"
@ -26,5 +27,5 @@ static const char Shaders_PBRPointLight_glsl[] =
" DirectLighting += occPBRIllumination (theView, aLight, theNormal,\n" " DirectLighting += occPBRIllumination (theView, aLight, theNormal,\n"
" BaseColor, Metallic, Roughness, IOR,\n" " BaseColor, Metallic, Roughness, IOR,\n"
" occLight_Specular (theId),\n" " occLight_Specular (theId),\n"
" occLight_Intensity(theId) * anAtten);\n" " occLight_Intensity(theId) * anAtten) * theShadow;\n"
"}\n"; "}\n";

View File

@ -12,7 +12,8 @@ static const char Shaders_PhongPointLight_glsl[] =
" in vec3 theNormal,\n" " in vec3 theNormal,\n"
" in vec3 theView,\n" " in vec3 theView,\n"
" in vec3 thePoint,\n" " in vec3 thePoint,\n"
" in bool theIsFront)\n" " in bool theIsFront,\n"
" in float theShadow)\n"
"{\n" "{\n"
" vec3 aLight = occLight_Position (theId) - thePoint;\n" " vec3 aLight = occLight_Position (theId) - thePoint;\n"
"\n" "\n"
@ -34,6 +35,6 @@ static const char Shaders_PhongPointLight_glsl[] =
" aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));\n" " aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));\n"
" }\n" " }\n"
"\n" "\n"
" Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten;\n" " Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;\n"
" Specular += occLight_Specular(theId) * aSpecl * anAtten;\n" " Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;\n"
"}\n"; "}\n";

View File

@ -0,0 +1,58 @@
puts "========"
puts "0032173: Visualization, TKOpenGl - implement simple shadow mapping for a point light source"
puts "Test shadow map from a point light source on multiple boxes."
puts "========"
pload MODELING VISUALIZATION
if { $::tcl_platform(os) == "Darwin" } { vcaps -core }
vclear
vinit View1
vrenderparams -shadingModel phong
# add geometry
box b1 20 0 0 10 10 10
box b2 -20 0 0 10 10 10
box b3 -50 -20 -25 100 5 50
box b4 0 10 0 5 5 5
box b5 0 0 5 3 3 3
box b6 0 0 -5 7 7 7
box b7 0 -5 -10 3 3 3
vdisplay -dispmode 1 b1 b2 b3 b4 b5 b6 b7
vfit
# add colors
vsetcolor b1 RED3
vsetcolor b2 GREEN3
vsetcolor b3 BLUE3
vsetcolor b4 ORANGE3
vsetcolor b5 YELLOW3
vsetcolor b6 SALMON3
vsetcolor b7 PURPLE3
# add light
vlight -clear
vlight pntlight1 -type POSITIONAL -pos 0 100 0 -intensity 1000 -castShadows 1
#dump single light phong
vviewparams -scale 8.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_single_pointlight_phong1.png
vviewparams -scale 8.0 -proj 0.5 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_single_pointlight_phong2.png
#dump single light pbr
vrenderparams -shadingModel pbr
vviewparams -scale 10.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_single_pointlight_pbr1.png
vviewparams -scale 10.0 -proj 0.2 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_single_pointlight_pbr2.png
#add second light
vlight pntlight2 -type POSITIONAL -pos 40 100 0 -intensity 1000 -castShadows 1
#dump double light phong
vrenderparams -shadingModel phong
vviewparams -scale 8.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_double_pointlight_phong1.png
vviewparams -scale 8.0 -proj 0.5 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_double_pointlight_phong2.png
#dump double light pbr
vrenderparams -shadingModel pbr
vviewparams -scale 10.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_double_pointlight_pbr1.png
vviewparams -scale 10.0 -proj -0.2 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
vdump $imagedir/${casename}_double_pointlight_pbr2.png