mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 17:15:34 +00:00
Merge pull request #2721 from akortunov/radial_fog
Support for radial fog
This commit is contained in:
commit
e80fbf4786
11 changed files with 64 additions and 20 deletions
|
@ -225,6 +225,7 @@
|
|||
Feature #4544: Actors movement deceleration
|
||||
Feature #4673: Weapon sheathing
|
||||
Feature #4675: Support for NiRollController
|
||||
Feature #4708: Radial fog support
|
||||
Feature #4730: Native animated containers support
|
||||
Feature #4784: Launcher: Duplicate Content Lists
|
||||
Feature #4812: Support NiSwitchNode
|
||||
|
|
|
@ -82,6 +82,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
|
|||
defines["forcePPL"] = "0"; // Don't force per-pixel lighting
|
||||
defines["clamp"] = "1"; // Clamp lighting
|
||||
defines["preLightEnv"] = "0"; // Apply environment maps after lighting like Morrowind
|
||||
defines["radialFog"] = "0";
|
||||
for (const auto& define : shadowDefines)
|
||||
defines[define.first] = define.second;
|
||||
mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(defines);
|
||||
|
|
|
@ -218,7 +218,9 @@ namespace MWRender
|
|||
{
|
||||
resourceSystem->getSceneManager()->setParticleSystemMask(SceneUtil::Mask_ParticleSystem);
|
||||
resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders");
|
||||
resourceSystem->getSceneManager()->setForceShaders(Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("enable shadows", "Shadows")); // Shadows have problems with fixed-function mode
|
||||
// Shadows and radial fog have problems with fixed-function mode
|
||||
bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") || Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("enable shadows", "Shadows");
|
||||
resourceSystem->getSceneManager()->setForceShaders(forceShaders);
|
||||
// FIXME: calling dummy method because terrain needs to know whether lighting is clamped
|
||||
resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders"));
|
||||
resourceSystem->getSceneManager()->setAutoUseNormalMaps(Settings::Manager::getBool("auto use object normal maps", "Shaders"));
|
||||
|
@ -255,6 +257,7 @@ 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";
|
||||
|
||||
// It is unnecessary to stop/start the viewer as no frames are being rendered yet.
|
||||
mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(globalDefines);
|
||||
|
|
|
@ -135,3 +135,14 @@ apply lighting to environment maps
|
|||
Normally environment map reflections aren't affected by lighting, which makes environment-mapped (and thus bump-mapped objects) glow in the dark.
|
||||
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.
|
||||
|
|
|
@ -350,6 +350,10 @@ 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
|
||||
|
||||
[Input]
|
||||
|
||||
# Capture control of the cursor prevent movement outside the window.
|
||||
|
|
|
@ -49,7 +49,8 @@ uniform vec2 envMapLumaBias;
|
|||
uniform mat2 bumpMapMatrix;
|
||||
#endif
|
||||
|
||||
varying float depth;
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
|
||||
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||
|
||||
|
@ -146,7 +147,7 @@ void main()
|
|||
|
||||
#endif
|
||||
|
||||
float shadowing = unshadowedLightRatio(depth);
|
||||
float shadowing = unshadowedLightRatio(linearDepth);
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
|
||||
|
@ -178,8 +179,11 @@ void main()
|
|||
#endif
|
||||
|
||||
gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos.xyz), shininess, matSpec) * shadowing;
|
||||
|
||||
float fogValue = clamp((depth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||
#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);
|
||||
|
||||
applyShadowDebugOverlay();
|
||||
|
|
|
@ -37,7 +37,8 @@ varying vec2 bumpMapUV;
|
|||
varying vec2 specularMapUV;
|
||||
#endif
|
||||
|
||||
varying float depth;
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
|
||||
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||
|
||||
|
@ -57,10 +58,12 @@ varying vec3 passNormal;
|
|||
void main(void)
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
depth = gl_Position.z;
|
||||
|
||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
gl_ClipVertex = viewPos;
|
||||
euclideanDepth = length(viewPos.xyz);
|
||||
linearDepth = gl_Position.z;
|
||||
|
||||
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||
|
||||
#if @envMap
|
||||
|
|
|
@ -12,7 +12,8 @@ uniform sampler2D normalMap;
|
|||
uniform sampler2D blendMap;
|
||||
#endif
|
||||
|
||||
varying float depth;
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
|
||||
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||
|
||||
|
@ -66,7 +67,7 @@ void main()
|
|||
gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a;
|
||||
#endif
|
||||
|
||||
float shadowing = unshadowedLightRatio(depth);
|
||||
float shadowing = unshadowedLightRatio(linearDepth);
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
|
||||
|
@ -90,7 +91,11 @@ void main()
|
|||
|
||||
gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos), shininess, matSpec) * shadowing;
|
||||
|
||||
float fogValue = clamp((depth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||
#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);
|
||||
|
||||
applyShadowDebugOverlay();
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#version 120
|
||||
|
||||
varying vec2 uv;
|
||||
varying float depth;
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
|
||||
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||
|
||||
|
@ -21,10 +22,11 @@ varying vec3 passNormal;
|
|||
void main(void)
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
depth = gl_Position.z;
|
||||
|
||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
gl_ClipVertex = viewPos;
|
||||
euclideanDepth = length(viewPos.xyz);
|
||||
linearDepth = gl_Position.z;
|
||||
|
||||
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ vec2 normalCoords(vec2 uv, float scale, float speed, float time, float timer1, f
|
|||
|
||||
varying vec3 screenCoordsPassthrough;
|
||||
varying vec4 position;
|
||||
varying float depthPassthrough;
|
||||
varying float linearDepth;
|
||||
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
|
@ -160,7 +160,7 @@ void main(void)
|
|||
vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
|
||||
UV.y *= -1.0;
|
||||
|
||||
float shadow = unshadowedLightRatio(depthPassthrough);
|
||||
float shadow = unshadowedLightRatio(linearDepth);
|
||||
|
||||
vec2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z;
|
||||
screenCoords.y = (1.0-screenCoords.y);
|
||||
|
@ -203,11 +203,17 @@ void main(void)
|
|||
float ior = (cameraPos.z>0.0)?(1.333/1.0):(1.0/1.333); // air to water; water to air
|
||||
float fresnel = clamp(fresnel_dielectric(vVec, normal, ior), 0.0, 1.0);
|
||||
|
||||
#if @radialFog
|
||||
float radialDepth = distance(position.xyz, cameraPos);
|
||||
float radialize = radialDepth / linearDepth;
|
||||
#else
|
||||
float radialize = 1.0;
|
||||
#endif
|
||||
vec2 screenCoordsOffset = normal.xy * REFL_BUMP;
|
||||
#if REFRACTION
|
||||
float depthSample = linearizeDepth(texture2D(refractionDepthMap,screenCoords).x);
|
||||
float depthSampleDistorted = linearizeDepth(texture2D(refractionDepthMap,screenCoords-screenCoordsOffset).x);
|
||||
float surfaceDepth = linearizeDepth(gl_FragCoord.z);
|
||||
float depthSample = linearizeDepth(texture2D(refractionDepthMap,screenCoords).x) * radialize;
|
||||
float depthSampleDistorted = linearizeDepth(texture2D(refractionDepthMap,screenCoords-screenCoordsOffset).x) * radialize;
|
||||
float surfaceDepth = linearizeDepth(gl_FragCoord.z) * radialize;
|
||||
float realWaterDepth = depthSample - surfaceDepth; // undistorted water depth in view direction, independent of frustum
|
||||
screenCoordsOffset *= clamp(realWaterDepth / BUMP_SUPPRESS_DEPTH,0,1);
|
||||
#endif
|
||||
|
@ -246,7 +252,11 @@ void main(void)
|
|||
#endif
|
||||
|
||||
// fog
|
||||
float fogValue = clamp((depthPassthrough - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||
#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);
|
||||
|
||||
applyShadowDebugOverlay();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
varying vec3 screenCoordsPassthrough;
|
||||
varying vec4 position;
|
||||
varying float depthPassthrough;
|
||||
varying float linearDepth;
|
||||
|
||||
#include "shadows_vertex.glsl"
|
||||
|
||||
|
@ -20,7 +20,7 @@ void main(void)
|
|||
|
||||
position = gl_Vertex;
|
||||
|
||||
depthPassthrough = gl_Position.z;
|
||||
linearDepth = gl_Position.z;
|
||||
|
||||
setupShadowCoords(gl_ModelViewMatrix * gl_Vertex, normalize((gl_NormalMatrix * gl_Normal).xyz));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue