From 7f80f00a4af26d4b65feb3ddd542d8a7e74e5a98 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 23 Feb 2016 22:03:33 +0100 Subject: [PATCH] Add basic gamma corrected linear and cubic filters. --- cubic/cubic-gamma-correct.slang | 84 ++++++++++++++++++++++++++++++ cubic/cubic-gamma-correct.slangp | 10 ++++ cubic/cubic.slang | 83 +++++++++++++++++++++++++++++ cubic/cubic.slangp | 3 ++ cubic/linearize.slang | 32 ++++++++++++ linear/linear-gamma-correct.slang | 31 +++++++++++ linear/linear-gamma-correct.slangp | 10 ++++ linear/linearize.slang | 32 ++++++++++++ 8 files changed, 285 insertions(+) create mode 100644 cubic/cubic-gamma-correct.slang create mode 100644 cubic/cubic-gamma-correct.slangp create mode 100644 cubic/cubic.slang create mode 100644 cubic/cubic.slangp create mode 100644 cubic/linearize.slang create mode 100644 linear/linear-gamma-correct.slang create mode 100644 linear/linear-gamma-correct.slangp create mode 100644 linear/linearize.slang diff --git a/cubic/cubic-gamma-correct.slang b/cubic/cubic-gamma-correct.slang new file mode 100644 index 00000000..5c7f57a3 --- /dev/null +++ b/cubic/cubic-gamma-correct.slang @@ -0,0 +1,84 @@ +#version 450 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void weights(out vec4 x, out vec4 y, vec2 t) +{ + vec2 t2 = t * t; + vec2 t3 = t2 * t; + + vec4 xs = vec4(1.0, t.x, t2.x, t3.x); + vec4 ys = vec4(1.0, t.y, t2.y, t3.y); + + const vec4 p0 = vec4(+0.0, -0.5, +1.0, -0.5); + const vec4 p1 = vec4(+1.0, 0.0, -2.5, +1.5); + const vec4 p2 = vec4(+0.0, +0.5, +2.0, -1.5); + const vec4 p3 = vec4(+0.0, 0.0, -0.5, +0.5); + + x = vec4(dot(xs, p0), dot(xs, p1), dot(xs, p2), dot(xs, p3)); + y = vec4(dot(ys, p0), dot(ys, p1), dot(ys, p2), dot(ys, p3)); +} + +void main() +{ + vec2 uv = vTexCoord * global.SourceSize.xy - 0.5; + vec2 texel = floor(uv); + vec2 tex = (texel + 0.5) * global.SourceSize.zw; + vec2 phase = uv - texel; + +#define TEX(x, y) textureLodOffset(Source, tex, 0.0, ivec2(x, y)).rgb + + vec4 x; + vec4 y; + weights(x, y, phase); + + vec3 color; + vec4 row = x * y.x; + color = TEX(-1, -1) * row.x; + color += TEX(+0, -1) * row.y; + color += TEX(+1, -1) * row.z; + color += TEX(+2, -1) * row.w; + + row = x * y.y; + color += TEX(-1, +0) * row.x; + color += TEX(+0, +0) * row.y; + color += TEX(+1, +0) * row.z; + color += TEX(+2, +0) * row.w; + + row = x * y.z; + color += TEX(-1, +1) * row.x; + color += TEX(+0, +1) * row.y; + color += TEX(+1, +1) * row.z; + color += TEX(+2, +1) * row.w; + + row = x * y.w; + color += TEX(-1, +2) * row.x; + color += TEX(+0, +2) * row.y; + color += TEX(+1, +2) * row.z; + color += TEX(+2, +2) * row.w; + + color = sqrt(clamp(color, vec3(0.0), vec3(1.0))); + FragColor = vec4(color, 1.0); +} diff --git a/cubic/cubic-gamma-correct.slangp b/cubic/cubic-gamma-correct.slangp new file mode 100644 index 00000000..4d3dd747 --- /dev/null +++ b/cubic/cubic-gamma-correct.slangp @@ -0,0 +1,10 @@ +shaders = 2 +shader0 = linearize.slang +shader1 = cubic-gamma-correct.slang + +filter_linear0 = false +scale_type0 = source +scale0 = 1.0 +srgb_framebuffer0 = true + +filter_linear1 = false diff --git a/cubic/cubic.slang b/cubic/cubic.slang new file mode 100644 index 00000000..a294794d --- /dev/null +++ b/cubic/cubic.slang @@ -0,0 +1,83 @@ +#version 450 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void weights(out vec4 x, out vec4 y, vec2 t) +{ + vec2 t2 = t * t; + vec2 t3 = t2 * t; + + vec4 xs = vec4(1.0, t.x, t2.x, t3.x); + vec4 ys = vec4(1.0, t.y, t2.y, t3.y); + + const vec4 p0 = vec4(+0.0, -0.5, +1.0, -0.5); + const vec4 p1 = vec4(+1.0, 0.0, -2.5, +1.5); + const vec4 p2 = vec4(+0.0, +0.5, +2.0, -1.5); + const vec4 p3 = vec4(+0.0, 0.0, -0.5, +0.5); + + x = vec4(dot(xs, p0), dot(xs, p1), dot(xs, p2), dot(xs, p3)); + y = vec4(dot(ys, p0), dot(ys, p1), dot(ys, p2), dot(ys, p3)); +} + +void main() +{ + vec2 uv = vTexCoord * global.SourceSize.xy - 0.5; + vec2 texel = floor(uv); + vec2 tex = (texel + 0.5) * global.SourceSize.zw; + vec2 phase = uv - texel; + +#define TEX(x, y) textureLodOffset(Source, tex, 0.0, ivec2(x, y)).rgb + + vec4 x; + vec4 y; + weights(x, y, phase); + + vec3 color; + vec4 row = x * y.x; + color = TEX(-1, -1) * row.x; + color += TEX(+0, -1) * row.y; + color += TEX(+1, -1) * row.z; + color += TEX(+2, -1) * row.w; + + row = x * y.y; + color += TEX(-1, +0) * row.x; + color += TEX(+0, +0) * row.y; + color += TEX(+1, +0) * row.z; + color += TEX(+2, +0) * row.w; + + row = x * y.z; + color += TEX(-1, +1) * row.x; + color += TEX(+0, +1) * row.y; + color += TEX(+1, +1) * row.z; + color += TEX(+2, +1) * row.w; + + row = x * y.w; + color += TEX(-1, +2) * row.x; + color += TEX(+0, +2) * row.y; + color += TEX(+1, +2) * row.z; + color += TEX(+2, +2) * row.w; + + FragColor = vec4(color, 1.0); +} diff --git a/cubic/cubic.slangp b/cubic/cubic.slangp new file mode 100644 index 00000000..fa882ac1 --- /dev/null +++ b/cubic/cubic.slangp @@ -0,0 +1,3 @@ +shaders = 1 +shader0 = cubic.slang +filter_linear0 = false diff --git a/cubic/linearize.slang b/cubic/linearize.slang new file mode 100644 index 00000000..d54a1515 --- /dev/null +++ b/cubic/linearize.slang @@ -0,0 +1,32 @@ +#version 450 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +vec3 gamma(vec3 v) +{ + return v * v; +} + +void main() +{ + FragColor = vec4(gamma(texture(Source, vTexCoord).rgb), 1.0); +} diff --git a/linear/linear-gamma-correct.slang b/linear/linear-gamma-correct.slang new file mode 100644 index 00000000..de3f0ff7 --- /dev/null +++ b/linear/linear-gamma-correct.slang @@ -0,0 +1,31 @@ +#version 450 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + vec3 color = texture(Source, vTexCoord).rgb; + FragColor = vec4(sqrt(color), 1.0); +} diff --git a/linear/linear-gamma-correct.slangp b/linear/linear-gamma-correct.slangp new file mode 100644 index 00000000..beb4d1b4 --- /dev/null +++ b/linear/linear-gamma-correct.slangp @@ -0,0 +1,10 @@ +shaders = 2 +shader0 = linearize.slang +shader1 = linear-gamma-correct.slang + +filter_linear0 = false +scale_type0 = source +scale0 = 1.0 +srgb_framebuffer0 = true + +filter_linear1 = true diff --git a/linear/linearize.slang b/linear/linearize.slang new file mode 100644 index 00000000..d54a1515 --- /dev/null +++ b/linear/linearize.slang @@ -0,0 +1,32 @@ +#version 450 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +vec3 gamma(vec3 v) +{ + return v * v; +} + +void main() +{ + FragColor = vec4(gamma(texture(Source, vTexCoord).rgb), 1.0); +}