Skip to content
Snippets Groups Projects
Commit d3c4a125 authored by Alexander Gauggel's avatar Alexander Gauggel
Browse files

[#106] Replace motion tile offset noise with unaligned dither for less visible noise

parent b01d16c2
No related branches found
No related tags found
1 merge request!89Resolve "Indirect Dispatch"
Pipeline #26852 passed
...@@ -113,34 +113,18 @@ SampleData loadSampleData(vec2 uv){ ...@@ -113,34 +113,18 @@ SampleData loadSampleData(vec2 uv){
return data; return data;
} }
const int ditherSize = 4;
// simple binary dither pattern // simple binary dither pattern
// could be optimized to avoid modulo and branch // could be optimized to avoid modulo and branch
float dither(ivec2 coord){ float dither(ivec2 coord){
int ditherSize = 4;
bool x = coord.x % ditherSize < (ditherSize / 2); bool x = coord.x % ditherSize < (ditherSize / 2);
bool y = coord.y % ditherSize < (ditherSize / 2); bool y = coord.y % ditherSize < (ditherSize / 2);
return x ^^ y ? 1 : 0; return x ^^ y ? 1 : 0;
} }
// from https://www.shadertoy.com/view/ttc3zr
uvec2 murmurHash22(uvec2 src) {
const uint M = 0x5bd1e995u;
uvec2 h = uvec2(1190494759u, 2147483647u);
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
vec2 hash22(vec2 src) {
uvec2 h = murmurHash22(floatBitsToUint(src));
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
void main(){ void main(){
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))) if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage))))
...@@ -151,7 +135,8 @@ void main(){ ...@@ -151,7 +135,8 @@ void main(){
vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center
// the motion tile lookup is jittered, so the hard edges in the blur are replaced by noise // the motion tile lookup is jittered, so the hard edges in the blur are replaced by noise
vec2 motionOffset = motionTileOffsetLength * (hash22(coord) * 2 - 1) / textureRes; // dither is shifted, so it does not line up with motion tiles
vec2 motionOffset = motionTileOffsetLength * (dither(coord + ivec2(ditherSize / 2)) * 2 - 1) / textureRes;
vec2 motionNeighbourhoodMax = processMotionVector(texture(sampler2D(inMotionNeighbourhoodMax, nearestSampler), uv + motionOffset).rg); vec2 motionNeighbourhoodMax = processMotionVector(texture(sampler2D(inMotionNeighbourhoodMax, nearestSampler), uv + motionOffset).rg);
SampleData mainPixel = loadSampleData(uv); SampleData mainPixel = loadSampleData(uv);
......
...@@ -97,7 +97,7 @@ void App::run() { ...@@ -97,7 +97,7 @@ void App::run() {
eMotionVectorMode motionBlurMotionMode = eMotionVectorMode::MaxTileNeighbourhood; eMotionVectorMode motionBlurMotionMode = eMotionVectorMode::MaxTileNeighbourhood;
bool freezeFrame = false; bool freezeFrame = false;
float motionBlurTileOffsetLength = 10; float motionBlurTileOffsetLength = 3;
float objectVerticalSpeed = 5; float objectVerticalSpeed = 5;
float objectAmplitude = 0; float objectAmplitude = 0;
float objectMeanHeight = 1; float objectMeanHeight = 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment