Merge branch 'post_fog' into 'master'

[Postprocessing]  API to work with fog

See merge request OpenMW/openmw!2212
check_span
psi29a 2 years ago
commit 9ba3ab2be9

@ -105,6 +105,7 @@ TestingOpenMW::VFSTestFile repeated_shared_block{R"(
, mImageManager(mVFS.get())
{
Settings::Manager::setBool("radial fog", "Fog", true);
Settings::Manager::setBool("exponential fog", "Fog", false);
Settings::Manager::setBool("stereo enabled", "Stereo", false);
}
@ -201,4 +202,4 @@ TestingOpenMW::VFSTestFile repeated_shared_block{R"(
Log(Debug::Error) << output;
EXPECT_THAT(output, HasSubstr("repeated 'shared' block"));
}
}
}

@ -71,6 +71,7 @@ namespace fx
#define OMW_REVERSE_Z @reverseZ
#define OMW_RADIAL_FOG @radialFog
#define OMW_EXPONENTIAL_FOG @exponentialFog
#define OMW_HDR @hdr
#define OMW_NORMALS @normals
#define OMW_USE_BINDINGS @useBindings
@ -190,6 +191,49 @@ mat4 omw_InvProjectionMatrix()
#endif
}
vec3 omw_GetWorldPosFromUV(vec2 uv)
{
float depth = omw_GetDepth(uv);
#if (OMW_REVERSE_Z == 1)
float flippedDepth = 1.0 - depth;
#else
float flippedDepth = omw_Texture2D(omw_SamplerDepth, uv).r * 2.0 - 1.0;
#endif
vec4 clip_space = vec4(uv * 2.0 - 1.0, flippedDepth, 1.0);
vec4 world_space = omw.invViewMatrix * (omw.invProjectionMatrix * clip_space);
return world_space.xyz / world_space.w;
}
float omw_GetLinearDepth(vec2 uv)
{
#if (OMW_REVERSE_Z == 1)
float depth = omw_GetDepth(uv);
float dist = omw.near * omw.far / (omw.far + depth * (omw.near - omw.far));
#else
float depth = omw_GetDepth(uv) * 2.0 - 1.0;
float dist = 2.0 * omw.near * omw.far / (omw.far + omw.near - depth * (omw.far - omw.near));
#endif
return dist;
}
float omw_EstimateFogCoverageFromUV(vec2 uv)
{
#if OMW_RADIAL_FOG
vec3 uvPos = omw_GetWorldPosFromUV(uv);
float dist = length(uvPos - omw.eyePos.xyz);
#else
float dist = omw_GetLinearDepth(uv);
#endif
#if OMW_EXPONENTIAL_FOG
float fogValue = 1.0 - exp(-2.0 * max(0.0, dist - omw.fogNear/2.0) / (omw.fogFar - omw.fogNear/2.0));
#else
float fogValue = clamp((dist - omw.fogNear) / (omw.fogFar - omw.fogNear), 0.0, 1.0);
#endif
return fogValue;
}
#if OMW_HDR
uniform sampler2D omw_EyeAdaptation;
#endif
@ -220,6 +264,7 @@ mat4 omw_InvProjectionMatrix()
{"@normals", technique.getNormals() ? "1" : "0"},
{"@reverseZ", SceneUtil::AutoDepth::isReversed() ? "1" : "0"},
{"@radialFog", Settings::Manager::getBool("radial fog", "Fog") ? "1" : "0"},
{"@exponentialFog", Settings::Manager::getBool("exponential fog", "Fog") ? "1" : "0"},
{"@hdr", technique.getHDR() ? "1" : "0"},
{"@in", mLegacyGLSL ? "varying" : "in"},
{"@out", mLegacyGLSL ? "varying" : "out"},

@ -122,39 +122,45 @@ Builtin Uniforms
Builtin Macros
##############
+------------------+----------------+---------------------------------------------------------------------------+
| Macro | Definition | Description |
+==================+================+===========================================================================+
|``OMW_REVERSE_Z`` | ``0`` or ``1`` | Whether a reversed depth buffer is in use. |
| | | |
| | | ``0`` Depth sampler will be in range [1, 0] |
| | | |
| | | ``1`` Depth sampler will be in range [0, 1] |
+------------------+----------------+---------------------------------------------------------------------------+
|``OMW_RADIAL_FOG``| ``0`` or ``1`` | Whether radial fog is in use. |
| | | |
| | | ``0`` Fog is linear |
| | | |
| | | ``1`` Fog is radial |
+------------------+----------------+---------------------------------------------------------------------------+
| ``OMW_HDR`` | ``0`` or ``1`` | Whether average scene luminance is computed every frame. |
| | | |
| | | ``0`` Average scene luminance is not computed |
| | | |
| | | ``1`` Average scene luminance is computed |
+------------------+----------------+---------------------------------------------------------------------------+
| ``OMW_NORMALS`` | ``0`` or ``1`` | Whether normals are available as a sampler in the technique. |
| | | |
| | | ``0`` Normals are not available |
| | | |
| | | ``1`` Normals are available. |
+------------------+----------------+---------------------------------------------------------------------------+
| ``OMW_MULTIVIEW``| ``0`` or ``1`` | Whether multiview rendering is in use. |
| | | |
| | | ``0`` Multiview not in use |
| | | |
| | | ``1`` Multiview in use. |
+------------------+----------------+---------------------------------------------------------------------------+
+-----------------------+----------------+----------------------------------------------------------------------+
| Macro | Definition | Description |
+=======================+================+======================================================================+
|``OMW_REVERSE_Z`` | ``0`` or ``1`` | Whether a reversed depth buffer is in use. |
| | | |
| | | ``0`` Depth sampler will be in range [1, 0] |
| | | |
| | | ``1`` Depth sampler will be in range [0, 1] |
+-----------------------+----------------+----------------------------------------------------------------------+
|``OMW_RADIAL_FOG`` | ``0`` or ``1`` | Whether radial fog is in use. |
| | | |
| | | ``0`` Fog is linear |
| | | |
| | | ``1`` Fog is radial |
+-----------------------+----------------+----------------------------------------------------------------------+
|``OMW_EXPONENTIAL_FOG``| ``0`` or ``1`` | Whether exponential fog is in use. |
| | | |
| | | ``0`` Fog is linear |
| | | |
| | | ``1`` Fog is exponential |
+-----------------------+----------------+----------------------------------------------------------------------+
| ``OMW_HDR`` | ``0`` or ``1`` | Whether average scene luminance is computed every frame. |
| | | |
| | | ``0`` Average scene luminance is not computed |
| | | |
| | | ``1`` Average scene luminance is computed |
+-----------------------+----------------+----------------------------------------------------------------------+
| ``OMW_NORMALS`` | ``0`` or ``1`` | Whether normals are available as a sampler in the technique. |
| | | |
| | | ``0`` Normals are not available |
| | | |
| | | ``1`` Normals are available. |
+-----------------------+----------------+----------------------------------------------------------------------+
| ``OMW_MULTIVIEW`` | ``0`` or ``1`` | Whether multiview rendering is in use. |
| | | |
| | | ``0`` Multiview not in use |
| | | |
| | | ``1`` Multiview in use. |
+-----------------------+----------------+----------------------------------------------------------------------+
Builtin Functions
@ -162,27 +168,35 @@ Builtin Functions
The following functions can be accessed in any fragment or vertex shader.
+----------------------------------------+-------------------------------------------------------------------------------+
| Function | Description |
+========================================+===============================================================================+
| ``float omw_GetDepth(vec2)`` | Returns the depth value from a sampler given a uv coordinate. |
| | |
| | Reverses sampled value when ``OMW_REVERSE_Z`` is set. |
+----------------------------------------+-------------------------------------------------------------------------------+
| ``float omw_GetEyeAdaptation()`` | Returns the average scene luminance in range [0, 1]. |
| | |
| | If HDR is not in use, this returns `1.0` |
| | |
| | Scene luminance is always calculated on original scene texture. |
+----------------------------------------+-------------------------------------------------------------------------------+
| ``vec4 omw_GetLastShader(vec2 uv)`` | Returns RGBA color output of the last shader |
+----------------------------------------+-------------------------------------------------------------------------------+
| ``vec4 omw_GetLastPass(vec2 uv)`` | Returns RGBA color output of the last pass |
+----------------------------------------+-------------------------------------------------------------------------------+
| ``vec3 omw_GetNormals(vec2 uv)`` | Returns normalized worldspace normals [-1, 1] |
| | |
| | The values in sampler are in [0, 1] but are transformed to [-1, 1] |
+----------------------------------------+-----------------------+-------------------------------------------------------+
+--------------------------------------------------+-------------------------------------------------------------------------------+
| Function | Description |
+==================================================+===============================================================================+
| ``float omw_GetDepth(vec2)`` | Returns the depth value from a sampler given a uv coordinate. |
| | |
| | Reverses sampled value when ``OMW_REVERSE_Z`` is set. |
+--------------------------------------------------+-------------------------------------------------------------------------------+
| ``float omw_GetEyeAdaptation()`` | Returns the average scene luminance in range [0, 1]. |
| | |
| | If HDR is not in use, this returns `1.0` |
| | |
| | Scene luminance is always calculated on original scene texture. |
+--------------------------------------------------+-------------------------------------------------------------------------------+
| ``vec4 omw_GetLastShader(vec2 uv)`` | Returns RGBA color output of the last shader |
+--------------------------------------------------+-------------------------------------------------------------------------------+
| ``vec4 omw_GetLastPass(vec2 uv)`` | Returns RGBA color output of the last pass |
+--------------------------------------------------+-------------------------------------------------------------------------------+
| ``vec3 omw_GetNormals(vec2 uv)`` | Returns normalized worldspace normals [-1, 1] |
| | |
| | The values in sampler are in [0, 1] but are transformed to [-1, 1] |
+--------------------------------------------------+-----------------------+-------------------------------------------------------+
| ``vec3 omw_GetWorldPosFromUV(vec2 uv)`` | Returns world position for given uv coordinate. |
+--------------------------------------------------+-----------------------+-------------------------------------------------------+
| ``float omw_GetLinearDepth(vec2 uv)`` | Returns the depth in game units for given uv coordinate. |
+--------------------------------------------------+-----------------------+-------------------------------------------------------+
| ``float omw_EstimateFogCoverageFromUV(vec2 uv)`` | Returns a fog coverage in the range from 0.0 (no fog) and 1.0 (full fog) |
| | |
| | Calculates an estimated fog coverage for given uv coordinate. |
+--------------------------------------------------+-----------------------+-------------------------------------------------------+
Special Attributes

@ -13,10 +13,7 @@ fragment main {
void main()
{
float depth = omw_GetDepth(omw_TexCoord);
float zNear = omw.near;
float zFar = omw.far;
omw_FragColor = vec4(vec3((2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear))) * uFactor, 1.0);
omw_FragColor = vec4(vec3(omw_GetLinearDepth(omw_TexCoord) / omw.far * uFactor), 1.0);
}
}

Loading…
Cancel
Save