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

0032042: Visualization, TKOpenGl - pre-multiply headlight flag into light source position

OpenGl_ShaderManager::pushLightSourceState() now pre-multiplies headlight transformation.
Built-in shading GLSL programs have been updated to remove special handling if headlight flag;
also removed redundant pre-normalization of light source direction
(already normalized implicitly by Graphic3d_CLight interface).

Graphic3d_CLight::SetHeadlight() now raises exception in case of ambient light type.
OpenGl_ShaderManager::SetLastView() - removed unused property.
This commit is contained in:
kgv 2021-01-08 00:48:29 +03:00 committed by bugmaster
parent 0f26ed5476
commit 37f80e163c
8 changed files with 81 additions and 107 deletions

View File

@ -114,6 +114,10 @@ void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
// =======================================================================
void Graphic3d_CLight::SetHeadlight (Standard_Boolean theValue)
{
if (myType == Graphic3d_TOLS_AMBIENT)
{
throw Standard_ProgramError ("Graphic3d_CLight::SetHeadlight() is not applicable to ambient light");
}
updateRevisionIf (myIsHeadlight != theValue);
myIsHeadlight = theValue;
}

View File

@ -202,6 +202,9 @@ public:
//! Returns direction of directional/spot light and range for positional/spot light in alpha channel.
const Graphic3d_Vec4& PackedDirectionRange() const { return myDirection; }
//! Returns direction of directional/spot light.
Graphic3d_Vec3 PackedDirection() const { return myDirection.xyz(); }
//! @return modification counter
Standard_Size Revision() const { return myRevision; }

View File

