mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 03:40:14 +00:00
Add clipping planes when allow shadow map overlap is enabled
This commit is contained in:
parent
25e92481f4
commit
db707a31ec
@ -1243,10 +1243,16 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<osg::Plane> extraPlanes;
|
||||||
if (settings->getMultipleShadowMapHint() == ShadowSettings::CASCADED)
|
if (settings->getMultipleShadowMapHint() == ShadowSettings::CASCADED)
|
||||||
cropShadowCameraToMainFrustum(frustum, camera, cascaseNear, cascadeFar);
|
{
|
||||||
|
cropShadowCameraToMainFrustum(frustum, camera, cascaseNear, cascadeFar, extraPlanes);
|
||||||
|
for (auto plane : extraPlanes)
|
||||||
|
local_polytope.getPlaneList().push_back(plane);
|
||||||
|
local_polytope.setupMask();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
cropShadowCameraToMainFrustum(frustum, camera, reducedNear, reducedFar);
|
cropShadowCameraToMainFrustum(frustum, camera, reducedNear, reducedFar, extraPlanes);
|
||||||
|
|
||||||
osg::ref_ptr<VDSMCameraCullCallback> vdsmCallback = new VDSMCameraCullCallback(this, local_polytope);
|
osg::ref_ptr<VDSMCameraCullCallback> vdsmCallback = new VDSMCameraCullCallback(this, local_polytope);
|
||||||
camera->setCullCallback(vdsmCallback.get());
|
camera->setCullCallback(vdsmCallback.get());
|
||||||
@ -1873,16 +1879,12 @@ struct ConvexHull
|
|||||||
{
|
{
|
||||||
typedef std::set<osg::Vec3d> VertexSet;
|
typedef std::set<osg::Vec3d> VertexSet;
|
||||||
|
|
||||||
double lowestPoint = DBL_MAX;
|
|
||||||
|
|
||||||
// Collect the set of vertices
|
// Collect the set of vertices
|
||||||
VertexSet vertices;
|
VertexSet vertices;
|
||||||
for (Edge edge : _edges)
|
for (Edge edge : _edges)
|
||||||
{
|
{
|
||||||
vertices.insert(edge.first);
|
vertices.insert(edge.first);
|
||||||
vertices.insert(edge.second);
|
vertices.insert(edge.second);
|
||||||
lowestPoint = osg::minimum(lowestPoint, edge.first.z());
|
|
||||||
lowestPoint = osg::minimum(lowestPoint, edge.second.z());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertices.size() == 0)
|
if (vertices.size() == 0)
|
||||||
@ -1893,19 +1895,18 @@ struct ConvexHull
|
|||||||
VertexSet extremeVerticesSet(extremeVertices.cbegin(), extremeVertices.cend());
|
VertexSet extremeVerticesSet(extremeVertices.cbegin(), extremeVertices.cend());
|
||||||
|
|
||||||
// Add their extrusions to the final edge collection
|
// Add their extrusions to the final edge collection
|
||||||
|
// We extrude as far as -1.5 as the coordinate space shouldn't ever put any shadow casters further than -1.0
|
||||||
Edges finalEdges;
|
Edges finalEdges;
|
||||||
// Add edges towards -Z
|
// Add edges towards -Z
|
||||||
for (auto vertex : extremeVertices)
|
for (auto vertex : extremeVertices)
|
||||||
finalEdges.push_back(Edge(vertex, osg::Vec3d(vertex.x(), vertex.y(), -DBL_MAX)));
|
finalEdges.push_back(Edge(vertex, osg::Vec3d(vertex.x(), vertex.y(), -1.5)));
|
||||||
// Add edge loop to 'seal' the hull
|
// Add edge loop to 'seal' the hull
|
||||||
for (auto itr = extremeVertices.cbegin(); itr != extremeVertices.cend() - 1; ++itr)
|
for (auto itr = extremeVertices.cbegin(); itr != extremeVertices.cend() - 1; ++itr)
|
||||||
finalEdges.push_back(Edge(osg::Vec3d(itr->x(), itr->y(), -DBL_MAX), osg::Vec3d((itr + 1)->x(), (itr + 1)->y(), -DBL_MAX)));
|
finalEdges.push_back(Edge(osg::Vec3d(itr->x(), itr->y(), -1.5), osg::Vec3d((itr + 1)->x(), (itr + 1)->y(), -1.5)));
|
||||||
// The convex hull algorithm we are using sometimes places a point at both ends of the vector, so we don't always need to add the last edge separately.
|
// The convex hull algorithm we are using sometimes places a point at both ends of the vector, so we don't always need to add the last edge separately.
|
||||||
if (extremeVertices.front() != extremeVertices.back())
|
if (extremeVertices.front() != extremeVertices.back())
|
||||||
finalEdges.push_back(Edge(osg::Vec3d(extremeVertices.front().x(), extremeVertices.front().y(), -DBL_MAX), osg::Vec3d(extremeVertices.back().x(), extremeVertices.back().y(), -DBL_MAX)));
|
finalEdges.push_back(Edge(osg::Vec3d(extremeVertices.front().x(), extremeVertices.front().y(), -1.5), osg::Vec3d(extremeVertices.back().x(), extremeVertices.back().y(), -1.5)));
|
||||||
|
|
||||||
// Just in case using -DBL_MAX upsets some of the maths, we pretend we've only extended the volume by a little bit.
|
|
||||||
lowestPoint -= 1.0;
|
|
||||||
// Remove internal edges connected to extreme vertices
|
// Remove internal edges connected to extreme vertices
|
||||||
for (auto vertex : extremeVertices)
|
for (auto vertex : extremeVertices)
|
||||||
{
|
{
|
||||||
@ -1917,7 +1918,7 @@ struct ConvexHull
|
|||||||
else if (edge.second == vertex)
|
else if (edge.second == vertex)
|
||||||
connectedVertices.push_back(edge.first);
|
connectedVertices.push_back(edge.first);
|
||||||
}
|
}
|
||||||
connectedVertices.push_back(osg::Vec3d(vertex.x(), vertex.y(), lowestPoint));
|
connectedVertices.push_back(osg::Vec3d(vertex.x(), vertex.y(), -1.5));
|
||||||
|
|
||||||
Vertices unwantedEdgeEnds = findInternalEdges(vertex, connectedVertices);
|
Vertices unwantedEdgeEnds = findInternalEdges(vertex, connectedVertices);
|
||||||
for (auto edgeEnd : unwantedEdgeEnds)
|
for (auto edgeEnd : unwantedEdgeEnds)
|
||||||
@ -2381,11 +2382,12 @@ struct RenderLeafBounds
|
|||||||
double min_z, max_z;
|
double min_z, max_z;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MWShadowTechnique::cropShadowCameraToMainFrustum(Frustum& frustum, osg::Camera* camera, double viewNear, double viewFar)
|
bool MWShadowTechnique::cropShadowCameraToMainFrustum(Frustum& frustum, osg::Camera* camera, double viewNear, double viewFar, std::vector<osg::Plane>& planeList)
|
||||||
{
|
{
|
||||||
osg::Matrixd light_p = camera->getProjectionMatrix();
|
osg::Matrixd light_p = camera->getProjectionMatrix();
|
||||||
osg::Matrixd light_v = camera->getViewMatrix();
|
osg::Matrixd light_v = camera->getViewMatrix();
|
||||||
osg::Matrixd light_vp = light_v * light_p;
|
osg::Matrixd light_vp = light_v * light_p;
|
||||||
|
osg::Matrixd oldLightP = light_p;
|
||||||
|
|
||||||
ConvexHull convexHull;
|
ConvexHull convexHull;
|
||||||
convexHull.setToFrustum(frustum);
|
convexHull.setToFrustum(frustum);
|
||||||
@ -2433,6 +2435,18 @@ bool MWShadowTechnique::cropShadowCameraToMainFrustum(Frustum& frustum, osg::Cam
|
|||||||
|
|
||||||
light_p.postMult(m);
|
light_p.postMult(m);
|
||||||
camera->setProjectionMatrix(light_p);
|
camera->setProjectionMatrix(light_p);
|
||||||
|
|
||||||
|
convexHull.transform(osg::Matrixd::inverse(oldLightP));
|
||||||
|
|
||||||
|
xMin = convexHull.min(0);
|
||||||
|
xMax = convexHull.max(0);
|
||||||
|
yMin = convexHull.min(1);
|
||||||
|
yMax = convexHull.max(1);
|
||||||
|
|
||||||
|
planeList.push_back(osg::Plane(0.0, -1.0, 0.0, yMax));
|
||||||
|
planeList.push_back(osg::Plane(0.0, 1.0, 0.0, -yMin));
|
||||||
|
planeList.push_back(osg::Plane(-1.0, 0.0, 0.0, xMax));
|
||||||
|
planeList.push_back(osg::Plane(1.0, 0.0, 0.0, -xMin));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -205,7 +205,7 @@ namespace SceneUtil {
|
|||||||
|
|
||||||
virtual bool computeShadowCameraSettings(Frustum& frustum, LightData& positionedLight, osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix);
|
virtual bool computeShadowCameraSettings(Frustum& frustum, LightData& positionedLight, osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix);
|
||||||
|
|
||||||
virtual bool cropShadowCameraToMainFrustum(Frustum& frustum, osg::Camera* camera, double viewNear, double viewFar);
|
virtual bool cropShadowCameraToMainFrustum(Frustum& frustum, osg::Camera* camera, double viewNear, double viewFar, std::vector<osg::Plane>& planeList);
|
||||||
|
|
||||||
virtual bool adjustPerspectiveShadowMapCameraSettings(osgUtil::RenderStage* renderStage, Frustum& frustum, LightData& positionedLight, osg::Camera* camera, double viewNear, double viewFar);
|
virtual bool adjustPerspectiveShadowMapCameraSettings(osgUtil::RenderStage* renderStage, Frustum& frustum, LightData& positionedLight, osg::Camera* camera, double viewNear, double viewFar);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user