mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-02 04:39:16 +01:00
Sample the fog cells in their middle across the view and dither the output
This commit is contained in:
21
shaders/dither.glsl
Normal file
21
shaders/dither.glsl
Normal file
@@ -0,0 +1,21 @@
|
||||
// noise of half a step of the 8-bit output, added to the colour about to be written to the window: smooth dark gradients (the
|
||||
// fog at night) show no bands, which otherwise crawl over the image with the smallest change of the light. interleaved gradient
|
||||
// noise (Jimenez 2014) of the pixel, the same in every frame. the colour is the one written to the window: encoded already with
|
||||
// OUTPUT_GAMMA, linear otherwise (the sRGB framebuffer encodes it, so the step is taken in the encoded values)
|
||||
#ifndef DITHER_GLSL
|
||||
#define DITHER_GLSL
|
||||
|
||||
vec3 dither_output(vec3 color)
|
||||
{
|
||||
float noise = (fract(52.9829189 * fract(dot(gl_FragCoord.xy, vec2(0.06711056, 0.00583715)))) - 0.5) / 255.0;
|
||||
#if OUTPUT_GAMMA
|
||||
return max(color + noise, vec3(0.0));
|
||||
#else
|
||||
vec3 linear = max(color, vec3(0.0));
|
||||
vec3 encoded = mix(linear * 12.92, 1.055 * pow(linear, vec3(1.0 / 2.4)) - 0.055, step(vec3(0.0031308), linear));
|
||||
encoded = max(encoded + noise, vec3(0.0));
|
||||
return mix(encoded / 12.92, pow((encoded + 0.055) / 1.055, vec3(2.4)), step(vec3(0.04045), encoded));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,10 @@
|
||||
// depth), how dense the fog is and how much light it scatters towards the camera. the density: the haze, the patches of the
|
||||
// ground fog, the low clouds; the light: the colour the fog has towards the horizon (weather_common.glsl), less what the
|
||||
// shadows of the sun and of the clouds hold back, and the lamps and headlights of the light clusters. blended with the
|
||||
// previous frame, found where the cell was then; the cells are sampled at another point every frame, each cell going through
|
||||
// the points from a place of its own, so the volume doesn't flicker as a whole and the blending smooths the edges of the cells.
|
||||
// previous frame, found where the cell was then; the cells are sampled at another depth every frame, each cell going through
|
||||
// the depths from a place of its own, so the volume doesn't flicker as a whole. across the view the cells are sampled in their
|
||||
// middle: moved across, the ray of a cell crosses the edges of the cones of lamps somewhere else every frame, which the blending
|
||||
// doesn't smooth out (the edges of the cells are smoothed when the fog is read, fog_volume.glsl)
|
||||
// rgb: light scattered towards the camera per metre, a: extinction per metre
|
||||
|
||||
#include <common>
|
||||
@@ -36,8 +38,6 @@ layout(location = 6) uniform vec4 options;
|
||||
layout(location = 7) uniform int cablamp;
|
||||
// x: near, y: slices / log((far + FOG_VOLUME_BIAS) / (near + FOG_VOLUME_BIAS)) of the previous frame
|
||||
layout(location = 8) uniform vec2 previous_slicing;
|
||||
// where in its cell the cell is sampled this frame across the view (0-1), as slicing.w is along the depth
|
||||
layout(location = 9) uniform vec2 jitter;
|
||||
|
||||
// how many times brighter or darker than this frame the light of the history may be
|
||||
const float FOG_HISTORY_REACH = 4.0;
|
||||
@@ -56,8 +56,8 @@ float slice_depth(float slice)
|
||||
return (slicing.x + FOG_VOLUME_BIAS) * exp(slice / slicing.z) - FOG_VOLUME_BIAS;
|
||||
}
|
||||
|
||||
// where in the cell it is sampled this frame, 0-1 on each axis: the point of the sequence of the frames moved by a value of
|
||||
// the cell's own (pcg3d hash), the middle without the blending
|
||||
// where in the cell it is sampled this frame, 0-1 on each axis: across the view the middle, along the depth the point of the
|
||||
// sequence of the frames moved by a value of the cell's own (pcg3d hash), the middle without the blending
|
||||
vec3 cell_offset(ivec3 cell)
|
||||
{
|
||||
if (options.x >= 1.0)
|
||||
@@ -70,7 +70,7 @@ vec3 cell_offset(ivec3 cell)
|
||||
v.x += v.y * v.z;
|
||||
v.y += v.z * v.x;
|
||||
v.z += v.x * v.y;
|
||||
return fract(vec3(jitter, slicing.w) + vec3(v >> 8U) * (1.0 / 16777216.0));
|
||||
return vec3(0.5, 0.5, fract(slicing.w + float(v.z >> 8U) * (1.0 / 16777216.0)));
|
||||
}
|
||||
|
||||
float henyey_greenstein(float cosangle, float g)
|
||||
|
||||
@@ -6,6 +6,8 @@ layout(location = 0) out vec4 out_color;
|
||||
|
||||
uniform sampler2D iChannel0;
|
||||
|
||||
#include <dither.glsl>
|
||||
|
||||
vec2 barrelDistortion(vec2 f_coords, float amt) {
|
||||
vec2 cc = f_coords - 0.5;
|
||||
float dist = dot(cc, cc);
|
||||
@@ -54,4 +56,5 @@ void main()
|
||||
}
|
||||
|
||||
out_color = sumcol / sumw;
|
||||
out_color.rgb = dither_output(out_color.rgb);
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ layout(std430, binding = EXPOSURE_SSBO_BINDING) readonly buffer exposure_ssbo
|
||||
};
|
||||
|
||||
#include <tonemapping.glsl>
|
||||
#include <dither.glsl>
|
||||
|
||||
// param[0].x: share of the bloom in the image (0: no bloom, the texture is not read), param[0].y: 1 if the automatic
|
||||
// exposure is applied, param[0].z: fixed exposure multiplier, param[0].w: scale of the bloom texture (it holds the sum of
|
||||
// the levels of the chain)
|
||||
// the levels of the chain), param[1].x: 1 when this is the last pass before the window, which takes the dither
|
||||
void main()
|
||||
{
|
||||
vec2 texcoord = f_coords;
|
||||
@@ -36,4 +37,6 @@ void main()
|
||||
if (param[0].y > 0.5 && exposure > 0.0)
|
||||
exposurescale *= exposure;
|
||||
out_color = tonemap(vec4(hdr_color * exposurescale, 1.0));
|
||||
if (param[1].x > 0.5)
|
||||
out_color.rgb = dither_output(out_color.rgb);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user