@ -110,12 +110,7 @@ const char THE_FUNC_pointLight[] =
EOL" in vec3 thePoint,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = occLight_Position (theId);"
EOL" if (!occLight_IsHeadlight (theId))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
EOL" }"
EOL" aLight -= thePoint;"
EOL" vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;"
EOL
EOL" float aDist = length (aLight);"
EOL" float aRange = occLight_Range (theId);"
@ -147,12 +142,7 @@ const char THE_FUNC_PBR_pointLight[] =
EOL" in vec3 thePoint,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = occLight_Position (theId);"
EOL" if (occLight_IsHeadlight (theId))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 1.0));"
EOL" }"
EOL" aLight -= thePoint;"
EOL" vec3 aLight = occLight_Position (theId) - thePoint;"
EOL
EOL" float aDist = length (aLight);"
EOL" float aRange = occLight_Range (theId);"
@ -175,14 +165,7 @@ const char THE_FUNC_spotLight[] =
EOL" in vec3 thePoint,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = occLight_Position (theId);"
EOL" vec3 aSpotDir = occLight_SpotDirection (theId);"
EOL" if (!occLight_IsHeadlight (theId))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
EOL" aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));"
EOL" }"
EOL" aLight -= thePoint;"
EOL" vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;"
EOL
EOL" float aDist = length (aLight);"
EOL" float aRange = occLight_Range (theId);"
@ -190,6 +173,7 @@ const char THE_FUNC_spotLight[] =
EOL" if (anAtten <= 0.0) return;"
EOL" aLight /= aDist;"
EOL
EOL" vec3 aSpotDir = vec3 (occWorldViewMatrix * vec4 (occLight_SpotDirection (theId), 0.0));"
EOL" aSpotDir = normalize (aSpotDir);"
// light cone
EOL" float aCosA = dot (aSpotDir, -aLight);"
@ -228,14 +212,7 @@ const char THE_FUNC_spotLight[] =
EOL" in vec3 thePoint,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = occLight_Position (theId);"
EOL" vec3 aSpotDir = occLight_SpotDirection (theId);"
EOL" if (occLight_IsHeadlight (theId))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 1.0));"
EOL" aSpotDir = vec3 (occWorldViewMatrixInverse * vec4 (aSpotDir, 0.0));"
EOL" }"
EOL" aLight -= thePoint;"
EOL" vec3 aLight = occLight_Position (theId) - thePoint;"
EOL
EOL" float aDist = length (aLight);"
EOL" float aRange = occLight_Range (theId);"
@ -243,7 +220,7 @@ const char THE_FUNC_spotLight[] =
EOL" if (anAtten <= 0.0) return;"
EOL" aLight /= aDist;"
EOL
EOL" aSpotDir = normalize (aSpotDir);"
EOL" vec3 aSpotDir = occLight_SpotDirection (theId);"
// light cone
EOL" float aCosA = dot (aSpotDir, -aLight);"
EOL" float aRelativeAngle = 2.0 * acos(aCosA) / occLight_SpotCutOff(theId);"
@ -274,11 +251,7 @@ const char THE_FUNC_directionalLight[] =
EOL" in vec3 theView,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = normalize (occLight_Position (theId));"
EOL" if (!occLight_IsHeadlight (theId))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
EOL" }"
EOL" vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));"
EOL
EOL" vec3 aHalf = normalize (aLight + theView);"
EOL
@ -303,11 +276,7 @@ const char THE_FUNC_PBR_directionalLight[] =
EOL" in vec3 theView,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = normalize (occLight_Position (theId));"
EOL" if (occLight_IsHeadlight (theId))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 0.0));"
EOL" }"
EOL" vec3 aLight = occLight_Position (theId);"
EOL
EOL" theNormal = theIsFront ? theNormal : -theNormal;"
EOL" DirectLighting += occPBRIllumination (theView, aLight, theNormal,"
@ -323,11 +292,7 @@ const char THE_FUNC_directionalLightFirst[] =
EOL" in vec3 theView,"
EOL" in bool theIsFront)"
EOL"{"
EOL" vec3 aLight = normalize (occLight_Position(0));"
EOL" if (!occLight_IsHeadlight (0))"
EOL" {"
EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
EOL" }"
EOL" vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (0), 0.0));"
EOL
EOL" vec3 aHalf = normalize (aLight + theView);"
EOL
@ -546,8 +511,7 @@ OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
myUnlitPrograms (new OpenGl_SetOfPrograms()),
myContext (theContext),
mySRgbState (theContext->ToRenderSRGB()),
myHasLocalOrigin (Standard_False),
myLastView (NULL)
myHasLocalOrigin (Standard_False)
{
//
}
@ -910,33 +874,60 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
aLightType = aLight.Type();
aLightParams.Color = aLight.PackedColor();
aLightParams.Color.a() = aLight.Intensity(); // used by PBR and ignored by old shading model
if (aLight.Type() == Graphic3d_TOLS_DIRECTIONAL)
{
aLightParams.Position = -aLight.PackedDirectionRange();
}
else if (!aLight.IsHeadlight())
{
aLightParams.Position.x() = static_cast<float>(aLight.Position().X() - myLocalOrigin.X());
aLightParams.Position.y() = static_cast<float>(aLight.Position().Y() - myLocalOrigin.Y());
aLightParams.Position.z() = static_cast<float>(aLight.Position().Z() - myLocalOrigin.Z());
}
else
{
aLightParams.Position.x() = static_cast<float>(aLight.Position().X());
aLightParams.Position.y() = static_cast<float>(aLight.Position().Y());
aLightParams.Position.z() = static_cast<float>(aLight.Position().Z());
}
aLightParams.Position.w() = aLight.IsHeadlight() ? 1.0f : 0.0f;
if (aLight.Type() == Graphic3d_TOLS_SPOT)
{
aLightParams.Direction = aLight.PackedDirectionRange();
}
if (aLight.Type() == Graphic3d_TOLS_POSITIONAL)
{
aLightParams.Direction.w() = aLight.Range();
}
aLightParams.Parameters = aLight.PackedParams();
switch (aLight.Type())
{
case Graphic3d_TOLS_AMBIENT:
{
break;
}
case Graphic3d_TOLS_DIRECTIONAL:
{
if (aLight.IsHeadlight())
{
const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
aLightParams.Position = anOrientInv * Graphic3d_Vec4 (-aLight.PackedDirection(), 0.0f);
}
else
{
aLightParams.Position = Graphic3d_Vec4 (-aLight.PackedDirection(), 0.0f);
}
break;
}
case Graphic3d_TOLS_SPOT:
{
if (aLight.IsHeadlight())
{
const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
aLightParams.Direction = anOrientInv * Graphic3d_Vec4 (aLight.PackedDirection(), 0.0f);
}
else
{
aLightParams.Direction = Graphic3d_Vec4 (aLight.PackedDirection(), 0.0f);
}
}
Standard_FALLTHROUGH
case Graphic3d_TOLS_POSITIONAL:
{
if (aLight.IsHeadlight())
{
aLightParams.Position.x() = static_cast<float>(aLight.Position().X());
aLightParams.Position.y() = static_cast<float>(aLight.Position().Y());
aLightParams.Position.z() = static_cast<float>(aLight.Position().Z());
const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
aLightParams.Position = anOrientInv * Graphic3d_Vec4 (aLightParams.Position.xyz(), 1.0f);
}
else
{
aLightParams.Position.x() = static_cast<float>(aLight.Position().X() - myLocalOrigin.X());
aLightParams.Position.y() = static_cast<float>(aLight.Position().Y() - myLocalOrigin.Y());
aLightParams.Position.z() = static_cast<float>(aLight.Position().Z() - myLocalOrigin.Z());
aLightParams.Position.w() = 0.0f;
}
aLightParams.Direction.w() = aLight.Range();
break;
}
}
++aLightsNb;
}
@ -1426,10 +1417,10 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
{
const Handle(OpenGl_ShaderProgram)& aProgram = !theProgram.IsNull() ? theProgram : myFfpProgram;
PushClippingState (aProgram);
PushLightSourceState (aProgram); // should be before PushWorldViewState()
PushWorldViewState (aProgram);
PushModelWorldState (aProgram);
PushProjectionState (aProgram);
PushLightSourceState (aProgram);
PushMaterialState (aProgram);
PushOitState (aProgram);

View File

@ -293,9 +293,11 @@ public:
Standard_EXPORT void UpdateLightSourceState();
//! Pushes current state of OCCT light sources to specified program (only on state change).
//! Note that light sources definition depends also on WorldViewState.
void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
{
if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
|| myWorldViewState.Index() != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
{
pushLightSourceState (theProgram);
}
@ -540,19 +542,6 @@ public:
//! Sets shading model.
Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel);
//! Sets last view manger used with.
//! Helps to handle matrix states in multi-view configurations.
void SetLastView (const OpenGl_View* theLastView)
{
myLastView = theLastView;
}
//! Returns true when provided view is the same as cached one.
bool IsSameView (const OpenGl_View* theView) const
{
return myLastView == theView;
}
protected:
//! Define clipping planes program bits.
@ -849,10 +838,6 @@ protected:
mutable NCollection_Array1<OpenGl_Vec4d> myClipPlaneArrayFfp;
mutable NCollection_Array1<Standard_Integer> myClipChainArray;
private:
const OpenGl_View* myLastView; //!< Pointer to the last view shader manager used with
};
DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)

View File

@ -129,7 +129,6 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
myWorkspace = new OpenGl_Workspace (this, NULL);
Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
aLight->SetHeadlight (false);
aLight->SetColor (Quantity_NOC_WHITE);
myLights = new Graphic3d_LightSet();
myNoShadingLight = new Graphic3d_LightSet();
@ -2063,15 +2062,6 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
{
aContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
}
// ==============================================================
// Step 6: Keep shader manager informed about last View
// ==============================================================
if (!aManager.IsNull())
{
aManager->SetLastView (this);
}
}
// =======================================================================

View File

@ -147,10 +147,10 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
//! Intensity of light source (>= 0), float.
#define occLight_Intensity(theId) occLightSources[theId * 4 + 0].a
//! Is light a headlight, bool?
#define occLight_IsHeadlight(theId) (occLightSources[theId * 4 + 1].w > 0.5)
//! Is light a headlight, bool? DEPRECATED method.
#define occLight_IsHeadlight(theId) false
//! Position of specified light source, vec3.
//! Position of specified light source or direction of directional light source, vec3.
#define occLight_Position(theId) occLightSources[theId * 4 + 1].xyz
//! Direction of specified spot light source, vec3.

View File

@ -150,10 +150,10 @@ static const char Shaders_Declarations_glsl[] =
"//! Intensity of light source (>= 0), float.\n"
"#define occLight_Intensity(theId) occLightSources[theId * 4 + 0].a\n"
"\n"
"//! Is light a headlight, bool?\n"
"#define occLight_IsHeadlight(theId) (occLightSources[theId * 4 + 1].w > 0.5)\n"
"//! Is light a headlight, bool? DEPRECATED method.\n"
"#define occLight_IsHeadlight(theId) false\n"
"\n"
"//! Position of specified light source, vec3.\n"
"//! Position of specified light source or direction of directional light source, vec3.\n"
"#define occLight_Position(theId) occLightSources[theId * 4 + 1].xyz\n"
"\n"
"//! Direction of specified spot light source, vec3.\n"

View File

@ -11562,6 +11562,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
}
theDI << "\n";
{
theDI << "perfCounters:";
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)