mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-05-04 07:47:59 +03:00
initial reverse-z depth implementation
This commit is contained in:
parent
10d100f205
commit
70fac33940
46 changed files with 614 additions and 92 deletions
|
@ -226,6 +226,18 @@ namespace NifOsg
|
|||
return sIntersectionDisabledNodeMask;
|
||||
}
|
||||
|
||||
bool Loader::sReverseZ = false;
|
||||
|
||||
void Loader::setReverseZ(bool reverseZ)
|
||||
{
|
||||
sReverseZ = reverseZ;
|
||||
}
|
||||
|
||||
bool Loader::getReverseZ()
|
||||
{
|
||||
return sReverseZ;
|
||||
}
|
||||
|
||||
class LoaderImpl
|
||||
{
|
||||
public:
|
||||
|
@ -1823,7 +1835,7 @@ namespace NifOsg
|
|||
// Depth test flag
|
||||
stateset->setMode(GL_DEPTH_TEST, zprop->flags&1 ? osg::StateAttribute::ON
|
||||
: osg::StateAttribute::OFF);
|
||||
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
|
||||
auto depth = SceneUtil::createDepth(Loader::getReverseZ());
|
||||
// Depth write flag
|
||||
depth->setWriteMask((zprop->flags>>1)&1);
|
||||
// Morrowind ignores depth test function
|
||||
|
|
|
@ -51,10 +51,14 @@ namespace NifOsg
|
|||
static void setIntersectionDisabledNodeMask(unsigned int mask);
|
||||
static unsigned int getIntersectionDisabledNodeMask();
|
||||
|
||||
static void setReverseZ(bool reverseZ);
|
||||
static bool getReverseZ();
|
||||
|
||||
private:
|
||||
static unsigned int sHiddenNodeMask;
|
||||
static unsigned int sIntersectionDisabledNodeMask;
|
||||
static bool sShowMarkers;
|
||||
static bool sReverseZ;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -275,6 +275,16 @@ namespace Resource
|
|||
return mClampLighting;
|
||||
}
|
||||
|
||||
void SceneManager::setReverseZ(bool reverseZ)
|
||||
{
|
||||
mReverseZ = reverseZ;
|
||||
}
|
||||
|
||||
bool SceneManager::getReverseZ() const
|
||||
{
|
||||
return mReverseZ;
|
||||
}
|
||||
|
||||
void SceneManager::setAutoUseNormalMaps(bool use)
|
||||
{
|
||||
mAutoUseNormalMaps = use;
|
||||
|
|
|
@ -92,6 +92,9 @@ namespace Resource
|
|||
void setClampLighting(bool clamp);
|
||||
bool getClampLighting() const;
|
||||
|
||||
void setReverseZ(bool reverseZ);
|
||||
bool getReverseZ() const;
|
||||
|
||||
/// @see ShaderVisitor::setAutoUseNormalMaps
|
||||
void setAutoUseNormalMaps(bool use);
|
||||
|
||||
|
@ -202,6 +205,7 @@ namespace Resource
|
|||
SceneUtil::LightingMethod mLightingMethod;
|
||||
SceneUtil::LightManager::SupportedMethods mSupportedLightingMethods;
|
||||
bool mConvertAlphaTestToAlphaToCoverage;
|
||||
bool mReverseZ;
|
||||
|
||||
osg::ref_ptr<MultiObjectCache> mInstanceCache;
|
||||
|
||||
|
|
|
@ -23,10 +23,13 @@
|
|||
#include <osg/Geometry>
|
||||
#include <osg/io_utils>
|
||||
#include <osg/Depth>
|
||||
#include <osg/ClipControl>
|
||||
|
||||
#include <sstream>
|
||||
#include "shadowsbin.hpp"
|
||||
|
||||
#include <components/sceneutil/util.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace osgShadow;
|
||||
|
@ -347,6 +350,11 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|||
_projectionMatrix = cv->getProjectionMatrix();
|
||||
}
|
||||
|
||||
bool isOrthographicViewFrustum(const osg::Matrix& m)
|
||||
{
|
||||
return m(0,3)==0.0 && m(1,3)==0.0 && m(2,3)==0.0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MWShadowTechnique::ComputeLightSpaceBounds::ComputeLightSpaceBounds(osg::Viewport* viewport, const osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix) :
|
||||
|
@ -890,6 +898,16 @@ void SceneUtil::MWShadowTechnique::disableFrontFaceCulling()
|
|||
}
|
||||
}
|
||||
|
||||
void SceneUtil::MWShadowTechnique::enableReverseZ()
|
||||
{
|
||||
_reverseZ = true;
|
||||
}
|
||||
|
||||
void SceneUtil::MWShadowTechnique::disableReverseZ()
|
||||
{
|
||||
_reverseZ = false;
|
||||
}
|
||||
|
||||
void SceneUtil::MWShadowTechnique::setupCastingShader(Shader::ShaderManager & shaderManager)
|
||||
{
|
||||
// This can't be part of the constructor as OSG mandates that there be a trivial constructor available
|
||||
|
@ -970,6 +988,9 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
|||
return;
|
||||
}
|
||||
|
||||
osg::Matrix shadowProj;
|
||||
cv.getCurrentCamera()->getUserValue("shadowProj", shadowProj);
|
||||
|
||||
ViewDependentData* vdd = getViewDependentData(&cv);
|
||||
|
||||
if (!vdd)
|
||||
|
@ -985,34 +1006,41 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
|||
|
||||
osg::CullSettings::ComputeNearFarMode cachedNearFarMode = cv.getComputeNearFarMode();
|
||||
|
||||
osg::RefMatrix& viewProjectionMatrix = *cv.getProjectionMatrix();
|
||||
|
||||
// check whether this main views projection is perspective or orthographic
|
||||
bool orthographicViewFrustum = viewProjectionMatrix(0,3)==0.0 &&
|
||||
viewProjectionMatrix(1,3)==0.0 &&
|
||||
viewProjectionMatrix(2,3)==0.0;
|
||||
|
||||
double minZNear = 0.0;
|
||||
double maxZFar = dbl_max;
|
||||
bool orthographicViewFrustum;
|
||||
|
||||
if (cachedNearFarMode==osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
|
||||
if (_reverseZ)
|
||||
{
|
||||
double left, right, top, bottom;
|
||||
if (orthographicViewFrustum)
|
||||
{
|
||||
viewProjectionMatrix.getOrtho(left, right, bottom, top, minZNear, maxZFar);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewProjectionMatrix.getFrustum(left, right, bottom, top, minZNear, maxZFar);
|
||||
}
|
||||
OSG_INFO<<"minZNear="<<minZNear<<", maxZFar="<<maxZFar<<std::endl;
|
||||
cv.getCurrentCamera()->getUserValue("near", minZNear);
|
||||
cv.getCurrentCamera()->getUserValue("far", maxZFar);
|
||||
orthographicViewFrustum = isOrthographicViewFrustum(shadowProj);
|
||||
}
|
||||
|
||||
// set the compute near/far mode to the highest quality setting to ensure we push the near plan out as far as possible
|
||||
if (settings->getComputeNearFarModeOverride()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
|
||||
else
|
||||
{
|
||||
cv.setComputeNearFarMode(settings->getComputeNearFarModeOverride());
|
||||
osg::RefMatrix& viewProjectionMatrix = *cv.getProjectionMatrix();
|
||||
|
||||
// check whether this main views projection is perspective or orthographic
|
||||
orthographicViewFrustum = isOrthographicViewFrustum(viewProjectionMatrix);
|
||||
|
||||
if (cachedNearFarMode==osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
|
||||
{
|
||||
double left, right, top, bottom;
|
||||
if (orthographicViewFrustum)
|
||||
{
|
||||
viewProjectionMatrix.getOrtho(left, right, bottom, top, minZNear, maxZFar);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewProjectionMatrix.getFrustum(left, right, bottom, top, minZNear, maxZFar);
|
||||
}
|
||||
}
|
||||
|
||||
// set the compute near/far mode to the highest quality setting to ensure we push the near plan out as far as possible
|
||||
if (settings->getComputeNearFarModeOverride()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
|
||||
{
|
||||
cv.setComputeNearFarMode(settings->getComputeNearFarModeOverride());
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Traverse main scene graph
|
||||
|
@ -1024,6 +1052,9 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
|||
|
||||
cv.popStateSet();
|
||||
|
||||
if (_reverseZ)
|
||||
cv.pushProjectionMatrix(new osg::RefMatrix(shadowProj));
|
||||
|
||||
if (cv.getComputeNearFarMode()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
|
||||
{
|
||||
OSG_INFO<<"Just done main subgraph traversak"<<std::endl;
|
||||
|
@ -1063,7 +1094,8 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
|||
}
|
||||
|
||||
// return compute near far mode back to it's original settings
|
||||
cv.setComputeNearFarMode(cachedNearFarMode);
|
||||
if (!_reverseZ)
|
||||
cv.setComputeNearFarMode(cachedNearFarMode);
|
||||
|
||||
OSG_INFO<<"frustum.eye="<<frustum.eye<<", frustum.centerNearPlane, "<<frustum.centerNearPlane<<" distance = "<<(frustum.eye-frustum.centerNearPlane).length()<<std::endl;
|
||||
|
||||
|
@ -1448,6 +1480,8 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
|||
prepareStateSetForRenderingShadow(*vdd, cv.getTraversalNumber());
|
||||
}
|
||||
|
||||
if (_reverseZ)
|
||||
cv.popProjectionMatrix();
|
||||
// OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl;
|
||||
}
|
||||
|
||||
|
@ -1636,6 +1670,9 @@ void MWShadowTechnique::createShaders()
|
|||
_shadowCastingStateSet->addUniform(new osg::Uniform("alphaTestShadows", false));
|
||||
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
|
||||
depth->setWriteMask(true);
|
||||
osg::ref_ptr<osg::ClipControl> clipcontrol = new osg::ClipControl(osg::ClipControl::LOWER_LEFT, osg::ClipControl::NEGATIVE_ONE_TO_ONE);
|
||||
if (_reverseZ)
|
||||
_shadowCastingStateSet->setAttribute(clipcontrol, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
||||
_shadowCastingStateSet->setAttribute(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
||||
_shadowCastingStateSet->setMode(GL_DEPTH_CLAMP, osg::StateAttribute::ON);
|
||||
|
||||
|
|
|
@ -85,6 +85,10 @@ namespace SceneUtil {
|
|||
|
||||
virtual void disableFrontFaceCulling();
|
||||
|
||||
virtual void enableReverseZ();
|
||||
|
||||
virtual void disableReverseZ();
|
||||
|
||||
virtual void setupCastingShader(Shader::ShaderManager &shaderManager);
|
||||
|
||||
class ComputeLightSpaceBounds : public osg::NodeVisitor, public osg::CullStack
|
||||
|
@ -266,6 +270,8 @@ namespace SceneUtil {
|
|||
|
||||
float _shadowFadeStart = 0.0;
|
||||
|
||||
bool _reverseZ = false;
|
||||
|
||||
class DebugHUD final : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
|
||||
#include <iterator>
|
||||
|
||||
#include <components/sceneutil/util.hpp>
|
||||
|
||||
using namespace osgUtil;
|
||||
|
||||
namespace SceneUtil
|
||||
|
@ -107,6 +109,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
|||
MergeGeometryVisitor mgv(this);
|
||||
mgv.setTargetMaximumNumberOfVertices(1000000);
|
||||
mgv.setMergeAlphaBlending(_mergeAlphaBlending);
|
||||
mgv.setReverseZ(_reverseZ);
|
||||
mgv.setViewPoint(_viewPoint);
|
||||
node->accept(mgv);
|
||||
|
||||
|
@ -1560,7 +1563,7 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group)
|
|||
}
|
||||
if (_alphaBlendingActive && _mergeAlphaBlending && !geom->getStateSet())
|
||||
{
|
||||
osg::Depth* d = new osg::Depth;
|
||||
auto d = createDepth(_reverseZ);
|
||||
d->setWriteMask(0);
|
||||
geom->getOrCreateStateSet()->setAttribute(d);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class Optimizer
|
|||
|
||||
public:
|
||||
|
||||
Optimizer() : _mergeAlphaBlending(false) {}
|
||||
Optimizer() : _mergeAlphaBlending(false), _reverseZ(false) {}
|
||||
virtual ~Optimizer() {}
|
||||
|
||||
enum OptimizationOptions
|
||||
|
@ -119,6 +119,7 @@ class Optimizer
|
|||
};
|
||||
|
||||
void setMergeAlphaBlending(bool merge) { _mergeAlphaBlending = merge; }
|
||||
void setReverseZ(bool reverseZ) { _reverseZ = reverseZ; }
|
||||
void setViewPoint(const osg::Vec3f& viewPoint) { _viewPoint = viewPoint; }
|
||||
|
||||
/** Reset internal data to initial state - the getPermissibleOptionsMap is cleared.*/
|
||||
|
@ -257,6 +258,7 @@ class Optimizer
|
|||
|
||||
osg::Vec3f _viewPoint;
|
||||
bool _mergeAlphaBlending;
|
||||
bool _reverseZ;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -377,12 +379,18 @@ class Optimizer
|
|||
/// default to traversing all children.
|
||||
MergeGeometryVisitor(Optimizer* optimizer=0) :
|
||||
BaseOptimizerVisitor(optimizer, MERGE_GEOMETRY),
|
||||
_targetMaximumNumberOfVertices(10000), _alphaBlendingActive(false), _mergeAlphaBlending(false) {}
|
||||
_targetMaximumNumberOfVertices(10000), _alphaBlendingActive(false), _mergeAlphaBlending(false), _reverseZ(false) {}
|
||||
|
||||
void setMergeAlphaBlending(bool merge)
|
||||
{
|
||||
_mergeAlphaBlending = merge;
|
||||
}
|
||||
|
||||
void setReverseZ(bool reverseZ)
|
||||
{
|
||||
_reverseZ = reverseZ;
|
||||
}
|
||||
|
||||
void setViewPoint(const osg::Vec3f& viewPoint)
|
||||
{
|
||||
_viewPoint = viewPoint;
|
||||
|
@ -421,6 +429,7 @@ class Optimizer
|
|||
std::vector<osg::StateSet*> _stateSetStack;
|
||||
bool _alphaBlendingActive;
|
||||
bool _mergeAlphaBlending;
|
||||
bool _reverseZ;
|
||||
osg::Vec3f _viewPoint;
|
||||
};
|
||||
|
||||
|
|
|
@ -94,10 +94,12 @@ namespace SceneUtil
|
|||
}
|
||||
}
|
||||
|
||||
ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager) : mShadowedScene(new osgShadow::ShadowedScene),
|
||||
mShadowTechnique(new MWShadowTechnique),
|
||||
mOutdoorShadowCastingMask(outdoorShadowCastingMask),
|
||||
mIndoorShadowCastingMask(indoorShadowCastingMask)
|
||||
ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager, bool reverseZ)
|
||||
: mShadowedScene(new osgShadow::ShadowedScene)
|
||||
, mReverseZ(reverseZ)
|
||||
, mShadowTechnique(new MWShadowTechnique)
|
||||
, mOutdoorShadowCastingMask(outdoorShadowCastingMask)
|
||||
, mIndoorShadowCastingMask(indoorShadowCastingMask)
|
||||
{
|
||||
mShadowedScene->setShadowTechnique(mShadowTechnique);
|
||||
|
||||
|
@ -108,6 +110,9 @@ namespace SceneUtil
|
|||
mShadowSettings = mShadowedScene->getShadowSettings();
|
||||
setupShadowSettings();
|
||||
|
||||
if (mReverseZ)
|
||||
mShadowTechnique->enableReverseZ();
|
||||
|
||||
mShadowTechnique->setupCastingShader(shaderManager);
|
||||
|
||||
enableOutdoorMode();
|
||||
|
@ -180,4 +185,9 @@ namespace SceneUtil
|
|||
mShadowTechnique->enableShadows();
|
||||
mShadowSettings->setCastsShadowTraversalMask(mOutdoorShadowCastingMask);
|
||||
}
|
||||
|
||||
bool ShadowManager::getReverseZ() const
|
||||
{
|
||||
return mReverseZ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace SceneUtil
|
|||
|
||||
static Shader::ShaderManager::DefineMap getShadowsDisabledDefines();
|
||||
|
||||
ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager);
|
||||
ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager, bool reverseZ);
|
||||
|
||||
void setupShadowSettings();
|
||||
|
||||
|
@ -26,8 +26,11 @@ namespace SceneUtil
|
|||
void enableIndoorMode();
|
||||
|
||||
void enableOutdoorMode();
|
||||
|
||||
bool getReverseZ() const;
|
||||
protected:
|
||||
bool mEnableShadows;
|
||||
bool mReverseZ;
|
||||
|
||||
osg::ref_ptr<osgShadow::ShadowedScene> mShadowedScene;
|
||||
osg::ref_ptr<osgShadow::ShadowSettings> mShadowSettings;
|
||||
|
|
|
@ -285,4 +285,43 @@ bool attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::
|
|||
return addMSAAIntermediateTarget;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Depth> createDepth(bool reverseZ)
|
||||
{
|
||||
static osg::Depth::Function func = reverseZ ? osg::Depth::GEQUAL : osg::Depth::LEQUAL;
|
||||
return new osg::Depth(func);
|
||||
}
|
||||
|
||||
osg::Matrix getReversedZProjectionMatrixAsPerspectiveInf(double fov, double aspect, double near)
|
||||
{
|
||||
double A = 1.0/std::tan(osg::DegreesToRadians(fov)/2.0);
|
||||
return osg::Matrix(
|
||||
A/aspect, 0, 0, 0,
|
||||
0, A, 0, 0,
|
||||
0, 0, 0, -1,
|
||||
0, 0, near, 0
|
||||
);
|
||||
}
|
||||
|
||||
osg::Matrix getReversedZProjectionMatrixAsPerspective(double fov, double aspect, double near, double far)
|
||||
{
|
||||
double A = 1.0/std::tan(osg::DegreesToRadians(fov)/2.0);
|
||||
return osg::Matrix(
|
||||
A/aspect, 0, 0, 0,
|
||||
0, A, 0, 0,
|
||||
0, 0, far/(far-near)-1.0, -1,
|
||||
0, 0, -(far*near)/(far - near), 0
|
||||
);
|
||||
}
|
||||
|
||||
osg::Matrix getReversedZProjectionMatrixAsOrtho(double left, double right, double bottom, double top, double near, double far)
|
||||
{
|
||||
return osg::Matrix(
|
||||
2/(right-left), 0, 0, 0,
|
||||
0, 2/(top-bottom), 0, 0,
|
||||
0, 0, 1/(far-near), 0,
|
||||
(right+left)/(left-right), (top+bottom)/(bottom-top), far/(far-near), 1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <osg/NodeCallback>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Vec4f>
|
||||
#include <osg/Depth>
|
||||
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
|
@ -64,6 +65,23 @@ namespace SceneUtil
|
|||
|
||||
// Alpha-to-coverage requires a multisampled framebuffer, so we need to set that up for RTTs
|
||||
bool attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::Camera::BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face = 0, bool mipMapGeneration = false);
|
||||
|
||||
// Returns a suitable depth state attribute dependent on whether a reverse-z
|
||||
// depth buffer is in use.
|
||||
osg::ref_ptr<osg::Depth> createDepth(bool reverseZ);
|
||||
|
||||
// Returns a perspective projection matrix for use with a reversed z-buffer
|
||||
// and an infinite far plane. This is derived by mapping the default z-range
|
||||
// of [0,1] to [1,0], then taking the limit as far plane approaches
|
||||
// infinity.
|
||||
osg::Matrix getReversedZProjectionMatrixAsPerspectiveInf(double fov, double aspect, double near);
|
||||
|
||||
// Returns a perspective projection matrix for use with a reversed z-buffer.
|
||||
osg::Matrix getReversedZProjectionMatrixAsPerspective(double fov, double aspect, double near, double far);
|
||||
|
||||
// Returns an orthographic projection matrix for use with a reversed z-buffer.
|
||||
osg::Matrix getReversedZProjectionMatrixAsOrtho(double left, double right, double bottom, double top, double near, double far);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <osg/Material>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
// disable nonsense test against a worldsize bb what will always pass
|
||||
|
@ -62,7 +64,7 @@ namespace SceneUtil
|
|||
return waterGeom;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::StateSet> createSimpleWaterStateSet(float alpha, int renderBin)
|
||||
osg::ref_ptr<osg::StateSet> createSimpleWaterStateSet(float alpha, int renderBin, bool reverseZ)
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
||||
|
||||
|
@ -76,7 +78,7 @@ namespace SceneUtil
|
|||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||
|
||||
osg::ref_ptr<osg::Depth> depth (new osg::Depth);
|
||||
auto depth = createDepth(reverseZ);
|
||||
depth->setWriteMask(false);
|
||||
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace SceneUtil
|
|||
{
|
||||
osg::ref_ptr<osg::Geometry> createWaterGeometry(float size, int segments, float textureRepeats);
|
||||
|
||||
osg::ref_ptr<osg::StateSet> createSimpleWaterStateSet(float alpha, int renderBin);
|
||||
osg::ref_ptr<osg::StateSet> createSimpleWaterStateSet(float alpha, int renderBin, bool reverseZ);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -163,7 +163,7 @@ std::vector<osg::ref_ptr<osg::StateSet> > ChunkManager::createPasses(float chunk
|
|||
|
||||
float blendmapScale = mStorage->getBlendmapScale(chunkSize);
|
||||
|
||||
return ::Terrain::createPasses(useShaders, &mSceneManager->getShaderManager(), layers, blendmapTextures, blendmapScale, blendmapScale);
|
||||
return ::Terrain::createPasses(useShaders, mSceneManager, layers, blendmapTextures, blendmapScale, blendmapScale);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> ChunkManager::createChunk(float chunkSize, const osg::Vec2f &chunkCenter, unsigned char lod, unsigned int lodFlags, bool compile)
|
||||
|
@ -219,7 +219,7 @@ osg::ref_ptr<osg::Node> ChunkManager::createChunk(float chunkSize, const osg::Ve
|
|||
layer.mDiffuseMap = compositeMap->mTexture;
|
||||
layer.mParallax = false;
|
||||
layer.mSpecular = false;
|
||||
geometry->setPasses(::Terrain::createPasses(mSceneManager->getForceShaders() || !mSceneManager->getClampLighting(), &mSceneManager->getShaderManager(), std::vector<TextureLayer>(1, layer), std::vector<osg::ref_ptr<osg::Texture2D> >(), 1.f, 1.f));
|
||||
geometry->setPasses(::Terrain::createPasses(mSceneManager->getForceShaders() || !mSceneManager->getClampLighting(), mSceneManager, std::vector<TextureLayer>(1, layer), std::vector<osg::ref_ptr<osg::Texture2D> >(), 1.f, 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
#include <osg/TexMat>
|
||||
#include <osg/BlendFunc>
|
||||
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
#include <components/sceneutil/util.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
|
@ -95,19 +97,18 @@ namespace
|
|||
class LequalDepth
|
||||
{
|
||||
public:
|
||||
static const osg::ref_ptr<osg::Depth>& value()
|
||||
static const osg::ref_ptr<osg::Depth>& value(bool reverseZ)
|
||||
{
|
||||
static LequalDepth instance;
|
||||
static LequalDepth instance(reverseZ);
|
||||
return instance.mValue;
|
||||
}
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Depth> mValue;
|
||||
|
||||
LequalDepth()
|
||||
: mValue(new osg::Depth)
|
||||
LequalDepth(bool reverseZ)
|
||||
: mValue(SceneUtil::createDepth(reverseZ))
|
||||
{
|
||||
mValue->setFunction(osg::Depth::LEQUAL);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -170,9 +171,10 @@ namespace
|
|||
|
||||
namespace Terrain
|
||||
{
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, Shader::ShaderManager* shaderManager, const std::vector<TextureLayer> &layers,
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, Resource::SceneManager* sceneManager, const std::vector<TextureLayer> &layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps, int blendmapScale, float layerTileSize)
|
||||
{
|
||||
Shader::ShaderManager* shaderManager = &sceneManager->getShaderManager();
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > passes;
|
||||
|
||||
unsigned int blendmapIndex = 0;
|
||||
|
@ -195,7 +197,7 @@ namespace Terrain
|
|||
else
|
||||
{
|
||||
stateset->setAttributeAndModes(BlendFuncFirst::value(), osg::StateAttribute::ON);
|
||||
stateset->setAttributeAndModes(LequalDepth::value(), osg::StateAttribute::ON);
|
||||
stateset->setAttributeAndModes(LequalDepth::value(sceneManager->getReverseZ()), osg::StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,7 +240,7 @@ namespace Terrain
|
|||
if (!vertexShader || !fragmentShader)
|
||||
{
|
||||
// Try again without shader. Error already logged by above
|
||||
return createPasses(false, shaderManager, layers, blendmaps, blendmapScale, layerTileSize);
|
||||
return createPasses(false, sceneManager, layers, blendmaps, blendmapScale, layerTileSize);
|
||||
}
|
||||
|
||||
stateset->setAttributeAndModes(shaderManager->getProgram(vertexShader, fragmentShader));
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace osg
|
|||
class Texture2D;
|
||||
}
|
||||
|
||||
namespace Shader
|
||||
namespace Resource
|
||||
{
|
||||
class ShaderManager;
|
||||
class SceneManager;
|
||||
}
|
||||
|
||||
namespace Terrain
|
||||
|
@ -26,7 +26,7 @@ namespace Terrain
|
|||
bool mSpecular;
|
||||
};
|
||||
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, Shader::ShaderManager* shaderManager,
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, Resource::SceneManager* sceneManager,
|
||||
const std::vector<TextureLayer>& layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue