Add orx-fx, the new home for what was in openrndr-filter before

This commit is contained in:
Edwin Jakobs
2019-12-04 14:04:46 +01:00
parent 6bfc4e274d
commit d192519e5c
42 changed files with 1244 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
package org.openrndr.extra.fx
import org.openrndr.resourceUrl
import java.net.URL
internal class FilterTools
internal fun filterFragmentCode(resourceId: String): String {
val urlString = resourceUrl("gl3/$resourceId", FilterTools::class.java)
return URL(urlString).readText()
}

View File

@@ -0,0 +1,37 @@
package org.openrndr.extra.fx.antialias
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
/**
* FXAA approximate antialiasing filter. Only works on LDR inputs
*/
class FXAA : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("antialias/fxaa.frag"))) {
/**
* luma threshold, default value is 0.5
*/
var lumaThreshold: Double by parameters
/**
* max search span, default value is 8.0
*/
var maxSpan: Double by parameters
/**
* direction reduce multiplier, default value is 0.0
*/
var directionReduceMultiplier: Double by parameters
/**
* direction reduce minimum, default value is 0.0
*/
var directionReduceMinimum: Double by parameters
init {
lumaThreshold = 0.5
maxSpan = 8.0
directionReduceMinimum = 0.0
directionReduceMultiplier = 0.0
}
}

View File

@@ -0,0 +1,27 @@
package org.openrndr.extra.fx.blend
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
class ColorBurn : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/color-burn.frag")))
class ColorDodge : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/color-dodge.frag")))
class Darken : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/darken.frag")))
class HardLight : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/hard-light.frag")))
class Lighten : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/lighten.frag")))
class Multiply : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/multiply.frag")))
class Normal : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/normal.frag")))
class Overlay : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/overlay.frag")))
class Screen : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/screen.frag")))
class SourceIn : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/source-in.frag")))
class SourceOut : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/source-out.frag")))
class DestinationIn : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/destination-in.frag")))
class DestinationOut : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/destination-out.frag")))
class Xor : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/xor.frag")))
class MultiplyContrast : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/multiply-contrast.frag")))
class Passthrough : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/passthrough.frag")))
class Add : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/add.frag")))
class Subtract : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("blend/subtract.frag")))

View File

@@ -0,0 +1,66 @@
package org.openrndr.extra.fx.blur
import org.openrndr.draw.ColorBuffer
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.draw.colorBuffer
import org.openrndr.extra.fx.filterFragmentCode
import org.openrndr.math.Vector2
/**
* Approximate separated Gaussian blur
*/
class ApproximateGaussianBlur : Filter(Shader.createFromCode(Filter.filterVertexCode,
filterFragmentCode("blur/approximate-gaussian-blur.frag"))) {
/**
* blur sample window, default value is 5
*/
var window: Int by parameters
/**
* spread multiplier, default value is 1.0
*/
var spread: Double by parameters
/**
* blur sigma, default value is 1.0
*/
var sigma: Double by parameters
/**
* post blur gain, default value is 1.0
*/
var gain: Double by parameters
private var intermediate: ColorBuffer? = null
init {
window = 5
spread = 1.0
gain = 1.0
sigma = 1.0
}
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
intermediate?.let {
if (it.width != target[0].width || it.height != target[0].height) {
intermediate = null
}
}
if (intermediate == null) {
intermediate = colorBuffer(target[0].width, target[0].height, target[0].contentScale, target[0].format, target[0].type)
}
intermediate?.let {
parameters["blurDirection"] = Vector2(1.0, 0.0)
super.apply(source, arrayOf(it))
parameters["blurDirection"] = Vector2(0.0, 1.0)
super.apply(arrayOf(it), target)
}
}
}

View File

@@ -0,0 +1,59 @@
package org.openrndr.extra.fx.blur
import org.openrndr.draw.ColorBuffer
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.draw.colorBuffer
import org.openrndr.extra.fx.filterFragmentCode
import org.openrndr.math.Vector2
/**
* BoxBlur implemented as a separable filter
*/
class BoxBlur : Filter(Shader.createFromCode(Filter.filterVertexCode,
filterFragmentCode("blur/box-blur.frag"))) {
/**
* The sample window, default is 5
*/
var window: Int by parameters
/**
* Spread multiplier, default is 1.0
*/
var spread: Double by parameters
/**
* Post-blur gain, default is 1.0
*/
var gain: Double by parameters
private var intermediate: ColorBuffer? = null
init {
window = 5
spread = 1.0
gain = 1.0
}
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
intermediate?.let {
if (it.width != target[0].width || it.height != target[0].height) {
intermediate = null
}
}
if (intermediate == null) {
intermediate = colorBuffer(target[0].width, target[0].height, target[0].contentScale, target[0].format, target[0].type)
}
intermediate?.let {
parameters["blurDirection"] = Vector2(1.0, 0.0)
super.apply(source, arrayOf(it))
parameters["blurDirection"] = Vector2(0.0, 1.0)
super.apply(arrayOf(it), target)
}
}
}

View File

@@ -0,0 +1,39 @@
package org.openrndr.extra.fx.blur
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
/**
* Exact Gaussian blur, implemented as a single pass filter
*/
class GaussianBlur : Filter(Shader.createFromCode(Filter.filterVertexCode,
filterFragmentCode("blur/gaussian-blur.frag"))) {
/**
* The sample window, default value is 5
*/
var window: Int by parameters
/**
* Spread multiplier, default value is 1.0
*/
var spread: Double by parameters
/**
* Blur kernel sigma, default value is 1.0
*/
var sigma: Double by parameters
/**
* Post-blur gain, default value is 1.0
*/
var gain: Double by parameters
init {
window = 5
spread = 1.0
sigma = 1.0
gain = 1.0
}
}

View File

@@ -0,0 +1,35 @@
package org.openrndr.extra.fx.blur
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
class HashBlur : Filter(Shader.createFromCode(Filter.filterVertexCode,
filterFragmentCode("blur/hash-blur.frag"))) {
/**
* Blur radius in pixels, default is 5.0
*/
var radius: Double by parameters
/**
* Time/seed, this should be fed with seconds, default is 0.0
*/
var time: Double by parameters
/**
* Number of samples, default is 30
*/
var samples: Int by parameters
/**
* Post-blur gain, default is 1.0
*/
var gain: Double by parameters
init {
radius = 5.0
time = 0.0
samples = 30
gain = 1.0
}
}

View File

@@ -0,0 +1,30 @@
package org.openrndr.extra.fx.color
import org.openrndr.draw.*
import org.openrndr.extra.fx.filterFragmentCode
class ColorLookup(lookup: ColorBuffer) : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("color/color-lookup.frag"))) {
/** a color look-up texture */
var lookup: ColorBuffer by parameters
/**
* noise gain in look-up, default value is 0.0
*/
var noiseGain: Double by parameters
/**
* noise seed, default value is 0.0
*/
var seed: Double by parameters
init {
this.lookup = lookup
this.noiseGain = 0.0
this.seed = 0.0
}
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
lookup.filter(MinifyingFilter.LINEAR, MagnifyingFilter.LINEAR)
super.apply(source, target)
}
}

View File

@@ -0,0 +1,9 @@
package org.openrndr.extra.fx.color
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
class ColorMix : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("color/color-mix.frag"))) {
}

View File

@@ -0,0 +1,14 @@
package org.openrndr.extra.fx.color
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
class SubtractConstant : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("color/subtract-constant.frag"))) {
var constant: ColorRGBa by parameters
init {
constant = ColorRGBa(1.0, 1.0, 1.0, 0.0)
}
}

View File

@@ -0,0 +1,25 @@
package org.openrndr.extra.fx.dither
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
class ADither: Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("dither/a-dither.frag"))) {
var pattern: Int
set(value) {
parameters["pattern"] = value
}
get() = parameters["pattern"] as Int
var levels: Int
set(value) {
parameters["levels"] = value;
}
get() = parameters["levels"] as Int
init {
levels = 4
pattern = 3
}
}

View File

@@ -0,0 +1,10 @@
package org.openrndr.extra.fx.transform
import org.openrndr.draw.Filter
import org.openrndr.draw.Shader
import org.openrndr.extra.fx.filterFragmentCode
/**
* Vertically flips in the input image
*/
class FlipVertically : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("transform/flip-vertically.frag")))

View File

@@ -0,0 +1,121 @@
#version 330 core
//uniform vec2 u_texelStep;
uniform float lumaThreshold;
uniform float maxSpan;
uniform float directionReduceMultiplier;
uniform float directionReduceMinimum;
uniform sampler2D tex0;
in vec2 v_texCoord0;
out vec4 fragColor;
// see FXAA
// http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
// http://iryoku.com/aacourse/downloads/09-FXAA-3.11-in-15-Slides.pdf
// http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA
void main(void)
{
const int u_showEdges = 0;
const int u_fxaaOn = 1;
vec2 u_texelStep = 1.0 / textureSize(tex0, 0);
vec3 rgbM = min(vec3(1), texture(tex0, v_texCoord0).rgb);
// Possibility to toggle FXAA on and off.
if (u_fxaaOn == 0)
{
fragColor = vec4(rgbM, 1.0);
return;
}
// Sampling neighbour texels. Offsets are adapted to OpenGL texture coordinates.
vec3 rgbNW = min(vec3(1),textureOffset(tex0, v_texCoord0, ivec2(-1, 1)).rgb);
vec3 rgbNE = min(vec3(1),textureOffset(tex0, v_texCoord0, ivec2(1, 1)).rgb);
vec3 rgbSW = min(vec3(1),textureOffset(tex0, v_texCoord0, ivec2(-1, -1)).rgb);
vec3 rgbSE = min(vec3(1),textureOffset(tex0, v_texCoord0, ivec2(1, -1)).rgb);
// see http://en.wikipedia.org/wiki/Grayscale
const vec3 toLuma = vec3(0.299, 0.587, 0.114);
// Convert from RGB to luma.
float lumaNW = dot(rgbNW, toLuma);
float lumaNE = dot(rgbNE, toLuma);
float lumaSW = dot(rgbSW, toLuma);
float lumaSE = dot(rgbSE, toLuma);
float lumaM = dot(rgbM, toLuma);
// Gather minimum and maximum luma.
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
// If contrast is lower than a maximum threshold ...
if (lumaMax - lumaMin < lumaMax * lumaThreshold)
{
// ... do no AA and return.
fragColor = vec4(rgbM, 1.0);
return;
}
// Sampling is done along the gradient.
vec2 samplingDirection;
samplingDirection.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
samplingDirection.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
// Sampling step distance depends on the luma: The brighter the sampled texels, the smaller the final sampling step direction.
// This results, that brighter areas are less blurred/more sharper than dark areas.
float samplingDirectionReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * 0.25 * directionReduceMultiplier, directionReduceMinimum);
// Factor for norming the sampling direction plus adding the brightness influence.
float minSamplingDirectionFactor = 1.0 / (min(abs(samplingDirection.x), abs(samplingDirection.y)) + samplingDirectionReduce);
// Calculate final sampling direction vector by reducing, clamping to a range and finally adapting to the texture size.
samplingDirection = clamp(samplingDirection * minSamplingDirectionFactor, vec2(-maxSpan, -maxSpan), vec2(maxSpan, maxSpan)) * u_texelStep;
// Inner samples on the tab.
vec3 rgbSampleNeg = min(vec3(1),texture(tex0, v_texCoord0 + samplingDirection * (1.0/3.0 - 0.5)).rgb);
vec3 rgbSamplePos = min(vec3(1),texture(tex0, v_texCoord0 + samplingDirection * (2.0/3.0 - 0.5)).rgb);
vec3 rgbTwoTab = (rgbSamplePos + rgbSampleNeg) * 0.5;
// Outer samples on the tab.
vec3 rgbSampleNegOuter = min(vec3(1),texture(tex0, v_texCoord0 + samplingDirection * (0.0/3.0 - 0.5)).rgb);
vec3 rgbSamplePosOuter = min(vec3(1),texture(tex0, v_texCoord0 + samplingDirection * (3.0/3.0 - 0.5)).rgb);
vec3 rgbFourTab = (rgbSamplePosOuter + rgbSampleNegOuter) * 0.25 + rgbTwoTab * 0.5;
// Calculate luma for checking against the minimum and maximum value.
float lumaFourTab = dot(rgbFourTab, toLuma);
// Are outer samples of the tab beyond the edge ...
if (lumaFourTab < lumaMin || lumaFourTab > lumaMax)
{
// ... yes, so use only two samples.
fragColor = vec4(rgbTwoTab, 1.0);
// fragColor.r = 1.0;
}
else
{
// ... no, so use four samples.
fragColor = vec4(rgbFourTab, 1.0);
// fragColor.g = 1.0;
}
// Show edges for debug purposes.
if (u_showEdges != 0)
{
fragColor.r = 1.0;
}
//fragColor.rgb = vec3(fragColor.rgb-rgbM)*40.0;
}

View File

@@ -0,0 +1,29 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? a.rgb: a.rgb / a.a;
vec3 nb = b.a == 0.0 ? b.rgb: b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(vec3(0.0), nb.rgb, b.a);
vec4 m = vec4(ka+kb, 1.0) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,39 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
float blendColorBurn(float base, float blend) {
return (blend==0.0)?blend:max((1.0-((1.0-base)/blend)),0.0);
}
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? vec3(0.0): a.rgb / a.a;
vec3 nb = b.a == 0.0 ? b.rgb: b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(vec3(1.0), nb.rgb, b.a);
vec4 m = vec4(
blendColorBurn(ka.r, kb.r),
blendColorBurn(ka.g, kb.g),
blendColorBurn(ka.b, kb.b),
1.0
) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,37 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
float dodge(float base, float blend) {
return (blend==1.0)?blend:min(base/(1.0-blend),1.0);
}
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? vec3(0.0): a.rgb / a.a;
vec3 nb = b.a == 0.0 ? vec3(0.0): b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(vec3(0.0), nb.rgb, b.a);
vec4 m = vec4(
dodge(ka.r, kb.r),
dodge(ka.g, kb.g),
dodge(ka.b, kb.b),
1.0
) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,34 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? vec3(0.0): a.rgb / a.a;
vec3 nb = b.a == 0.0 ? vec3(0.0): b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(na.rgb, nb.rgb, b.a);
vec4 m = vec4(
kb.r <= ka.r? kb.r : ka.r,
kb.g <= ka.g? kb.g : ka.g,
kb.b <= ka.b? kb.b : ka.b,
1.0
) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,15 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
o_color.rgb = a.rgb;
o_color.a = b.a;
}

View File

@@ -0,0 +1,14 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
o_color.rgb = a.rgb;
o_color.a = max(a.a - b.a, 0.0);
}

View File

@@ -0,0 +1,33 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? vec3(0.0): a.rgb / a.a;
vec3 nb = b.a == 0.0 ? vec3(0.0): b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(vec3(0.5), nb.rgb, b.a);
vec4 m = vec4(
kb.r <= 0.5? 2*ka.r * kb.r : 1.0 - 2.0*(1.0 - ka.r)*(1.0 - kb.r),
kb.g <= 0.5? 2*ka.g * kb.g : 1.0 - 2.0*(1.0 - ka.g)*(1.0 - kb.g),
kb.b <= 0.5? 2*ka.b * kb.b : 1.0 - 2.0*(1.0 - ka.b)*(1.0 - kb.b),
1.0
) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,34 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? vec3(0.0): a.rgb / a.a;
vec3 nb = b.a == 0.0 ? vec3(0.0): b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(na.rgb, nb.rgb, b.a);
vec4 m = vec4(
kb.r >= ka.r? kb.r : ka.r,
kb.g >= ka.g? kb.g : ka.g,
kb.b >= ka.b? kb.b : ka.b,
1.0
) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,32 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
//float ai = dot(vec3(1.0), a.rgb)/3.0;
//float bi = dot(vec3(1.0), b.rgb)/3.0;
float ai = max(a.z, max(a.x, a.y));
float bi = max(b.z, max(b.x, b.y));
//vec3 f = bi < 0.5? vec3(0.0) : a.rgb;
// vec3 f = smoothstep(0.5, 0.9, bi) * a.rgb;
vec3 f = a.rgb - (1.0-b.rgb)*2.0*b.a;
o_color.rgb = max(vec3(0.0), f) * (1.0) + b.rgb * (1.0-a.a);;
o_color.a = 1.0; //min(1.0, a.a + b.a);
}

View File

@@ -0,0 +1,30 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? a.rgb: a.rgb / a.a;
vec3 nb = b.a == 0.0 ? b.rgb: b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(1.0), na.rgb, a.a);
vec3 kb = mix(vec3(1.0), nb.rgb, b.a);
vec4 m = vec4(ka*kb, 1.0) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,15 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
float alpha = min(1,max(0, b.a));
o_color = a * (1.0-alpha) + b;
o_color.a = 1.0;
}

View File

@@ -0,0 +1,23 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec4 c = vec4(
a.r <= 0.5? 2.0*a.r * b.r : 1.0 - 2.0*(1.0-a.r)*(1.0-b.r),
a.g <= 0.5? 2.0*a.g * b.g : 1.0 - 2.0*(1.0-a.g)*(1.0-b.g),
a.b <= 0.5? 2.0*a.b * b.b : 1.0 - 2.0*(1.0-a.b)*(1.0-b.b),
1.0
);
vec4 d = a * (1.0 - b.a) + c * b.a;
o_color = max(vec4(0), min(vec4(1), d));
o_color.a = 1.0;
}

View File

@@ -0,0 +1,9 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
out vec4 o_color;
void main() {
o_color = texture(tex0, v_texCoord0);
}

View File

@@ -0,0 +1,33 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? vec3(0.0): a.rgb / a.a;
vec3 nb = b.a == 0.0 ? vec3(0.0): b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(na.rgb, nb.rgb, b.a);
vec4 m = vec4(
1.0-((1.0-ka.r)*(1.0-kb.r)),
1.0-((1.0-ka.g)*(1.0-kb.g)),
1.0-((1.0-ka.b)*(1.0-kb.b)),
1.0
) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,14 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
o_color.rgb = b.rgb;
o_color.a = a.a;
}

View File

@@ -0,0 +1,14 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
o_color.rgb = b.rgb;
o_color.a = max(b.a - a.a, 0.0);
}

View File

@@ -0,0 +1,29 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec3 na = a.a == 0.0 ? a.rgb: a.rgb / a.a;
vec3 nb = b.a == 0.0 ? b.rgb: b.rgb / b.a;
float minAlpha = min(a.a, b.a);
float maxAlpha = max(a.a, b.a);
vec3 ka = mix(vec3(0.0), na.rgb, a.a);
vec3 kb = mix(vec3(0.0), nb.rgb, b.a);
vec4 m = vec4(na-kb, 1.0) * maxAlpha;
vec4 l = a;
l = l * (1.0 - b.a) + b;
l = l * (1.0 - m.a) + m;
o_color = l;
o_color.a = maxAlpha;
}

View File

@@ -0,0 +1,22 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 o_color;
void main() {
vec4 a = texture(tex0, v_texCoord0);
vec4 b = texture(tex1, v_texCoord0);
vec4 color = vec4(0.0);
if (a.a > b.a) {
color = a;
}
if (b.a > a.a) {
color = b;
}
o_color = color;
}

View File

@@ -0,0 +1,29 @@
// openrndr - gl3 - approximate-gaussian-blur
#version 330 core
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform vec2 blurDirection;
uniform int window;
uniform float sigma;
uniform float spread;
uniform float gain;
out vec4 o_color;
void main() {
vec2 s = textureSize(tex0, 0).xy;
s = vec2(1.0/s.x, 1.0/s.y);
int w = window;
vec4 sum = vec4(0.0);
float weight = 0;
for (int x = -w; x <= w; ++x) {
float lw = exp( -(x*x) / (2 * sigma * sigma) ) ;
vec2 tc = v_texCoord0 + x * blurDirection * s;// * spread;
sum += texture(tex0, tc) * lw;
weight += lw;
}
o_color = (sum / weight) * gain;
}

View File

@@ -0,0 +1,31 @@
// openrndr - gl3 - box-blur
#version 330 core
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform vec2 blurDirection;
uniform int window;
uniform float sigma;
uniform float gain;
uniform vec4 subtract;
uniform float spread;
out vec4 o_color;
void main() {
vec2 s = textureSize(tex0, 0).xy;
s = vec2(1.0/s.x, 1.0/s.y);
int w = window;
vec4 sum = vec4(0, 0, 0, 0);
float weight = 0;
for (int x = -w; x<= w; ++x) {
float lw = 1.0;
sum += texture(tex0, v_texCoord0 + x * blurDirection * s * spread);
weight += lw;
}
o_color = (sum / weight) * gain;
// o_color.a = 1.0;
}

View File

@@ -0,0 +1,31 @@
#version 330 core
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform int window;
uniform float sigma;
uniform float spread;
uniform float gain;
out vec4 o_color;
void main() {
vec2 s = textureSize(tex0, 0).xy;
s = vec2(1.0/s.x, 1.0/s.y);
int w = window;
vec4 sum = vec4(0,0,0,0);
float weight = 0;
for (int y = -w; y<= w; ++y) {
for (int x = -w; x<= w; ++x) {
float lw = exp(-(x*x+y*y) / (2 * sigma * sigma));
sum+=texture(tex0, v_texCoord0 + vec2(x,y) * s * spread) * lw;
weight+=lw;
}
}
o_color = (sum / weight) * gain;
}

View File

@@ -0,0 +1,49 @@
#version 330 core
// based on Hashed blur by David Hoskins.
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
uniform float radius;
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform float time;
uniform int samples;
uniform float gain;
out vec4 o_color;
#define TAU 6.28318530718
//-------------------------------------------------------------------------------------------
#define HASHSCALE 443.8975
vec2 hash22(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * HASHSCALE);
p3 += dot(p3, p3.yzx+19.19);
return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
}
vec2 sampleTexture(inout vec2 r) {
r = fract(r * vec2(33.3983, 43.4427));
//return r-.5;
return sqrt(r.x+.001) * vec2(sin(r.y * TAU), cos(r.y * TAU))*.5; // <<=== circular sampling.
}
//-------------------------------------------------------------------------------------------
vec4 blur(vec2 uv, float radius) {
vec2 circle = vec2(radius) * (vec2(1.0) / textureSize(tex0, 0));
vec2 random = hash22(uv + vec2(time));
vec4 acc = vec4(0.0);
for (int i = 0; i < samples; i++) {
acc += texture(tex0, uv + circle * sampleTexture(random));
}
return acc / float(samples);
}
//-------------------------------------------------------------------------------------------
void main() {
vec2 uv = v_texCoord0;
float radiusSqr = pow(radius, 2.0);
o_color = blur(uv, radiusSqr);
o_color.rgb *= gain;
}

View File

@@ -0,0 +1,25 @@
#version 330
out vec4 o_color;
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform int iteration;
uniform float spread;
void main() {
ivec2 size = textureSize(tex0, 0);
vec2 pixelSize = vec2(1.0/size.x, 1.0/size.y);
vec2 halfPixelSize = pixelSize / 2.0f;
vec2 d = (pixelSize.xy * vec2(iteration, iteration)) + halfPixelSize.xy;
d *= spread;
vec4 dec = vec4(2.2);
vec4 enc = vec4(1.0/2.2);
vec4 cOut = pow(texture(tex0, v_texCoord0+ vec2(-1, 1)*d), dec);
cOut += pow(texture(tex0, v_texCoord0 + vec2(1, 1)*d), dec);
cOut += pow(texture(tex0, v_texCoord0 + vec2(1, -1)*d), dec);
cOut += pow(texture(tex0, v_texCoord0+ vec2(-1, -1)*d), dec);
o_color = pow(cOut/4.0, enc);
}

View File

@@ -0,0 +1,41 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform sampler2D lookup;
uniform float seed;
uniform float noiseGain;
out vec4 o_color;
#define HASHSCALE 443.8975
vec2 hash22(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * HASHSCALE);
p3 += dot(p3, p3.yzx+19.19);
return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
}
// -- from https://github.com/jeromeetienne/threex.coloradjust/blob/master/threex.coloradjust.js
vec4 sampleAs3DTexture(sampler2D lut, vec3 uv, float width) {
float sliceSize = 1.0 / width; // space of 1 slice
float slicePixelSize = sliceSize / width; // space of 1 pixel
float sliceInnerSize = slicePixelSize * (width - 1.0); // space of width pixels
float zSlice0 = min(floor(uv.z * width), width - 1.0);
float zSlice1 = min(zSlice0 + 1.0, width - 1.0);
float xOffset = slicePixelSize * 0.5 + uv.x * sliceInnerSize;
float s0 = xOffset + (zSlice0 * sliceSize);
float s1 = xOffset + (zSlice1 * sliceSize);
vec4 slice0Color = texture(lut, vec2(s0, 1.0-uv.y));
vec4 slice1Color = texture(lut, vec2(s1, 1.0-uv.y));
float zOffset = mod(uv.z * width, 1.0);
vec4 result = mix(slice0Color, slice1Color, zOffset);
return result;
}
void main() {
vec4 color = texture(tex0, v_texCoord0);
vec3 noise = vec3(hash22(v_texCoord0-vec2(seed)), hash22(-v_texCoord0+vec2(seed)).x);
vec3 graded = sampleAs3DTexture(lookup, min(vec3(1.0), max(vec3(0.0),color.rgb + noise * noiseGain)), 16.0).rgb;
o_color.rgb = min(vec3(1.0), max(vec3(0.0), graded));
o_color.a = color.a;
}

View File

@@ -0,0 +1,20 @@
#version 330
uniform float[25] colorMatrix;
vec4 colorTransform(vec4 color, float[25] matrix) {
float r = color.r * matrix[0] + color.g * matrix[5] + color.b * matrix[10] + color.a * matrix[15] + matrix[20];
float g = color.r * matrix[1] + color.g * matrix[6] + color.b * matrix[11] + color.a * matrix[16] + matrix[21];
float b = color.r * matrix[2] + color.g * matrix[7] + color.b * matrix[12] + color.a * matrix[17] + matrix[22];
float a = color.r * matrix[3] + color.g * matrix[8] + color.b * matrix[13] + color.a * matrix[18] + matrix[23];
return vec4(r, g, b, a);
}
in vec2 v_texCoord0;
uniform sampler2D tex0;
out vec4 o_color;
void main() {
vec4 c = texture(tex0, v_texCoord0);
o_color = colorTransform(c, colorMatrix);
}

View File

@@ -0,0 +1,11 @@
#version 330
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform vec4 constant;
out vec4 o_color;
void main() {
vec4 c = texture(tex0, v_texCoord0);
o_color = max(vec4(0.0), c - constant);
}

View File

@@ -0,0 +1,55 @@
#version 330
// this shader is based on the "a dither" work by Øyvind Kolås
// https://pippin.gimp.org/a_dither/
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform int pattern;
uniform int levels;
float mask1(int levels, float l, int x, int y, int c) {
float mask = ((x ^ y * 149) * 1234& 511)/511.0;
return floor(levels * l + mask)/levels;
}
float mask2(int levels, float l, int x, int y, int c) {
float mask = (((x+c*17) ^ y * 149) * 1234 & 511)/511.0;
return floor(levels * l + mask)/levels;
}
float mask3(int levels, float l, int x, int y, int c) {
float mask = ((x + y * 237) * 119 & 255)/255.0;
return floor(levels * l + mask)/levels;
}
float mask4(int levels, float l, int x, int y, int c) {
float mask = (((x+c*67) + y * 236) * 119 & 255)/255.0;
return floor(levels * l + mask)/levels;
}
out vec4 o_color;
void main() {
vec4 c = texture(tex0, v_texCoord0);
ivec2 ic = ivec2(v_texCoord0 * textureSize(tex0, 0));
vec3 rgb = vec3(1.0, 0.0, 1.0);
if (pattern == 0) {
rgb = vec3(mask1(levels, c.r, ic.x, ic.y, 0), mask1(levels, c.g, ic.x, ic.y, 1), mask1(levels, c.b, ic.x, ic.y, 2));
} else if (pattern == 1) {
rgb = vec3(mask2(levels, c.r, ic.x, ic.y, 0), mask2(levels, c.g, ic.x, ic.y, 1), mask2(levels, c.b, ic.x, ic.y, 2));
} else if (pattern == 2) {
rgb = vec3(mask3(levels, c.r, ic.x, ic.y, 0), mask3(levels, c.g, ic.x, ic.y, 1), mask3(levels, c.b, ic.x, ic.y, 2));
} else {
rgb = vec3(mask4(levels, c.r, ic.x, ic.y, 0), mask4(levels, c.g, ic.x, ic.y, 1), mask4(levels, c.b, ic.x, ic.y, 2));
}
o_color.rgb = rgb;
o_color.a = 1.0;
}

View File

@@ -0,0 +1,12 @@
#version 330 core
in vec2 v_texCoord0;
uniform sampler2D tex0;
uniform vec4 constant;
out vec4 o_color;
void main() {
vec2 uv = v_texCoord0;
uv.y = 1.0 - uv.y;
o_color = texture(tex0, uv);
}

View File

@@ -5,6 +5,7 @@ include 'orx-camera',
'orx-easing',
'orx-file-watcher',
'orx-filter-extension',
'orx-fx',
'orx-gradient-descent',
'orx-integral-image',
'orx-interval-tree',