Changed shadow cubemap calculation of up and direction vectors.
Included point light range to shader calculations.
Replaced use of define values in shaders for uniforms vectors with range
parameters.
Code cleanup.
public:
//! return default valut for znear.
- Standard_EXPORT Standard_Real GetDefaultZNear();
+ Standard_EXPORT static Standard_Real GetDefaultZNear();
//! return default valut for zfar.
- Standard_EXPORT Standard_Real GetDefaultZFar();
+ Standard_EXPORT static Standard_Real GetDefaultZFar();
//! Get camera look direction.
//! @return camera look direction.
// =======================================================================
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;
+ const Standard_Integer aDiv2 = theFace / 2;
+ const Standard_Integer aMod2 = theFace % 2;
+ return gp_Dir (aDiv2 == 0 ? aMod2 == 0 ? 1.0 : -1.0 : 0.0,
+ aDiv2 == 1 ? aMod2 == 0 ? 1.0 : -1.0 : 0.0,
+ aDiv2 == 2 ? aMod2 == 0 ? 1.0 : -1.0 : 0.0);
}
// =======================================================================
// =======================================================================
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;
+ const Standard_Integer aDiv2 = theFace / 2;
+ const Standard_Integer aMod2 = theFace % 2;
+ return gp_Dir (0.0,
+ aDiv2 == 0 ? 1.0 : aDiv2 == 2 ? -1.0 : 0.0,
+ aDiv2 == 1 ? aMod2 == 0 ? 1.0 : -1.0 : 0.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)
if (theNbShadowMaps + theNbShadowCubeMaps > 0)
{
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 occShadowMapMatrices[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX));
+ aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 occShadowMapRangeParams[THE_NB_SHADOWMAPS]", Graphic3d_TOS_FRAGMENT));
aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 occShadowMapSizeBias", Graphic3d_TOS_FRAGMENT));
if (theNbShadowMaps > 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);
- }
+ theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X),
+ myDepthStencilTexture->TextureId(), 0);
}
else
{
{
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);
- }
+ theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X),
+ myDepthStencilTexture->TextureId(), 0);
+ theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X),
+ myDepthStencilTexture->TextureId(), 0);
}
else
{
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);
+ if (hasDepthStencilAttach (theGlCtx))
+ {
+ theGlCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theFace),
+ myDepthStencilTexture->TextureId(), 0);
+ }
+ else
+ {
+ theGlCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theFace),
+ myDepthStencilTexture->TextureId(), 0);
+ theGlCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theFace),
+ myDepthStencilTexture->TextureId(), 0);
+ }
}
// =======================================================================
#include <OpenGl_ShaderManager.hxx>
+#include <Graphic3d_Camera.hxx>
#include <Graphic3d_CubeMapPacked.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <OpenGl_Aspects.hxx>
theProgram->SetUniform (myContext, aShadowMatLoc, aNbShadowMaps, &myShadowMatArray.First());
theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS), aSizeBias);
}
+ if (const OpenGl_ShaderUniformLocation aShadowRangeLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_RANGEPARAMS))
+ {
+ Standard_Integer aNbShadowMaps = theProgram->NbShadowMaps() + theProgram->NbShadowCubeMaps();
+ if (myShadowRangeArray.Size() < aNbShadowMaps)
+ {
+ myShadowRangeArray.Resize (0, aNbShadowMaps - 1, false);
+ }
+
+ if (myLightSourceState.HasShadowMaps())
+ {
+ 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);
+ myShadowRangeArray[aShadowIter] = Graphic3d_Vec2 (aShadow->Camera()->ZNear(), aShadow->Camera()->ZFar());
+ }
+ }
+ theProgram->SetUniform (myContext, aShadowRangeLoc, aNbShadowMaps, &myShadowRangeArray.First());
+ }
}
// =======================================================================
mutable NCollection_Array1<Standard_Integer> myLightTypeArray;
mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray;
mutable NCollection_Array1<Graphic3d_Mat4> myShadowMatArray;
+ mutable NCollection_Array1<Graphic3d_Vec2> myShadowRangeArray;
mutable NCollection_Array1<OpenGl_Vec4> myClipPlaneArray;
mutable NCollection_Array1<OpenGl_Vec4d> myClipPlaneArrayFfp;
mutable NCollection_Array1<Standard_Integer> myClipChainArray;
"occShadowMapSamplers", // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,
"occShadowCubeMapSamplers", // OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS,
"occShadowMapMatrices", // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,
+ "occShadowMapRangeParams", // OpenGl_OCC_LIGHT_SHADOWMAP_RANGEPARAMS,
"occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
"occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, // occShadowMapSamplers
OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS, // occShadowCubeMapSamplers
OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, // occShadowMapMatrices
+ OpenGl_OCC_LIGHT_SHADOWMAP_RANGEPARAMS, // occShadowMapRangeParams
// Material state
OpenGl_OCCT_TEXTURE_ENABLE,
myShadowCamera->SetZeroToOneDepth (theView.Camera()->IsZeroToOneDepth());
myShadowCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
myShadowCamera->SetFOVy (90.0);
- const gp_Pnt& aLightPos = myShadowLight->Position();
- myShadowCamera->MoveEyeTo (aLightPos);
+ myShadowCamera->MoveEyeTo (myShadowLight->Position());
// 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());
+ myShadowCamera->SetZRange (1.0, myShadowLight->Range() <= 1.0 ? Graphic3d_Camera::GetDefaultZFar() : myShadowLight->Range());
myLightMatrix = myShadowCamera->ProjectionMatrixF() * myShadowCamera->OrientationMatrixF();
return true;
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,
+ theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_CUBE_MAP, 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);
+ theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_CUBE_MAP, 0, GL_TEXTURE_WIDTH, &aTestWidth);
+ theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_CUBE_MAP, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
+ theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_CUBE_MAP, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestWidth == 0 || aTestHeight == 0)
{
// no memory or broken input parameters
aShadowMap->SetLightSource (aLight);
if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
{
- // point light shadows are not currently supported on opengles 2.0.
+ // cube shadow maps are not currently working on opengles 2.0.
if (aCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES
|| aCtx->VersionMajor() >= 3)
{
//! 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)
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 aRange = occShadowMapRangeParams[theId].y;
+ float aNear = occShadowMapRangeParams[theId].x;
+ float aFar = aRange <= aNear ? POINTLIGHT_ZFAR : aRange;
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.
" 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 aRange = occShadowMapRangeParams[theId].y;\n"
+ " float aNear = occShadowMapRangeParams[theId].x;\n"
+ " float aFar = aRange <= aNear ? POINTLIGHT_ZFAR : aRange;\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"
vsetcolor b7 PURPLE3
# add light
vlight -clear
-vlight pntlight1 -type POSITIONAL -pos 0 100 0 -intensity 1000 -castShadows 1
+vlight pntlight1 -type POSITIONAL -pos 0 100 0 -intensity 1000 -castShadows 1 -range 1000
#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