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.
void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast)
{
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");
}
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
// purpose :
//! @name Public camera properties
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.
//! @return camera look direction.
const gp_Dir& Direction() const { return myDirection; }
{
//
}
+
+// =======================================================================
+// 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;
+}
#ifndef _Graphic3d_CubeMap_HeaderFile
#define _Graphic3d_CubeMap_HeaderFile
+#include <gp_Dir.hxx>
#include <Graphic3d_CubeMapOrder.hxx>
#include <Graphic3d_TextureMap.hxx>
//! Empty destructor.
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:
Graphic3d_CubeMapSide myCurrentSide; //!< Iterator state
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
// purpose :
//! Returns total amount of lights of specified type.
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()
public:
#include <Message.hxx>
#include "../Shaders/Shaders_LightShadow_glsl.pxx"
+#include "../Shaders/Shaders_LightPointShadow_glsl.pxx"
#include "../Shaders/Shaders_PBRDistribution_glsl.pxx"
#include "../Shaders/Shaders_PBRDirectionalLight_glsl.pxx"
#include "../Shaders/Shaders_PBRGeometry_glsl.pxx"
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
// =======================================================================
TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
const Handle(Graphic3d_LightSet)& theLights,
- Standard_Boolean theHasVertColor,
- Standard_Boolean theIsPBR,
- Standard_Boolean theHasTexColor,
- Standard_Integer theNbShadowMaps) const
+ Standard_Boolean theHasVertColor,
+ Standard_Boolean theIsPBR,
+ Standard_Boolean theHasTexColor,
+ Standard_Integer theNbShadowMaps,
+ Standard_Integer theNbShadowCubeMaps) const
{
TCollection_AsciiString aLightsFunc, aLightsLoop;
theNbLights = 0;
if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX)
{
Standard_Integer anIndex = 0;
+ Standard_Integer a2DSamplerIndex = 0;
+ Standard_Integer aCubeSamplerIndex = 0;
for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
aLightIter.More(); aLightIter.Next())
{
{
aLightsLoop = aLightsLoop +
EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront,"
- EOL" occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
+ EOL" occLightShadow (occShadowMapSamplers[" + a2DSamplerIndex++ + "], " + anIndex + ", theNormal));";
}
else
{
}
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;
break;
}
{
aLightsLoop = aLightsLoop +
EOL" occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront,"
- EOL" occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
+ EOL" occLightShadow (occShadowMapSamplers[" + a2DSamplerIndex++ + "], " + anIndex + ", theNormal));";
}
else
{
aLightsLoop +=
EOL" if (aType == OccLightType_Point)"
EOL" {"
- EOL" occPointLight (anIndex, theNormal, theView, aPoint, theIsFront);"
+ EOL" occPointLight (anIndex, theNormal, theView, aPoint, theIsFront, 1.0);"
EOL" }";
}
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
}
bool isShadowShaderAdded = false;
+ bool isShadowCubeShaderAdded = false;
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) == 1
&& theNbLights == 1
&& !theIsPBR
}
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;
}
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 BackColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
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()
+ THE_FUNC_transformNormal_world
+ EOL
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (aNbLights);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
const Standard_Integer theBits,
const Standard_Boolean theIsFlatNormal,
const Standard_Boolean theIsPBR,
- const Standard_Integer theNbShadowMaps) const
+ const Standard_Integer theNbShadowMaps,
+ const Standard_Integer theNbShadowCubeMaps) const
{
TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() +
"computeLighting (normalize (Normal), normalize (View), PositionWorld, gl_FrontFacing)";
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));
- 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 ("sampler2D occShadowMapSamplers[THE_NB_SHADOWMAPS]", Graphic3d_TOS_FRAGMENT));
- aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 occShadowMapSizeBias", Graphic3d_TOS_FRAGMENT));
-
+ aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 occShadowMapMatrices[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX));
+ 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));
aSrcVertExtraMain +=
EOL" for (int aShadowIter = 0; aShadowIter < THE_NB_SHADOWMAPS; ++aShadowIter)"
Standard_Integer aNbLights = 0;
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcFragGetVertColor.IsEmpty(),
- theIsPBR, toUseTexColor, theNbShadowMaps);
+ theIsPBR, toUseTexColor, theNbShadowMaps, theNbShadowCubeMaps);
aSrcFrag += TCollection_AsciiString()
+ EOL
+ aSrcFragGetVertColor
+ EOL"}";
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);
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (aNbLights);
aProgramSrc->SetNbShadowMaps (theNbShadowMaps);
+ aProgramSrc->SetNbShadowCubeMaps (theNbShadowCubeMaps);
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
aProgramSrc->SetDefaultSampler (false);
aProgramSrc->SetNbLightsMax (0);
aProgramSrc->SetNbShadowMaps (0);
+ aProgramSrc->SetNbShadowCubeMaps (0);
aProgramSrc->SetNbClipPlanesMax (0);
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
aProgSrc->SetDefaultSampler (false);
aProgSrc->SetNbLightsMax (0);
aProgSrc->SetNbShadowMaps (0);
+ aProgSrc->SetNbShadowCubeMaps (0);
aProgSrc->SetNbClipPlanesMax (0);
aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
const Standard_Integer theBits,
const Standard_Boolean theIsFlatNormal,
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.
Standard_EXPORT Handle(Graphic3d_ShaderProgram) getStdProgramBoundBox() const;
//! @param theNbShadowMaps [in] flag to include shadow map
Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
const Handle(Graphic3d_LightSet)& theLights,
- Standard_Boolean theHasVertColor,
- Standard_Boolean theIsPBR,
- Standard_Boolean theHasTexColor,
- Standard_Integer theNbShadowMaps) const;
+ Standard_Boolean theHasVertColor,
+ Standard_Boolean theIsPBR,
+ Standard_Boolean theHasTexColor,
+ Standard_Integer theNbShadowMaps,
+ Standard_Integer theNbShadowCubeMaps) const;
protected:
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
: myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
myNbShadowMaps (0),
+ myNbShadowCubeMaps (0),
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
myTextureSetBits (Graphic3d_TextureSetBits_NONE),
//! Specify the length of array of light sources (THE_MAX_LIGHTS).
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; }
- //! 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; }
+ //! 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),
//! to be used for initialization occClipPlaneEquations.
//! Default value is THE_MAX_CLIP_PLANES_DEFAULT.
private:
- TCollection_AsciiString myID; //!< the unique identifier of program object
- Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects
- Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables
- Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes
- 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 myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPS)
- 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_Integer myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
- Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
- Standard_Boolean myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
- 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
+ TCollection_AsciiString myID; //!< the unique identifier of program object
+ Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects
+ Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables
+ Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes
+ 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 myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAP2D)
+ Standard_Integer myNbShadowCubeMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPCUBE)
+ 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_Integer myTextureSetBits; //!< texture units declared within the program, @sa Graphic3d_TextureSetBits
+ Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
+ Standard_Boolean myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
+ 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
};
//! Note that it can be overridden to Graphic3d_TextureUnit_0 for FFP fallback on hardware without multi-texturing.
Graphic3d_TextureUnit_PointSprite = Graphic3d_TextureUnit_1,
+ //! samplerCube occShadowCubeMapSampler.
+ //! Point light source shadowmap texture.
+ Graphic3d_TextureUnit_ShadowCubeMap = -7,
+
//! sampler2D occDepthPeelingDepth.
//! 1st texture unit for Depth Peeling lookups.
Graphic3d_TextureUnit_DepthPeelingDepth = -6,
myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH),
myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_PbrIblSpecular),
myShadowMapTexUnit (Graphic3d_TextureUnit_ShadowMap),
+ myShadowCubeMapTexUnit (Graphic3d_TextureUnit_ShadowCubeMap),
myDepthPeelingDepthTexUnit (Graphic3d_TextureUnit_DepthPeelingDepth),
myDepthPeelingFrontColorTexUnit (Graphic3d_TextureUnit_DepthPeelingFrontColor),
myFrameStats (new OpenGl_FrameStats()),
}
}
+ myShadowCubeMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowCubeMap); // -7
myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingDepth); // -6
myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingFrontColor); // -5
myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowMap); // -4
myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular); // -1
if (!myHasPBR)
{
+ myShadowCubeMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowCubeMapTexUnit + 3);
myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingDepthTexUnit + 3);
myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingFrontColorTexUnit + 3);
myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowMapTexUnit + 3);
//! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable.
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.
Graphic3d_TextureUnit DepthPeelingDepthTexUnit() const { return myDepthPeelingDepthTexUnit; }
//! (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 myShadowCubeMapTexUnit; //!< samplerCube occShadowCubeMapSampler
Graphic3d_TextureUnit myDepthPeelingDepthTexUnit; //!< sampler2D occDepthPeelingDepth, texture unit for Depth Peeling lookups
Graphic3d_TextureUnit myDepthPeelingFrontColorTexUnit; //!< sampler2D occDepthPeelingFrontColor, texture unit for Depth Peeling lookups
const Graphic3d_Vec2i& theSize,
const OpenGl_ColorFormats& theColorFormats,
const Standard_Integer theDepthFormat,
- const Standard_Integer theNbSamples)
+ const Standard_Integer theNbSamples,
+ const Standard_Boolean theIsCubeMap)
{
myColorFormats = theColorFormats;
// 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
+ Graphic3d_TypeOfTexture aTypeOfTexture = theIsCubeMap ? Graphic3d_TypeOfTexture_CUBEMAP : Graphic3d_TypeOfTexture_2D;
const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, myDepthFormat);
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,
"Warning! Depth textures are not supported by hardware!");
{
if (hasDepthStencilAttach (theGlContext))
{
- theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
+ if (theIsCubeMap)
+ {
+ 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
{
- 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);
+ if (theIsCubeMap)
+ {
+ for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
+ {
+ 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)
}
}
}
+ 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)
{
+ std::cout << "\n\nIncomplete framebuffer: " << theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) << "\n\n";
Release (theGlContext.operator->());
return Standard_False;
}
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
// purpose :
Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& theGlCtx,
const Handle(OpenGl_FrameBuffer)& theFbo,
Image_PixMap& theImage,
- Graphic3d_BufferType theBufferType)
+ Graphic3d_BufferType theBufferType,
+ const Standard_Integer theCubeFace)
{
if (theGlCtx.IsNull()
|| theImage.IsEmpty())
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
if (!theFbo.IsNull() && theFbo->IsValid())
{
//! @param theFbo FBO to dump (or window buffer, if NULL)
//! @param theImage target image
//! @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
Standard_EXPORT static Standard_Boolean BufferDump (const Handle(OpenGl_Context)& theGlCtx,
const Handle(OpenGl_FrameBuffer)& theFbo,
Image_PixMap& theImage,
- Graphic3d_BufferType theBufferType);
+ Graphic3d_BufferType theBufferType,
+ const Standard_Integer theCubeFace = -1);
public:
//! @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 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
Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
const Graphic3d_Vec2i& theSize,
const OpenGl_ColorFormats& theColorFormats,
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.
Standard_EXPORT Standard_Boolean InitLazy (const Handle(OpenGl_Context)& theGlCtx,
//! Bind frame buffer for reading GL_READ_FRAMEBUFFER
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.
Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);
// update shadow map variables
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;
{
aSizeBias.SetValues (1.0f / (float )myLightSourceState.ShadowMaps()->First()->Texture()->SizeX(),
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)
{
const Handle(OpenGl_ShadowMap)& aShadow = myLightSourceState.ShadowMaps()->Value (aShadowIter);
}
}
- 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);
}
}
const Standard_Boolean theIsFlatNormal,
const Standard_Boolean theIsPBR)
{
- Standard_Integer aNbShadowMaps = myLightSourceState.HasShadowMaps()
- ? myLightSourceState.LightSources()->NbCastShadows()
- : 0;
- Handle(Graphic3d_ShaderProgram) aProgramSrc = getStdProgramPhong (myLightSourceState.LightSources(), theBits, theIsFlatNormal, theIsPBR, aNbShadowMaps);
+ Standard_Integer aNbShadowMaps, aNbShadowCubeMaps;
+ myLightSourceState.LightSources()->CalculateNbShadows (aNbShadowMaps, aNbShadowCubeMaps);
+ // point light shadows are not currently supported on opengles 2.0.
+ 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;
if (!Create (aProgramSrc, aKey, theProgram))
{
"occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
"occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
- "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
- "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
- "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
-
- "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
- "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
- "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
- "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
- "occShadowMapSizeBias", // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS
- "occShadowMapSamplers", // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,
- "occShadowMapMatrices", // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,
-
- "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
- "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
- "occPbrMaterial", // OpenGl_OCCT_PBR_MATERIAL
- "occCommonMaterial", // OpenGl_OCCT_COMMON_MATERIAL
- "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
- "occColor", // OpenGl_OCCT_COLOR
-
- "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
- "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
-
- "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
- "occPointSize", // OpenGl_OCCT_POINT_SIZE
-
- "occViewport", // OpenGl_OCCT_VIEWPORT
- "occLineWidth", // OpenGl_OCCT_LINE_WIDTH
- "occLineFeather", // OpenGl_OCCT_LINE_FEATHER
- "occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
- "occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
- "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
- "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
-
- "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
- "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
-
- "occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
+ "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
+ "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
+ "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
+
+ "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
+ "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
+ "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
+ "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
+ "occShadowMapSizeBias", // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS
+ "occShadowMapSamplers", // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,
+ "occShadowCubeMapSamplers", // OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS,
+ "occShadowMapMatrices", // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,
+
+ "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
+ "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
+ "occPbrMaterial", // OpenGl_OCCT_PBR_MATERIAL
+ "occCommonMaterial", // OpenGl_OCCT_COMMON_MATERIAL
+ "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF
+ "occColor", // OpenGl_OCCT_COLOR
+
+ "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT
+ "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR
+
+ "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D
+ "occPointSize", // OpenGl_OCCT_POINT_SIZE
+
+ "occViewport", // OpenGl_OCCT_VIEWPORT
+ "occLineWidth", // OpenGl_OCCT_LINE_WIDTH
+ "occLineFeather", // OpenGl_OCCT_LINE_FEATHER
+ "occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN
+ "occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR
+ "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR
+ "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE
+
+ "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE
+ "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
+
+ "occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
};
namespace
myShareCount(1),
myNbLightsMax (0),
myNbShadowMaps (0),
+ myNbShadowCubeMaps (0),
myNbClipPlanesMax (0),
myNbFragOutputs (1),
myTextureSetBits (Graphic3d_TextureSetBits_NONE),
}
TCollection_AsciiString aHeaderConstants;
- myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
- myNbShadowMaps = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 0;
- myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
+ myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
+ myNbShadowMaps = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 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_CLIP_PLANES ") + myNbClipPlanesMax + "\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)
{
- 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
&& theCtx->arbClipControl)
}
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"))
{
SetUniform (theCtx, aLocSampler, GLint(theCtx->DepthPeelingDepthTexUnit()));
OpenGl_OCC_LIGHT_SOURCE_TYPES,
OpenGl_OCC_LIGHT_SOURCE_PARAMS,
OpenGl_OCC_LIGHT_AMBIENT,
- OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS,// occShadowMapSizeBias
- OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, // occShadowMapSamplers
- OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, // occShadowMapMatrices
+ OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS, // occShadowMapSizeBias
+ OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, // occShadowMapSamplers
+ OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS, // occShadowCubeMapSamplers
+ OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, // occShadowMapMatrices
// Material state
OpenGl_OCCT_TEXTURE_ENABLE,
//! to be used for initialization occLightSources (OpenGl_OCC_LIGHT_SOURCE_PARAMS).
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; }
+ //! 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),
//! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS).
Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
protected:
- GLuint myProgramID; //!< Handle of OpenGL shader program
- OpenGl_ShaderList myShaderObjects; //!< List of attached shader objects
- 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 myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
- Standard_Integer myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPS)
- 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_Integer myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
- Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
- Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader should perform alpha-test
- Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage
+ GLuint myProgramID; //!< Handle of OpenGL shader program
+ OpenGl_ShaderList myShaderObjects; //!< List of attached shader objects
+ 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 myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
+ Standard_Integer myNbShadowMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAP2D)
+ Standard_Integer myNbShadowCubeMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPCUBE)
+ 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_Integer myTextureSetBits; //!< texture units declared within the program, @sa Graphic3d_TextureSetBits
+ Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
+ Standard_Boolean myHasAlphaTest; //!< flag indicating that Fragment Shader should perform alpha-test
+ Standard_Boolean myHasTessShader; //!< flag indicating that program defines tessellation stage
protected:
// purpose :
// =======================================================================
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 aGraphicBox = aMinMaxBox;
case Graphic3d_TypeOfLightSource_Positional:
{
// 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:
{
//! Compute camera.
//! @param theView [in] active view
//! @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,
- const gp_XYZ* theOrigin = NULL);
+ const gp_XYZ* theOrigin = NULL,
+ const Standard_Integer theFace = -1);
private:
return false;
}
}
-
theCtx->core11fwd->glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
theSizeXYZ.x(), theSizeXYZ.y(), 0,
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
}
case Graphic3d_TypeOfTexture_CUBEMAP:
{
- Unbind (theCtx);
- Release (theCtx.get());
- return false;
+ Bind (theCtx);
+ applyDefaultSamplerParams (theCtx);
+ 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;
}
}
&& myRenderParams.Method != Graphic3d_RM_RAYTRACING;
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())
{
myShadowMaps->Release (aCtx.get());
myShadowMaps->Resize (0, myLights->NbCastShadows() - 1, true);
}
-
- const GLint aSamplFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + 1;
- for (Standard_Integer aShadowIter = 0; aShadowIter < myShadowMaps->Size(); ++aShadowIter)
+ const GLint aSampleFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + aNbPointShadows + 1;
+ const GLint aSampleCubeFrom = GLint(aCtx->ShadowCubeMapTexUnit()) - aNbPointShadows + 1;
+ 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);
- if (aShadow.IsNull())
- {
- aShadow = new OpenGl_ShadowMap();
- }
- 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)
+ Handle(Graphic3d_CLight) aLight = aLightIter.Value();
+ if (aLight->ToCastShadows())
{
- OpenGl_ColorFormats aDummy;
- if (!aShadowFbo->Init (aCtx, Graphic3d_Vec2i (myRenderParams.ShadowMapResolution), aDummy, myFboDepthFormat, 0))
+ Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue (aLightIndex++);
+ if (aShadow.IsNull())
{
- 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;
+ }
}
}
}
{
const Handle(OpenGl_ShadowMap)& aShadowMap = myShadowMaps->ChangeValue (aShadowIndex);
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;
}
}
//function : renderShadowMap
//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();
- if (!theShadowMap->UpdateCamera (*this))
+ if (!theShadowMap->UpdateCamera (*this, NULL, theFace))
{
return;
}
aCtx->ShaderManager()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
const Handle(OpenGl_FrameBuffer)& aShadowBuffer = theShadowMap->FrameBuffer();
- aShadowBuffer->BindBuffer (aCtx);
+ if (theFace < 0)
+ {
+ aShadowBuffer->BindBuffer (aCtx);
+ }
+ else
+ {
+ aShadowBuffer->BindBufferCube (aCtx, theFace);
+ }
aShadowBuffer->SetupViewport (aCtx);
aCtx->SetColorMask (false);
myWorkspace->UseZBuffer() = true;
myWorkspace->UseDepthWrite() = true;
aCtx->core11fwd->glDepthFunc (GL_LEQUAL);
- aCtx->core11fwd->glDepthMask (GL_TRUE);
aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
aCtx->core11fwd->glClearDepth (1.0);
+ aCtx->core11fwd->glDepthMask (GL_TRUE);
aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
Graphic3d_Camera::Projection aProjection = theShadowMap->LightSource()->Type() == Graphic3d_TypeOfLightSource_Directional
myWorkspace->ResetAppliedAspect();
aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
-//Image_AlienPixMap anImage; anImage.InitZero (Image_Format_Gray, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY());
-//OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth);
-//anImage.Save (TCollection_AsciiString ("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png");
-
+ //Image_AlienPixMap anImage; anImage.InitZero (Image_Format_GrayF, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY());
+ //OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth);
+ //anImage.Save (TCollection_AsciiString("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png");
bindDefaultFbo();
}
//! Renders the graphical contents of the view into the preprepared shadowmap framebuffer.
//! @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.
//! @param theProjection [in] the projection that should be used for rendering.
#define INV_PI 0.318309886
#define INV_PI_2 0.159154943
+// Point light depth range values
+#define POINTLIGHT_ZNEAR 1.0
+#define POINTLIGHT_ZFAR 3000.0
+
// Matrix state
uniform mat4 occWorldViewMatrix; //!< World-view matrix
uniform mat4 occProjectionMatrix; //!< Projection matrix
srcinc:::Declarations.glsl
srcinc:::DeclarationsImpl.glsl
srcinc:::LightShadow.glsl
+srcinc:::LightPointShadow.glsl
srcinc:::PBRCookTorrance.glsl
srcinc:::PBRDirectionalLight.glsl
srcinc:::PBRDistribution.glsl
Shaders_Declarations_glsl.pxx
Shaders_DeclarationsImpl_glsl.pxx
Shaders_LightShadow_glsl.pxx
+Shaders_LightPointShadow_glsl.pxx
Shaders_Display_fs.pxx
Shaders_PBRCookTorrance_glsl.pxx
Shaders_PBRDirectionalLight_glsl.pxx
--- /dev/null
+//! 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;
+}
in vec3 theNormal,
in vec3 theView,
in vec3 thePoint,
- in bool theIsFront)
+ in bool theIsFront,
+ in float theShadow)
{
vec3 aLight = occLight_Position (theId) - thePoint;
DirectLighting += occPBRIllumination (theView, aLight, theNormal,
BaseColor, Metallic, Roughness, IOR,
occLight_Specular (theId),
- occLight_Intensity(theId) * anAtten);
+ occLight_Intensity(theId) * anAtten) * theShadow;
}
in vec3 theNormal,
in vec3 theView,
in vec3 thePoint,
- in bool theIsFront)
+ in bool theIsFront,
+ in float theShadow)
{
vec3 aLight = occLight_Position (theId) - thePoint;
aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));
}
- Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten;
- Specular += occLight_Specular(theId) * aSpecl * anAtten;
+ Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;
+ Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;
}
"#define INV_PI 0.318309886\n"
"#define INV_PI_2 0.159154943\n"
"\n"
+ "// Point light depth range values\n"
+ "#define POINTLIGHT_ZNEAR 1.0\n"
+ "#define POINTLIGHT_ZFAR 3000.0\n"
+ "\n"
"// Matrix state\n"
"uniform mat4 occWorldViewMatrix; //!< World-view matrix\n"
"uniform mat4 occProjectionMatrix; //!< Projection matrix\n"
--- /dev/null
+// 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";
" in vec3 theNormal,\n"
" in vec3 theView,\n"
" in vec3 thePoint,\n"
- " in bool theIsFront)\n"
+ " in bool theIsFront,\n"
+ " in float theShadow)\n"
"{\n"
" vec3 aLight = occLight_Position (theId) - thePoint;\n"
"\n"
" DirectLighting += occPBRIllumination (theView, aLight, theNormal,\n"
" BaseColor, Metallic, Roughness, IOR,\n"
" occLight_Specular (theId),\n"
- " occLight_Intensity(theId) * anAtten);\n"
+ " occLight_Intensity(theId) * anAtten) * theShadow;\n"
"}\n";
" in vec3 theNormal,\n"
" in vec3 theView,\n"
" in vec3 thePoint,\n"
- " in bool theIsFront)\n"
+ " in bool theIsFront,\n"
+ " in float theShadow)\n"
"{\n"
" vec3 aLight = occLight_Position (theId) - thePoint;\n"
"\n"
" aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));\n"
" }\n"
"\n"
- " Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten;\n"
- " Specular += occLight_Specular(theId) * aSpecl * anAtten;\n"
+ " Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;\n"
+ " Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;\n"
"}\n";
--- /dev/null
+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