From 640d3edd10922bfe01d93c1cca1dc79ee6219770 Mon Sep 17 00:00:00 2001 From: edwin Date: Fri, 2 Aug 2019 16:13:38 +0200 Subject: [PATCH] Add noise filters, CellNoise, SpeckleNoise, HashNoise, ValueNoise --- .../src/main/kotlin/filters/NoiseFilters.kt | 187 ++++++++++++++++++ .../extra/noise/shaders/gl3/cell-noise.frag | 56 ++++++ .../extra/noise/shaders/gl3/hash-noise.frag | 31 +++ .../noise/shaders/gl3/speckle-noise.frag | 35 ++++ .../extra/noise/shaders/gl3/value-noise.frag | 53 +++++ 5 files changed, 362 insertions(+) create mode 100644 orx-noise/src/main/kotlin/filters/NoiseFilters.kt create mode 100644 orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/cell-noise.frag create mode 100644 orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/hash-noise.frag create mode 100644 orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/speckle-noise.frag create mode 100644 orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/value-noise.frag diff --git a/orx-noise/src/main/kotlin/filters/NoiseFilters.kt b/orx-noise/src/main/kotlin/filters/NoiseFilters.kt new file mode 100644 index 00000000..1926e002 --- /dev/null +++ b/orx-noise/src/main/kotlin/filters/NoiseFilters.kt @@ -0,0 +1,187 @@ +package org.openrndr.extra.noise.filters + +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.Filter +import org.openrndr.draw.filterShaderFromUrl +import org.openrndr.math.Vector2 +import org.openrndr.math.Vector4 +import org.openrndr.resourceUrl + +/** + * Hash noise filter that produces white-noise-like noise. + */ +class HashNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/hash-noise.frag"))) { + /** + * noise gain per channel, default is Vector4(1.0, 1.0, 1.0, 0.0) + */ + var gain: Vector4 by parameters + + /** + * noise bias per channel, default is Vector4(0.0, 0.0, 0.0, 1.0) + */ + var bias: Vector4 by parameters + + /** + * is the noise monochrome, default is true + */ + var monochrome: Boolean by parameters + + /** + * noise seed, feed it with time to animate + */ + var seed: Double by parameters + + init { + monochrome = true + gain = Vector4(1.0, 1.0, 1.0, 0.0) + bias = Vector4(0.0, 0.0, 0.0, 1.0) + seed = 0.0 + } +} + +/** + * Speckle noise filter + */ +class SpeckleNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/speckle-noise.frag"))) { + + /** + * The color of the generated speckles + */ + var color: ColorRGBa by parameters + + /** + * Density of the speckles, default is 0.1, min, 0.0, max is 1.0 + */ + + var density: Double by parameters + + + /** + * Noisiness of the generated speckles, default is 0.0, min is 0.0, max is 1.0 + */ + var noise: Double by parameters + + /** + * should the output colors be multiplied by the alpha channel, default is true + */ + var premultipliedAlpha: Boolean by parameters + + /** + * noise seed, feed it with time to animate + */ + var seed: Double by parameters + + init { + density = 0.1 + color = ColorRGBa.WHITE + seed = 0.0 + noise = 0.0 + premultipliedAlpha = true + } +} + +/** + * Filter that produces cell or Voronoi noise + */ +class CellNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/cell-noise.frag"))) { + var seed: Vector2 by parameters + + /** + * base noise scale, default is Vector2(1.0, 1.0) + */ + var scale: Vector2 by parameters + + /** + * lacunarity is the amount by which scale is modulated per octave, default is Vector2(2.0, 2.0) + */ + var lacunarity: Vector2 by parameters + + /** + * gain is the base intensity per channel, default is Vector2(1.0, 1.0, 1.0, 1.0) + */ + var gain: Vector4 by parameters + + /** + * decay is the amount by which gain is modulated per octave, default is Vector4(0.5, 0.5, 0.5, 0.5) + */ + var decay: Vector4 by parameters + + /** + * the number of octaves of noise to generate, default is 4 + */ + var octaves: Int by parameters + + /** + * the value to add to the resulting noise + */ + var bias: Vector4 by parameters + + /** + * should the output colors be multiplied by the alpha channel, default is true + */ + var premultipliedAlpha: Boolean by parameters + + init { + seed = Vector2.ZERO + scale = Vector2.ONE + lacunarity = Vector2(2.0, 2.0) + gain = Vector4.ONE + decay = Vector4.ONE / 2.0 + octaves = 4 + bias = Vector4.ZERO + premultipliedAlpha = true + } +} + +/** + * Filter that produces value noise + */ +class ValueNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/value-noise.frag"))) { + var seed: Vector2 by parameters + + /** + * base noise scale, default is Vector2(1.0, 1.0) + */ + var scale: Vector2 by parameters + + /** + * lacunarity is the amount by which scale is modulated per octave, default is Vector2(2.0, 2.0) + */ + var lacunarity: Vector2 by parameters + + /** + * gain is the base intensity per channel, default is Vector2(1.0, 1.0, 1.0, 1.0) + */ + var gain: Vector4 by parameters + + /** + * decay is the amount by which gain is modulated per octave, default is Vector4(0.5, 0.5, 0.5, 0.5) + */ + var decay: Vector4 by parameters + + /** + * the number of octaves of noise to generate, default is 4 + */ + var octaves: Int by parameters + + /** + * the value to add to the resulting noise + */ + var bias: Vector4 by parameters + + /** + * should the output colors be multiplied by the alpha channel, default is true + */ + var premultipliedAlpha: Boolean by parameters + + init { + seed = Vector2.ZERO + scale = Vector2.ONE + lacunarity = Vector2(2.0, 2.0) + gain = Vector4.ONE + decay = Vector4.ONE / 2.0 + octaves = 4 + bias = Vector4.ZERO + premultipliedAlpha = true + } +} \ No newline at end of file diff --git a/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/cell-noise.frag b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/cell-noise.frag new file mode 100644 index 00000000..ff01d6c7 --- /dev/null +++ b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/cell-noise.frag @@ -0,0 +1,56 @@ +#version 330 + +// uniforms +uniform vec4 gain; +uniform vec4 bias; +uniform vec2 seed; + +uniform vec2 scale; +uniform vec2 lacunarity; +uniform vec4 decay; +uniform int octaves; +uniform bool premultipliedAlpha; + +// varyings +in vec2 v_texCoord0; + +// outputs +out vec4 o_output; + +vec2 hash22(vec2 p) { + float n = sin(dot(p, vec2(41, 289))); + return fract(vec2(262144, 32768)*n); +} + +float cell(vec2 p) { + vec2 ip = floor(p); + p = fract(p); + + float d = 1.0; + for (int i = -1; i <= 1; i++) { + for (int j = -1; j <= 1; j++) { + vec2 cellRef = vec2(i, j); + vec2 offset = hash22(ip + cellRef); + vec2 r = cellRef + offset - p; + float d2 = dot(r, r); + d = min(d, d2); + } + } + return d; +} + +void main() { + vec4 result = vec4(0.0); + vec4 _gain = gain; + vec2 _scale = scale; + for (int o = 0; o < octaves; ++o) { + result += cell((v_texCoord0+seed) * _scale) * _gain; + _scale *= lacunarity; + _gain *= decay; + } + o_output = result + bias; + + if (premultipliedAlpha) { + o_output.rgb *= o_output.a; + } +} \ No newline at end of file diff --git a/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/hash-noise.frag b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/hash-noise.frag new file mode 100644 index 00000000..fc94b2de --- /dev/null +++ b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/hash-noise.frag @@ -0,0 +1,31 @@ +#version 330 + +// uniforms +uniform vec4 gain; +uniform vec4 bias; +uniform bool monochrome; +uniform float seed; + +// varyings +in vec2 v_texCoord0; + +// outputs +out vec4 o_output; + +vec2 hash22(vec2 p) { + float n = sin(dot(p, vec2(41, 289))); + return fract(vec2(262144, 32768)*n); +} + +void main() { + + vec2 vseed = vec2(seed); + if (!monochrome) { + o_output.rg = hash22(vseed + v_texCoord0) * gain.rg + bias.rg; + o_output.ba = hash22(vseed + v_texCoord0+vec2(1.0, 1.0)) * gain.ba + bias.ba; + } else { + float c = hash22(vseed + v_texCoord0).r; + o_output = c * gain + bias; + } + +} \ No newline at end of file diff --git a/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/speckle-noise.frag b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/speckle-noise.frag new file mode 100644 index 00000000..2223e2a9 --- /dev/null +++ b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/speckle-noise.frag @@ -0,0 +1,35 @@ +#version 330 + +// uniforms +uniform float seed; +uniform float density; +uniform vec4 color; +uniform bool premultipliedAlpha; +uniform float noise; + +// varyings +in vec2 v_texCoord0; + +// outputs +out vec4 o_output; + +vec2 hash22(vec2 p) { + float n = sin(dot(p, vec2(41, 289))); + return fract(vec2(262144, 32768)*n); +} + +void main() { + vec2 vseed = vec2(seed); + vec2 hash = hash22(v_texCoord0 + seed); + float t = hash.x; + + vec4 result = vec4(0.0); + if (t < density) { + vec4 noisyColor = vec4(color.rgb * mix(1.0, hash.y, noise), color.a); + result = noisyColor; + } + o_output = result; + if (premultipliedAlpha) { + o_output.rgb *= o_output.a; + } +} \ No newline at end of file diff --git a/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/value-noise.frag b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/value-noise.frag new file mode 100644 index 00000000..444f5094 --- /dev/null +++ b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/value-noise.frag @@ -0,0 +1,53 @@ +#version 330 +// based on https://www.shadertoy.com/view/4dS3Wd + +// uniforms +uniform vec4 gain; +uniform vec4 bias; +uniform vec2 seed; + +uniform vec2 scale; +uniform vec2 lacunarity; +uniform vec4 decay; +uniform int octaves; +uniform bool premultipliedAlpha; + +// varyings +in vec2 v_texCoord0; + +// outputs +out vec4 o_output; + +float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } + +float noise(vec2 x) { + vec2 i = floor(x); + vec2 f = fract(x); + + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + +void main() { + vec4 result = vec4(0.0); + vec4 _gain = gain; + + vec2 shift = vec2(100); + mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50)); + vec2 x = ((v_texCoord0+seed) * scale); + for (int o = 0; o < octaves; ++o) { + result += noise(x) * _gain; + x = rot * x * lacunarity + shift; + _gain *= decay; + } + o_output = result + bias; + + if (premultipliedAlpha) { + o_output.rgb *= o_output.a; + } +} \ No newline at end of file