From: drochalo Date: Thu, 11 Apr 2024 16:53:27 +0000 (+0100) Subject: 0032752: Visualization, TKOpenGl - extend V3d_View::ToPixMap() options with Z-layer X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=102278b9feb1d2174109bab2f297e7852ffdb9fe;p=occt.git 0032752: Visualization, TKOpenGl - extend V3d_View::ToPixMap() options with Z-layer 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. --- diff --git a/src/Graphic3d/Graphic3d_Camera.hxx b/src/Graphic3d/Graphic3d_Camera.hxx index a44fe69d77..1f6961498a 100644 --- a/src/Graphic3d/Graphic3d_Camera.hxx +++ b/src/Graphic3d/Graphic3d_Camera.hxx @@ -203,10 +203,10 @@ public: 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. diff --git a/src/Graphic3d/Graphic3d_CubeMap.cxx b/src/Graphic3d/Graphic3d_CubeMap.cxx index 4f8b40d929..5912c0ad8b 100644 --- a/src/Graphic3d/Graphic3d_CubeMap.cxx +++ b/src/Graphic3d/Graphic3d_CubeMap.cxx @@ -59,41 +59,11 @@ Graphic3d_CubeMap::~Graphic3d_CubeMap() // ======================================================================= 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); } // ======================================================================= @@ -102,39 +72,9 @@ gp_Dir Graphic3d_CubeMap::GetCubeDirection (Graphic3d_CubeMapSide theFace) // ======================================================================= 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); } diff --git a/src/Graphic3d/Graphic3d_LightSet.cxx b/src/Graphic3d/Graphic3d_LightSet.cxx index a4571f4f4c..3c272d0974 100644 --- a/src/Graphic3d/Graphic3d_LightSet.cxx +++ b/src/Graphic3d/Graphic3d_LightSet.cxx @@ -97,10 +97,6 @@ void Graphic3d_LightSet::CalculateNbShadows (Standard_Integer& theNb2DShadows, S for (NCollection_IndexedDataMap::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) diff --git a/src/Graphic3d/Graphic3d_ShaderManager.cxx b/src/Graphic3d/Graphic3d_ShaderManager.cxx index 284d6a1f54..dc9b19ae81 100644 --- a/src/Graphic3d/Graphic3d_ShaderManager.cxx +++ b/src/Graphic3d/Graphic3d_ShaderManager.cxx @@ -1720,6 +1720,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con 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) { diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index e370a81576..722ed2fe3f 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -474,12 +474,9 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo { 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 { @@ -491,15 +488,12 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo { 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 { @@ -952,9 +946,21 @@ void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx) 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); + } } // ======================================================================= diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 0dd894ff1d..91d6d4a054 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -576,6 +577,25 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr 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()); + } } // ======================================================================= diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index f8dc9da70b..ba898e8df6 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -801,6 +801,7 @@ protected: mutable NCollection_Array1 myLightTypeArray; mutable NCollection_Array1 myLightParamsArray; mutable NCollection_Array1 myShadowMatArray; + mutable NCollection_Array1 myShadowRangeArray; mutable NCollection_Array1 myClipPlaneArray; mutable NCollection_Array1 myClipPlaneArrayFfp; mutable NCollection_Array1 myClipChainArray; diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx index 211aa13e48..4088c4e591 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/OpenGl/OpenGl_ShaderProgram.cxx @@ -62,6 +62,7 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] = "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 diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx index 73d588b462..f14a2e0034 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.hxx +++ b/src/OpenGl/OpenGl_ShaderProgram.hxx @@ -61,6 +61,7 @@ enum OpenGl_StateVariable 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, diff --git a/src/OpenGl/OpenGl_ShadowMap.cxx b/src/OpenGl/OpenGl_ShadowMap.cxx index 296d205be8..9d3f2c7179 100644 --- a/src/OpenGl/OpenGl_ShadowMap.cxx +++ b/src/OpenGl/OpenGl_ShadowMap.cxx @@ -138,13 +138,12 @@ bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView, 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; diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 1e00967edc..b0c00e60f9 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -524,12 +524,12 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& 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, + 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 diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 22ee42fad0..34fe02ac05 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -1732,7 +1732,7 @@ void OpenGl_View::Redraw() 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) { diff --git a/src/Shaders/LightPointShadow.glsl b/src/Shaders/LightPointShadow.glsl index 463287c40e..318ad94982 100644 --- a/src/Shaders/LightPointShadow.glsl +++ b/src/Shaders/LightPointShadow.glsl @@ -1,6 +1,5 @@ //! 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) @@ -11,8 +10,9 @@ float occLightPointShadow (in samplerCube theShadow, 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. diff --git a/src/Shaders/Shaders_LightPointShadow_glsl.pxx b/src/Shaders/Shaders_LightPointShadow_glsl.pxx index 1389d6ba32..14713875e4 100644 --- a/src/Shaders/Shaders_LightPointShadow_glsl.pxx +++ b/src/Shaders/Shaders_LightPointShadow_glsl.pxx @@ -14,8 +14,9 @@ static const char Shaders_LightPointShadow_glsl[] = " 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" diff --git a/tests/opengl/data/shadows/pointlight b/tests/opengl/data/shadows/pointlight index 0c5ae9fcd4..e3ff8e7514 100644 --- a/tests/opengl/data/shadows/pointlight +++ b/tests/opengl/data/shadows/pointlight @@ -28,7 +28,7 @@ vsetcolor b6 SALMON3 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