Better fog

just_say_no_to_geode
Petr Mikheev 2 years ago
parent 11bced737f
commit 3bf18c601c

@ -117,7 +117,7 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(autoUseTerrainNormalMapsCheckBox, "auto use terrain normal maps", "Shaders");
loadSettingBool(autoUseTerrainSpecularMapsCheckBox, "auto use terrain specular maps", "Shaders");
loadSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders");
loadSettingBool(radialFogCheckBox, "radial fog", "Shaders");
loadSettingBool(radialFogCheckBox, "radial fog", "Fog");
loadSettingBool(softParticlesCheckBox, "soft particles", "Shaders");
loadSettingBool(antialiasAlphaTestCheckBox, "antialias alpha test", "Shaders");
if (Settings::Manager::getInt("antialiasing", "Video") == 0) {
@ -265,7 +265,7 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(autoUseTerrainNormalMapsCheckBox, "auto use terrain normal maps", "Shaders");
saveSettingBool(autoUseTerrainSpecularMapsCheckBox, "auto use terrain specular maps", "Shaders");
saveSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders");
saveSettingBool(radialFogCheckBox, "radial fog", "Shaders");
saveSettingBool(radialFogCheckBox, "radial fog", "Fog");
saveSettingBool(softParticlesCheckBox, "soft particles", "Shaders");
saveSettingBool(antialiasAlphaTestCheckBox, "antialias alpha test", "Shaders");
saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game");

@ -256,7 +256,18 @@ namespace
Log(Debug::Info) << "OpenGL Vendor: " << glGetString(GL_VENDOR);
Log(Debug::Info) << "OpenGL Renderer: " << glGetString(GL_RENDERER);
Log(Debug::Info) << "OpenGL Version: " << glGetString(GL_VERSION);
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxTextureImageUnits);
}
int getMaxTextureImageUnits() const
{
if (mMaxTextureImageUnits == 0)
throw std::logic_error("mMaxTextureImageUnits is not initialized");
return mMaxTextureImageUnits;
}
private:
int mMaxTextureImageUnits = 0;
};
class InitializeStereoOperation final : public osg::GraphicsOperation
@ -664,7 +675,8 @@ void OMW::Engine::createWindow()
osg::ref_ptr<SceneUtil::OperationSequence> realizeOperations = new SceneUtil::OperationSequence(false);
mViewer->setRealizeOperation(realizeOperations);
realizeOperations->add(new IdentifyOpenGLOperation());
osg::ref_ptr<IdentifyOpenGLOperation> identifyOp = new IdentifyOpenGLOperation();
realizeOperations->add(identifyOp);
if (Debug::shouldDebugOpenGL())
realizeOperations->add(new Debug::EnableGLDebugOperation());
@ -679,6 +691,7 @@ void OMW::Engine::createWindow()
}
mViewer->realize();
mGlMaxTextureImageUnits = identifyOp->getMaxTextureImageUnits();
mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height);
}
@ -724,6 +737,7 @@ void OMW::Engine::prepareEngine()
VFS::registerArchives(mVFS.get(), mFileCollections, mArchives, true);
mResourceSystem = std::make_unique<Resource::ResourceSystem>(mVFS.get());
mResourceSystem->getSceneManager()->getShaderManager().setMaxTextureUnits(mGlMaxTextureImageUnits);
mResourceSystem->getSceneManager()->setUnRefImageDataAfterApply(false); // keep to Off for now to allow better state sharing
mResourceSystem->getSceneManager()->setFilterSettings(
Settings::Manager::getString("texture mag filter", "General"),

@ -264,6 +264,7 @@ namespace OMW
private:
Files::ConfigurationManager& mCfgMgr;
class LuaWorker;
int mGlMaxTextureImageUnits;
};
}

@ -268,6 +268,12 @@ namespace MWRender
fog->setEnd(10000000);
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
// turn of sky blending
stateset->addUniform(new osg::Uniform("far", 10000000.0f));
stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f));
stateset->addUniform(new osg::Uniform("sky", 0));
stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{1, 1}));
// Opaque stuff must have 1 as its fragment alpha as the FBO is translucent, so having blending off isn't enough
osg::ref_ptr<osg::TexEnvCombine> noBlendAlphaEnv = new osg::TexEnvCombine();
noBlendAlphaEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);

@ -720,6 +720,12 @@ void LocalMapRenderToTexture::setDefaults(osg::Camera* camera)
fog->setEnd(10000000);
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
// turn of sky blending
stateset->addUniform(new osg::Uniform("far", 10000000.0f));
stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f));
stateset->addUniform(new osg::Uniform("sky", 0));
stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{1, 1}));
osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
lightmodel->setAmbientIntensity(osg::Vec4(0.3f, 0.3f, 0.3f, 1.f));
stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

@ -41,6 +41,7 @@
#include <components/sceneutil/workqueue.hpp>
#include <components/sceneutil/writescene.hpp>
#include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/rtt.hpp>
#include <components/misc/constants.hpp>
@ -81,7 +82,6 @@ namespace MWRender
{
class PerViewUniformStateUpdater final : public SceneUtil::StateSetUpdater
{
public:
public:
PerViewUniformStateUpdater()
{
@ -90,6 +90,8 @@ namespace MWRender
void setDefaults(osg::StateSet* stateset) override
{
stateset->addUniform(new osg::Uniform("projectionMatrix", osg::Matrixf{}));
if (mSkyRTT)
stateset->addUniform(new osg::Uniform("sky", mSkyTextureUnit));
}
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override
@ -97,6 +99,11 @@ namespace MWRender
auto* uProjectionMatrix = stateset->getUniform("projectionMatrix");
if (uProjectionMatrix)
uProjectionMatrix->set(mProjectionMatrix);
if (mSkyRTT && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
{
osg::Texture* skyTexture = mSkyRTT->getColorTexture(static_cast<osgUtil::CullVisitor*>(nv));
stateset->setTextureAttribute(mSkyTextureUnit, skyTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
}
}
void applyLeft(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override
@ -123,8 +130,16 @@ namespace MWRender
return mProjectionMatrix;
}
void enableSkyRTT(int skyTextureUnit, SceneUtil::RTTNode* skyRTT)
{
mSkyTextureUnit = skyTextureUnit;
mSkyRTT = skyRTT;
}
private:
osg::Matrixf mProjectionMatrix;
int mSkyTextureUnit = -1;
SceneUtil::RTTNode* mSkyRTT = nullptr;
};
class SharedUniformStateUpdater : public SceneUtil::StateSetUpdater
@ -144,6 +159,7 @@ namespace MWRender
stateset->addUniform(new osg::Uniform("linearFac", 0.f));
stateset->addUniform(new osg::Uniform("near", 0.f));
stateset->addUniform(new osg::Uniform("far", 0.f));
stateset->addUniform(new osg::Uniform("skyBlendingStart", 0.f));
stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{}));
if (mUsePlayerUniforms)
{
@ -166,6 +182,11 @@ namespace MWRender
if (uFar)
uFar->set(mFar);
static const float mSkyBlendingStartCoef = Settings::Manager::getFloat("sky blending start", "Fog");
auto* uSkyBlendingStart = stateset->getUniform("skyBlendingStart");
if (uSkyBlendingStart)
uSkyBlendingStart->set(mFar * mSkyBlendingStartCoef);
auto* uScreenRes = stateset->getUniform("screenRes");
if (uScreenRes)
uScreenRes->set(mScreenRes);
@ -337,7 +358,8 @@ namespace MWRender
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const std::string& resourcePath, DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore)
: mViewer(viewer)
: mSkyBlending(Settings::Manager::getBool("sky blending", "Fog"))
, mViewer(viewer)
, mRootNode(rootNode)
, mResourceSystem(resourceSystem)
, mWorkQueue(workQueue)
@ -358,12 +380,14 @@ namespace MWRender
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
// Shadows and radial fog have problems with fixed-function mode.
bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders")
bool forceShaders = Settings::Manager::getBool("radial fog", "Fog")
|| Settings::Manager::getBool("exponential fog", "Fog")
|| Settings::Manager::getBool("soft particles", "Shaders")
|| Settings::Manager::getBool("force shaders", "Shaders")
|| Settings::Manager::getBool("enable shadows", "Shadows")
|| lightingMethod != SceneUtil::LightingMethod::FFP
|| reverseZ
|| mSkyBlending
|| Stereo::getMultiview();
resourceSystem->getSceneManager()->setForceShaders(forceShaders);
@ -413,7 +437,10 @@ namespace MWRender
globalDefines["forcePPL"] = Settings::Manager::getBool("force per pixel lighting", "Shaders") ? "1" : "0";
globalDefines["clamp"] = Settings::Manager::getBool("clamp lighting", "Shaders") ? "1" : "0";
globalDefines["preLightEnv"] = Settings::Manager::getBool("apply lighting to environment maps", "Shaders") ? "1" : "0";
globalDefines["radialFog"] = Settings::Manager::getBool("radial fog", "Shaders") ? "1" : "0";
bool exponentialFog = Settings::Manager::getBool("exponential fog", "Fog");
globalDefines["radialFog"] = (exponentialFog || Settings::Manager::getBool("radial fog", "Fog")) ? "1" : "0";
globalDefines["exponentialFog"] = exponentialFog ? "1" : "0";
globalDefines["skyBlending"] = mSkyBlending ? "1" : "0";
globalDefines["refraction_enabled"] = "0";
globalDefines["useGPUShader4"] = "0";
globalDefines["useOVR_multiview"] = "0";
@ -546,8 +573,14 @@ namespace MWRender
mFog = std::make_unique<FogManager>();
mSky = std::make_unique<SkyManager>(sceneRoot, resourceSystem->getSceneManager());
mSky = std::make_unique<SkyManager>(sceneRoot, resourceSystem->getSceneManager(), mSkyBlending);
mSky->setCamera(mViewer->getCamera());
if (mSkyBlending)
{
int skyTextureUnit = mResourceSystem->getSceneManager()->getShaderManager().reserveGlobalTextureUnits(1);
Log(Debug::Info) << "Reserving texture unit for sky RTT: " << skyTextureUnit;
mPerViewUniformStateUpdater->enableSkyRTT(skyTextureUnit, mSky->getSkyRTT());
}
source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON);
@ -573,8 +606,6 @@ namespace MWRender
mStateUpdater->setFogEnd(mViewDistance);
mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("simpleWater", false));
// Hopefully, anything genuinely requiring the default alpha func of GL_ALWAYS explicitly sets it
mRootNode->getOrCreateStateSet()->setAttribute(Shader::RemovedAlphaFunc::getInstance(GL_ALWAYS));
// The transparent renderbin sets alpha testing on because that was faster on old GPUs. It's now slower and breaks things.

@ -267,6 +267,7 @@ namespace MWRender
void updateRecastMesh();
const bool mSkyBlending;
osg::ref_ptr<osgUtil::IntersectionVisitor> getIntersectionVisitor(osgUtil::Intersector* intersector, bool ignorePlayer, bool ignoreActors);

@ -15,6 +15,7 @@
#include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/depth.hpp>
#include <components/sceneutil/rtt.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/resource/imagemanager.hpp>
@ -215,11 +216,35 @@ namespace
private:
const float &mAlpha;
};
class SkyRTT : public SceneUtil::RTTNode
{
public:
SkyRTT(osg::Vec2f size, osg::Group* earlyRenderBinRoot) :
RTTNode(static_cast<int>(size.x()), static_cast<int>(size.y()), 0, false, 1, StereoAwareness::Aware),
mEarlyRenderBinRoot(earlyRenderBinRoot)
{
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
}
void setDefaults(osg::Camera* camera) override
{
camera->setReferenceFrame(osg::Camera::RELATIVE_RF);
camera->setName("SkyCamera");
camera->setNodeMask(MWRender::Mask_RenderToTexture);
camera->addChild(mEarlyRenderBinRoot);
SceneUtil::ShadowManager::disableShadowsForStateSet(camera->getOrCreateStateSet());
}
private:
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;
};
}
namespace MWRender
{
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager)
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager, bool enableSkyRTT)
: mSceneManager(sceneManager)
, mCamera(nullptr)
, mAtmosphereNightRoll(0.f)
@ -271,6 +296,12 @@ namespace MWRender
mEarlyRenderBinRoot->getOrCreateStateSet()->setMode(GL_CLIP_PLANE0, osg::StateAttribute::OFF);
mRootNode->addChild(mEarlyRenderBinRoot);
if (enableSkyRTT)
{
mSkyRTT = new SkyRTT(Settings::Manager::getVector2("sky rtt resolution", "Fog"), mEarlyRenderBinRoot);
mRootNode->addChild(mSkyRTT);
}
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
}

@ -30,6 +30,11 @@ namespace Resource
class SceneManager;
}
namespace SceneUtil
{
class RTTNode;
}
namespace MWRender
{
///@brief The SkyManager handles rendering of the sky domes, celestial bodies as well as other objects that need to be rendered
@ -37,7 +42,7 @@ namespace MWRender
class SkyManager
{
public:
SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager);
SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager, bool enableSkyRTT);
~SkyManager();
void update(float duration);
@ -98,6 +103,8 @@ namespace MWRender
void setSunglare(bool enabled);
SceneUtil::RTTNode* getSkyRTT() { return mSkyRTT.get(); }
private:
void create();
///< no need to call this, automatically done on first enable()
@ -192,6 +199,8 @@ namespace MWRender
bool mDirtyParticlesEffect;
osg::Vec4f mMoonScriptColor;
osg::ref_ptr<SceneUtil::RTTNode> mSkyRTT;
};
}

@ -104,7 +104,7 @@ TestingOpenMW::VFSTestFile repeated_shared_block{R"(
}))
, mImageManager(mVFS.get())
{
Settings::Manager::setBool("radial fog", "Shaders", true);
Settings::Manager::setBool("radial fog", "Fog", true);
Settings::Manager::setBool("stereo enabled", "Stereo", false);
}

@ -182,7 +182,7 @@ float omw_GetPointLightRadius(int index)
{"@ubo", mUBO ? "1" : "0"},
{"@normals", technique.getNormals() ? "1" : "0"},
{"@reverseZ", SceneUtil::AutoDepth::isReversed() ? "1" : "0"},
{"@radialFog", Settings::Manager::getBool("radial fog", "Shaders") ? "1" : "0"},
{"@radialFog", Settings::Manager::getBool("radial fog", "Fog") ? "1" : "0"},
{"@hdr", technique.getHDR() ? "1" : "0"},
{"@in", mLegacyGLSL ? "varying" : "in"},
{"@out", mLegacyGLSL ? "varying" : "out"},

@ -84,9 +84,6 @@ namespace SceneUtil
stateset->setRenderBinDetails(renderBin, "RenderBin");
// Let the shader know we're dealing with simple water here.
stateset->addUniform(new osg::Uniform("simpleWater", true));
return stateset;
}
}

@ -12,6 +12,7 @@
#include <components/debug/debuglog.hpp>
#include <components/misc/stringops.hpp>
#include <components/settings/settings.hpp>
namespace Shader
{
@ -509,4 +510,22 @@ namespace Shader
program->addShader(linkedShader);
}
int ShaderManager::reserveGlobalTextureUnits(int count)
{
{
// Texture units from `8 - numberOfShadowMaps` to `8` are used for shadows, so we skip them here.
// TODO: Maybe instead of fixed texture units use `reserveGlobalTextureUnits` for shadows as well.
static const int numberOfShadowMaps = Settings::Manager::getBool("enable shadows", "Shadows") ?
std::clamp(Settings::Manager::getInt("number of shadow maps", "Shadows"), 1, 8) :
0;
if (getAvailableTextureUnits() >= 8 && getAvailableTextureUnits() - count < 8)
mReservedTextureUnits = mMaxTextureUnits - (8 - numberOfShadowMaps);
}
if (getAvailableTextureUnits() < count + 1)
throw std::runtime_error("Can't reserve texture unit; no available units");
mReservedTextureUnits += count;
return mMaxTextureUnits - mReservedTextureUnits;
}
}

@ -54,6 +54,12 @@ namespace Shader
bool createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const std::string& templateName, const ShaderManager::DefineMap& defines);
void setMaxTextureUnits(int maxTextureUnits) { mMaxTextureUnits = maxTextureUnits; }
int getMaxTextureUnits() const { return mMaxTextureUnits; }
int getAvailableTextureUnits() const { return mMaxTextureUnits - mReservedTextureUnits; }
int reserveGlobalTextureUnits(int count);
private:
void getLinkedShaders(osg::ref_ptr<osg::Shader> shader, const std::vector<std::string>& linkedShaderNames, const DefineMap& defines);
void addLinkedShaders(osg::ref_ptr<osg::Shader> shader, osg::ref_ptr<osg::Program> program);
@ -80,6 +86,9 @@ namespace Shader
std::mutex mMutex;
osg::ref_ptr<const osg::Program> mProgramTemplate;
int mMaxTextureUnits = 0;
int mReservedTextureUnits = 0;
};
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos);

@ -113,3 +113,53 @@ distant interior fog end
:Default: 16384 (2 cells)
This is the base fog end distance used for distant fog calculations in interior locations.
radial fog
----------
:Type: boolean
:Range: True/False
:Default: False
By default, the fog becomes thicker proportionally to your distance from the clipping plane set at the clipping distance, which causes distortion at the edges of the screen.
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.
exponential fog
---------------
:Type: boolean
:Range: True/False
:Default: False
Similar to "radial fog" but uses an exponential formula for the fog.
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.
sky blending
------------
:Type: boolean
:Range: True/False
:Default: False
Whether to use blending with the sky for everything that is close to the clipping plane.
If enabled the clipping plane becomes invisible.
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.
sky blending start
------------------
:Type: floating point
:Range: from 0.0 (including) to 1.0 (excluding)
:Default: 0.8
The fraction of the maximum distance at which blending with the sky starts.
sky rtt resolution
------------------
:Type: two positive integers
:Default: 512 256
The sky RTT texture size, used only for sky blending. Smaller values
reduce quality of the sky blending, but can have slightly better performance.

@ -137,17 +137,6 @@ Normally environment map reflections aren't affected by lighting, which makes en
Morrowind Code Patch includes an option to remedy that by doing environment-mapping before applying lighting, this is the equivalent of that option.
Affected objects will use shaders.
radial fog
----------
:Type: boolean
:Range: True/False
:Default: False
By default, the fog becomes thicker proportionally to your distance from the clipping plane set at the clipping distance, which causes distortion at the edges of the screen.
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
---------------
@ -284,4 +273,4 @@ systems that potentially differ from the source content, this setting may change
the look of some particle systems.
Note that the rendering will act as if you have 'force shaders' option enabled.
This means that shaders will be used to render all objects and the terrain.
This means that shaders will be used to render all objects and the terrain.

@ -137,6 +137,23 @@ distant interior fog start = 0
distant interior fog end = 16384
# Determine fog intensity based on the distance from the eye point.
# This makes fogging independent from the viewing angle. Shaders will be used to render all objects.
radial fog = false
# Whether to use exponential formula for fog.
exponential fog = false
# Whether to hide the clipping plane by blending with sky.
sky blending = false
# Fraction of the maximum distance at which blending with the sky starts.
sky blending start = 0.8
# The sky RTT texture size, used only for sky blending. Smaller values
# reduce quality of the sky blending, but can have slightly better performance.
sky rtt resolution = 512 256
[Map]
# Size of each exterior cell in pixels in the world map. (e.g. 12 to 24).
@ -427,10 +444,6 @@ terrain specular map pattern = _diffusespec
# Affected objects use shaders.
apply lighting to environment maps = false
# Determine fog intensity based on the distance from the eye point.
# This makes fogging independent from the viewing angle. Shaders will be used to render all objects.
radial fog = false
# Internal handling of lights, ignored if 'force shaders' is off. "legacy"
# provides fixed function pipeline emulation."shaders compatibility" (default)
# uncaps the light limit, enables groundcover lighting, and uses a modified

@ -52,6 +52,7 @@ set(SHADER_FILES
hdr_luminance_fragment.glsl
fullscreen_tri_vertex.glsl
fullscreen_tri_fragment.glsl
fog.glsl
)
copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_RESOURCES_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}")

@ -0,0 +1,34 @@
uniform float far;
#if @skyBlending
uniform sampler2D sky;
uniform float skyBlendingStart;
#endif
vec4 applyFogAtDist(vec4 color, float euclideanDist, float linearDist)
{
#if @radialFog
float dist = euclideanDist;
#else
float dist = abs(linearDist);
#endif
#if @exponentialFog
float fogValue = 1.0 - exp(-2.0 * max(0.0, dist - gl_Fog.start/2.0) / (gl_Fog.end - gl_Fog.start/2.0));
#else
float fogValue = clamp((dist - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
color.xyz = mix(color.xyz, gl_Fog.color.xyz, fogValue);
#if @skyBlending && !@useOVR_multiview
float fadeValue = clamp((far - dist) / (far - skyBlendingStart), 0.0, 1.0);
vec3 skyColor = texture2D(sky, gl_FragCoord.xy / screenRes).xyz;
color.xyz = mix(skyColor, color.xyz, fadeValue * fadeValue);
#endif
return color;
}
vec4 applyFogAtPos(vec4 color, vec3 pos)
{
return applyFogAtDist(color, length(pos), pos.z);
}

@ -27,6 +27,7 @@ varying vec4 passTangent;
varying float euclideanDepth;
varying float linearDepth;
uniform vec2 screenRes;
#if PER_PIXEL_LIGHTING
varying vec3 passViewPos;
@ -40,6 +41,7 @@ varying vec3 passNormal;
#include "shadows_fragment.glsl"
#include "lighting.glsl"
#include "alpha.glsl"
#include "fog.glsl"
void main()
{
@ -82,13 +84,7 @@ void main()
clampLightingResult(lighting);
gl_FragData[0].xyz *= lighting;
#if @radialFog
float fogValue = clamp((euclideanDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#else
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth);
#if !@disableNormals
gl_FragData[1].xyz = worldNormal * 0.5 + 0.5;

@ -33,10 +33,13 @@ varying float linearDepth;
varying vec3 passViewPos;
varying vec3 passNormal;
uniform vec2 screenRes;
#include "vertexcolors.glsl"
#include "shadows_fragment.glsl"
#include "lighting.glsl"
#include "alpha.glsl"
#include "fog.glsl"
uniform float emissiveMult;
uniform float specStrength;
@ -91,12 +94,8 @@ void main()
if (matSpec != vec3(0.0))
gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos.xyz), shininess, matSpec) * shadowing;
#if @radialFog
float fogValue = clamp((euclideanDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#else
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth);
#if defined(FORCE_OPAQUE) && FORCE_OPAQUE
// having testing & blending isn't enough - we need to write an opaque pixel to be opaque

@ -10,18 +10,17 @@ uniform sampler2D diffuseMap;
varying vec2 diffuseMapUV;
#endif
#if @radialFog
varying float euclideanDepth;
#else
varying float linearDepth;
#endif
uniform bool useFalloff;
uniform vec2 screenRes;
varying float passFalloff;
#include "vertexcolors.glsl"
#include "alpha.glsl"
#include "fog.glsl"
void main()
{
@ -39,15 +38,9 @@ void main()
alphaTest();
#if @radialFog
float fogValue = clamp((euclideanDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#else
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
#if defined(FORCE_OPAQUE) && FORCE_OPAQUE
gl_FragData[0].a = 1.0;
#endif
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth);
}

@ -63,10 +63,7 @@ uniform sampler2D glossMap;
varying vec2 glossMapUV;
#endif
uniform bool simpleWater;
varying float euclideanDepth;
varying float linearDepth;
uniform vec2 screenRes;
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
@ -85,6 +82,7 @@ varying vec3 passNormal;
#include "lighting.glsl"
#include "parallax.glsl"
#include "alpha.glsl"
#include "fog.glsl"
#if @softParticles
#include "softparticles.glsl"
@ -190,7 +188,7 @@ void main()
#endif
float shadowing = unshadowedLightRatio(linearDepth);
float shadowing = unshadowedLightRatio(passViewPos.z);
vec3 lighting;
#if !PER_PIXEL_LIGHTING
lighting = passLighting + shadowDiffuseLighting * shadowing;
@ -230,18 +228,8 @@ void main()
#endif
gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos.xyz), shininess, matSpec) * shadowing;
}
#if @radialFog
float depth;
// For the less detailed mesh of simple water we need to recalculate depth on per-pixel basis
if (simpleWater)
depth = length(passViewPos);
else
depth = euclideanDepth;
float fogValue = clamp((depth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#else
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
gl_FragData[0] = applyFogAtPos(gl_FragData[0], passViewPos);
#if !defined(FORCE_OPAQUE) && @softParticles
gl_FragData[0].a *= calcSoftParticleFade();

@ -50,9 +50,6 @@ varying vec2 specularMapUV;
varying vec2 glossMapUV;
#endif
varying float euclideanDepth;
varying float linearDepth;
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
#if !PER_PIXEL_LIGHTING
@ -74,10 +71,7 @@ void main(void)
gl_Position = mw_modelToClip(gl_Vertex);
vec4 viewPos = mw_modelToView(gl_Vertex);
gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz);
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
#if (@envMap || !PER_PIXEL_LIGHTING || @shadows_enabled)
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);

@ -1,7 +1,5 @@
uniform float near;
uniform float far;
uniform sampler2D opaqueDepthTex;
uniform vec2 screenRes;
uniform float particleSize;
float viewDepth(float depth)

@ -32,10 +32,13 @@ centroid varying vec3 shadowDiffuseLighting;
varying vec3 passViewPos;
varying vec3 passNormal;
uniform vec2 screenRes;
#include "vertexcolors.glsl"
#include "shadows_fragment.glsl"
#include "lighting.glsl"
#include "parallax.glsl"
#include "fog.glsl"
void main()
{
@ -116,12 +119,7 @@ void main()
gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos), shininess, matSpec) * shadowing;
}
#if @radialFog
float fogValue = clamp((euclideanDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#else
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth);
#if !@disableNormals && @writeNormals
gl_FragData[1].xyz = worldNormal.xyz * 0.5 + 0.5;

@ -212,7 +212,6 @@ uniform sampler2D normalMap;
uniform float osg_SimulationTime;
uniform float near;
uniform float far;
uniform vec3 nodePosition;
uniform float rainIntensity;
@ -223,6 +222,7 @@ uniform vec2 screenRes;
#include "shadows_fragment.glsl"
#include "lighting.glsl"
#include "fog.glsl"
float frustumDepth;
@ -291,6 +291,8 @@ void main(void)
// TODO: Figure out how to properly radialise refraction depth and thus underwater fog
// while avoiding oddities when the water plane is close to the clipping plane
// radialise = radialDepth / linearDepth;
#else
float radialDepth = 0.0;
#endif
vec2 screenCoordsOffset = normal.xy * REFL_BUMP;
@ -355,13 +357,7 @@ void main(void)
gl_FragData[0].w = clamp(fresnel*6.0 + specular * sunSpec.w, 0.0, 1.0); //clamp(fresnel*2.0 + specular * gl_LightSource[0].specular.w, 0.0, 1.0);
#endif
// fog
#if @radialFog
float fogValue = clamp((radialDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#else
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
#endif
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
gl_FragData[0] = applyFogAtDist(gl_FragData[0], radialDepth, linearDepth);
#if !@disableNormals
gl_FragData[1].rgb = normal * 0.5 + 0.5;

Loading…
Cancel
Save