mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 01:45:34 +00:00
Code review cleanup, add setting documentation
This commit is contained in:
parent
24454a1698
commit
328ec85757
5 changed files with 117 additions and 53 deletions
|
@ -31,7 +31,6 @@
|
|||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
#include <components/sceneutil/workqueue.hpp>
|
||||
#include <components/sceneutil/lightmanager.hpp>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "apps/openmw/mwrender/vismask.hpp"
|
||||
|
||||
namespace
|
||||
namespace
|
||||
{
|
||||
/* similar to the boost::hash_combine */
|
||||
template <class T>
|
||||
|
@ -136,33 +136,35 @@ namespace SceneUtil
|
|||
switch (method)
|
||||
{
|
||||
case LightingMethod::FFP:
|
||||
break;
|
||||
{
|
||||
break;
|
||||
}
|
||||
case LightingMethod::PerObjectUniform:
|
||||
{
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].diffuse", light->getDiffuse()), mode);
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].ambient", light->getAmbient()), mode);
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].specular", light->getSpecular()), mode);
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].position", light->getPosition()), mode);
|
||||
{
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].diffuse", light->getDiffuse()), mode);
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].ambient", light->getAmbient()), mode);
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].specular", light->getSpecular()), mode);
|
||||
stateset->addUniform(new osg::Uniform("LightBuffer[0].position", light->getPosition()), mode);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LightingMethod::SingleUBO:
|
||||
{
|
||||
osg::ref_ptr<LightBuffer> buffer = new LightBuffer(1);
|
||||
{
|
||||
osg::ref_ptr<LightBuffer> buffer = new LightBuffer(1);
|
||||
|
||||
buffer->setDiffuse(0, light->getDiffuse());
|
||||
buffer->setAmbient(0, light->getAmbient());
|
||||
buffer->setSpecular(0, light->getSpecular());
|
||||
buffer->setPosition(0, light->getPosition());
|
||||
buffer->setDiffuse(0, light->getDiffuse());
|
||||
buffer->setAmbient(0, light->getAmbient());
|
||||
buffer->setSpecular(0, light->getSpecular());
|
||||
buffer->setPosition(0, light->getPosition());
|
||||
|
||||
osg::ref_ptr<osg::UniformBufferObject> ubo = new osg::UniformBufferObject;
|
||||
buffer->mData->setBufferObject(ubo);
|
||||
osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Shader::UBOBinding::LightBuffer), buffer->mData.get(), 0, buffer->mData->getTotalDataSize());
|
||||
osg::ref_ptr<osg::UniformBufferObject> ubo = new osg::UniformBufferObject;
|
||||
buffer->mData->setBufferObject(ubo);
|
||||
osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Shader::UBOBinding::LightBuffer), buffer->mData.get(), 0, buffer->mData->getTotalDataSize());
|
||||
|
||||
stateset->setAttributeAndModes(ubb, mode);
|
||||
stateset->setAttributeAndModes(ubb, mode);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,9 +203,9 @@ namespace SceneUtil
|
|||
void apply(osg::State& state) const override
|
||||
{
|
||||
int lightNum = GL_LIGHT0 + mIndex;
|
||||
glLightfv( lightNum, GL_AMBIENT, mnullptr.ptr() );
|
||||
glLightfv( lightNum, GL_DIFFUSE, mnullptr.ptr() );
|
||||
glLightfv( lightNum, GL_SPECULAR, mnullptr.ptr() );
|
||||
glLightfv(lightNum, GL_AMBIENT, mnullptr.ptr());
|
||||
glLightfv(lightNum, GL_DIFFUSE, mnullptr.ptr());
|
||||
glLightfv(lightNum, GL_SPECULAR, mnullptr.ptr());
|
||||
|
||||
LightStateCache* cache = getLightStateCache(state.getContextID());
|
||||
cache->lastAppliedLight[mIndex] = nullptr;
|
||||
|
@ -334,7 +336,7 @@ namespace SceneUtil
|
|||
cache->lastAppliedLight[i] = mLights[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
state.applyModelViewMatrix(modelViewMatrix);
|
||||
}
|
||||
|
||||
|
@ -344,7 +346,7 @@ namespace SceneUtil
|
|||
};
|
||||
|
||||
struct StateSetGenerator
|
||||
{
|
||||
{
|
||||
LightManager* mLightManager;
|
||||
|
||||
virtual ~StateSetGenerator() {}
|
||||
|
@ -475,9 +477,9 @@ namespace SceneUtil
|
|||
mLightManager = findLightManager(nv->getNodePath());
|
||||
|
||||
if (!mLightManager)
|
||||
throw std::runtime_error("can't find parent LightManager");
|
||||
throw std::runtime_error("can't find parent LightManager");
|
||||
}
|
||||
|
||||
|
||||
mLightManager->addLight(static_cast<LightSource*>(node), osg::computeLocalToWorld(nv->getNodePath()), nv->getTraversalNumber());
|
||||
|
||||
traverse(node, nv);
|
||||
|
@ -523,7 +525,7 @@ namespace SceneUtil
|
|||
mLastFrameNumber = cv->getTraversalNumber();
|
||||
|
||||
if (mLightManager->getLightingMethod() == LightingMethod::SingleUBO)
|
||||
{
|
||||
{
|
||||
auto stateset = mLightManager->getStateSet();
|
||||
auto bo = mLightManager->getLightBuffer(mLastFrameNumber);
|
||||
osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Shader::UBOBinding::LightBuffer), bo->getData().get(), 0, bo->getData()->getTotalDataSize());
|
||||
|
@ -548,7 +550,7 @@ namespace SceneUtil
|
|||
buf->setDiffuse(0, sun->getDiffuse());
|
||||
buf->setAmbient(0, sun->getAmbient());
|
||||
buf->setSpecular(0, sun->getSpecular());
|
||||
buf->setPosition(0, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix()));
|
||||
buf->setPosition(0, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -560,12 +562,12 @@ namespace SceneUtil
|
|||
LightManager* mLightManager;
|
||||
size_t mLastFrameNumber;
|
||||
};
|
||||
|
||||
|
||||
class LightManagerStateAttribute : public osg::StateAttribute
|
||||
{
|
||||
public:
|
||||
LightManagerStateAttribute() : mLightManager(nullptr) {}
|
||||
LightManagerStateAttribute(LightManager* lightManager) : mLightManager(lightManager) {}
|
||||
LightManagerStateAttribute(LightManager* lightManager) : mLightManager(lightManager) {}
|
||||
|
||||
LightManagerStateAttribute(const LightManagerStateAttribute& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
|
||||
: osg::StateAttribute(copy,copyop),mLightManager(copy.mLightManager) {}
|
||||
|
@ -595,7 +597,7 @@ namespace SceneUtil
|
|||
: mStartLight(0)
|
||||
, mLightingMask(~0u)
|
||||
, mSun(nullptr)
|
||||
, mPointLightRadiusMultiplier(std::max(0.f, Settings::Manager::getFloat("light bounds multiplier", "Shaders")))
|
||||
, mPointLightRadiusMultiplier(std::clamp(Settings::Manager::getFloat("light bounds multiplier", "Shaders"), 0.f, 10.f))
|
||||
, mPointLightFadeStart(0.f)
|
||||
{
|
||||
mPointLightFadeEnd = std::max(0.f, Settings::Manager::getFloat("maximum light distance", "Shaders"));
|
||||
|
@ -608,7 +610,7 @@ namespace SceneUtil
|
|||
auto lightingModelString = Settings::Manager::getString("lighting method", "Shaders");
|
||||
bool validLightingModel = isValidLightingModelString(lightingModelString);
|
||||
if (!validLightingModel)
|
||||
Log(Debug::Error) << "Invalid option for 'lighting model': got '" << lightingModelString
|
||||
Log(Debug::Error) << "Invalid option for 'lighting model': got '" << lightingModelString
|
||||
<< "', expected legacy, default, or experimental.";
|
||||
|
||||
if (ffp || !validLightingModel)
|
||||
|
@ -625,10 +627,10 @@ namespace SceneUtil
|
|||
|
||||
osg::GLExtensions* exts = osg::GLExtensions::Get(0, false);
|
||||
bool supportsUBO = exts && exts->isUniformBufferObjectSupported;
|
||||
bool supportsGPU4 = exts && exts->isGpuShader4Supported;
|
||||
bool supportsGPU4 = exts && exts->isGpuShader4Supported;
|
||||
|
||||
if (!supportsUBO)
|
||||
Log(Debug::Info) << "GL_ARB_uniform_buffer_object not supported: using fallback uniforms";
|
||||
Log(Debug::Info) << "GL_ARB_uniform_buffer_object not supported: using fallback uniforms";
|
||||
else if (!supportsGPU4)
|
||||
Log(Debug::Info) << "GL_EXT_gpu_shader4 not supported: using fallback uniforms";
|
||||
|
||||
|
@ -648,7 +650,7 @@ namespace SceneUtil
|
|||
osg::ref_ptr<osg::Uniform> uambient = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].ambient").c_str());
|
||||
osg::ref_ptr<osg::Uniform> uposition = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].position").c_str());
|
||||
osg::ref_ptr<osg::Uniform> uattenuation = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].attenuation").c_str());
|
||||
|
||||
|
||||
mLightUniforms[i].emplace(UniformKey::Diffuse, udiffuse);
|
||||
mLightUniforms[i].emplace(UniformKey::Ambient, uambient);
|
||||
mLightUniforms[i].emplace(UniformKey::Specular, uspecular);
|
||||
|
@ -681,7 +683,7 @@ namespace SceneUtil
|
|||
|
||||
stateset->setAttribute(new LightManagerStateAttribute(this), osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
|
||||
stateset->addUniform(new osg::Uniform("PointLightCount", 0));
|
||||
|
||||
setUpdateCallback(new LightManagerUpdateCallback);
|
||||
|
@ -720,10 +722,10 @@ namespace SceneUtil
|
|||
{
|
||||
mMaxLights = value;
|
||||
}
|
||||
|
||||
|
||||
int LightManager::getMaxLightsInScene() const
|
||||
{
|
||||
static constexpr int max = 16384 / LightBuffer::queryBlockSize(1);
|
||||
static constexpr int max = 16384 / LightBuffer::queryBlockSize(1);
|
||||
return max;
|
||||
}
|
||||
|
||||
|
@ -732,7 +734,7 @@ namespace SceneUtil
|
|||
Shader::ShaderManager::DefineMap defines;
|
||||
|
||||
bool ffp = usingFFP();
|
||||
|
||||
|
||||
defines["ffpLighting"] = ffp ? "1" : "0";
|
||||
defines["maxLights"] = std::to_string(getMaxLights());
|
||||
defines["maxLightsInScene"] = std::to_string(getMaxLightsInScene());
|
||||
|
@ -794,7 +796,7 @@ namespace SceneUtil
|
|||
}
|
||||
|
||||
void LightManager::update(size_t frameNum)
|
||||
{
|
||||
{
|
||||
getLightIndexMap(frameNum).clear();
|
||||
mLights.clear();
|
||||
mLightsInViewSpace.clear();
|
||||
|
@ -802,7 +804,7 @@ namespace SceneUtil
|
|||
// Do an occasional cleanup for orphaned lights.
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
if (mStateSetCache[i].size() > 5000)
|
||||
if (mStateSetCache[i].size() > 5000)
|
||||
mStateSetCache[i].clear();
|
||||
}
|
||||
}
|
||||
|
@ -839,9 +841,9 @@ namespace SceneUtil
|
|||
auto id = lightList[i]->mLightSource->getId();
|
||||
hash_combine(hash, id);
|
||||
|
||||
if (getLightingMethod() != LightingMethod::SingleUBO)
|
||||
if (getLightingMethod() != LightingMethod::SingleUBO)
|
||||
continue;
|
||||
|
||||
|
||||
if (getLightIndexMap(frameNum).find(id) != getLightIndexMap(frameNum).end())
|
||||
continue;
|
||||
|
||||
|
@ -875,11 +877,11 @@ namespace SceneUtil
|
|||
if (it == mLightsInViewSpace.end())
|
||||
{
|
||||
it = mLightsInViewSpace.insert(std::make_pair(camPtr, LightSourceViewBoundCollection())).first;
|
||||
|
||||
|
||||
for (const auto& transform : mLights)
|
||||
{
|
||||
osg::Matrixf worldViewMat = transform.mWorldMatrix * (*viewMatrix);
|
||||
|
||||
|
||||
float radius = transform.mLightSource->getRadius();
|
||||
|
||||
osg::BoundingSphere viewBound = osg::BoundingSphere(osg::Vec3f(0,0,0), radius * mPointLightRadiusMultiplier);
|
||||
|
@ -901,7 +903,7 @@ namespace SceneUtil
|
|||
LightSourceViewBound l;
|
||||
l.mLightSource = transform.mLightSource;
|
||||
l.mViewBound = viewBound;
|
||||
it->second.push_back(l);
|
||||
it->second.push_back(l);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,7 +987,7 @@ namespace SceneUtil
|
|||
// Don't use Camera::getViewMatrix, that one might be relative to another camera!
|
||||
const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix();
|
||||
const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv->getCurrentCamera(), viewMatrix, mLastFrameNumber);
|
||||
|
||||
|
||||
// get the node bounds in view space
|
||||
// NB do not node->getBound() * modelView, that would apply the node's transformation twice
|
||||
osg::BoundingSphere nodeBound;
|
||||
|
@ -1026,7 +1028,7 @@ namespace SceneUtil
|
|||
for (auto it = lightList.begin(); it != lightList.end() && lightList.size() > maxLights; )
|
||||
{
|
||||
osg::CullStack::CullingStack& stack = cv->getModelViewCullingStack();
|
||||
|
||||
|
||||
osg::BoundingSphere bs = (*it)->mViewBound;
|
||||
bs._radius = bs._radius * 2.0;
|
||||
osg::CullingSet& cullingSet = stack.front();
|
||||
|
|
|
@ -148,6 +148,69 @@ By default, the fog becomes thicker proportionally to your distance from the cli
|
|||
This setting makes the fog use the actual eye point distance (or so called Euclidean distance) to calculate the fog, which makes the fog look less artificial, especially if you have a wide FOV.
|
||||
Note that the rendering will act as if you have 'force shaders' option enabled with this on, which means that shaders will be used to render all objects and the terrain.
|
||||
|
||||
lighting method
|
||||
---------------
|
||||
|
||||
:Type: string
|
||||
:Range: legacy|default|experimental
|
||||
:Default: default
|
||||
|
||||
Sets the internal handling of light sources.
|
||||
|
||||
'legacy' is restricted to a maximum of 8 lights per object and guarantees fixed function pipeline compatible lighting.
|
||||
|
||||
'default' removes the light limit via :ref:`max lights` and follows a new attenuation formula which can drastically reduce light popping and seams.
|
||||
It is recommended to use this mode with older hardware, as the technique ensures a range of compatibility equal to that of 'legacy'.
|
||||
|
||||
'experimental' carries all of the benefits that 'legacy' has, but uses a modern approach that allows for a higher 'max lights' count with little to no performance penalties on modern hardware.
|
||||
|
||||
light bounds multiplier
|
||||
-----------------------
|
||||
|
||||
:Type: float
|
||||
:Range: 0.0-10.0
|
||||
:Default: 2.0
|
||||
|
||||
Controls the bounding sphere radius of point lights, which is used to determine if an object should receive lighting from a particular light source.
|
||||
Note, this has no direct effect on the overall illumination of lights.
|
||||
Larger multipliers will allow for smoother transitions of light sources, but may require an increase in :ref:`max lights` and thus carries a performance penalty.
|
||||
This especially helps with abrupt light popping with handheld light sources such as torches and lanterns.
|
||||
|
||||
It is recommended to keep this at 1.0 if :ref:`lighting method` is set to 'legacy', as the number of lights is fixed in that mode.
|
||||
|
||||
maximum light distance
|
||||
----------------------
|
||||
|
||||
:Type: float
|
||||
:Range: The whole range of 32-bit floating point
|
||||
:Default: 8192
|
||||
|
||||
The maximum distance from the camera that lights will be illuminated, applies to both interiors and exteriors.
|
||||
A lower distance will improve performance.
|
||||
Set this to a non-positive value to disable fading.
|
||||
|
||||
light fade start
|
||||
----------------
|
||||
|
||||
:Type: float
|
||||
:Range: 0.0-1.0
|
||||
:Default: 0.85
|
||||
|
||||
The fraction of the maximum distance at which lights will begin to fade away.
|
||||
Tweaking it will make the transition proportionally more or less smooth.
|
||||
This setting has no effect if the maximum light distance is non-positive.
|
||||
|
||||
max lights
|
||||
----------
|
||||
|
||||
:Type: integer
|
||||
:Range: >=2
|
||||
:Default: 16
|
||||
|
||||
Sets the maximum number of lights that each object can receive lighting from.
|
||||
Has no effect if :ref:`force shaders` option is off or :ref:`lighting method` is 'legacy'. In this case the maximum number of lights is fixed at 8.
|
||||
Increasing this too much can cause significant performance loss, especially if :ref:`lighting method` is not set to 'experimental' or :ref:`force per pixel lighting` is on.
|
||||
|
||||
antialias alpha test
|
||||
---------------------------------------
|
||||
|
||||
|
|
|
@ -76,8 +76,8 @@ varying vec3 passNormal;
|
|||
|
||||
#include "vertexcolors.glsl"
|
||||
#include "shadows_fragment.glsl"
|
||||
#include "parallax.glsl"
|
||||
#include "lighting.glsl"
|
||||
#include "parallax.glsl"
|
||||
#include "alpha.glsl"
|
||||
|
||||
void main()
|
||||
|
|
|
@ -34,8 +34,8 @@ varying vec3 passNormal;
|
|||
|
||||
#include "vertexcolors.glsl"
|
||||
#include "shadows_fragment.glsl"
|
||||
#include "parallax.glsl"
|
||||
#include "lighting.glsl"
|
||||
#include "parallax.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue