[orx-fx] Add Duotone, DuotoneGradient, LumaHalftone, Posterize, RgbToOkLab, OkLabToRgb
This commit is contained in:
@@ -63,12 +63,19 @@ Most blur effects are opacity preserving
|
||||
- `ColorCorrection`, corrections for brightness, contrast, saturation and hue
|
||||
- `ColorLookup`, Color LUT filter
|
||||
- `ColorMix`, filter implementation of OPENRNDR's color matrix mixing
|
||||
- `Duotone`, maps luminosity to two colors, very similar to `LumaMap` but uses LAB color interpolation.
|
||||
- `DuotoneGradient`, a two-point gradient version of `Duotone`
|
||||
- `LumaMap`, maps luminosity to two colors
|
||||
- `LumaOpacity`, maps luminosity to opacity but retains source color
|
||||
- `LumaThreshold`, applies a treshold on the input luminosity and maps to two colors
|
||||
- `Posterize`, a posterize effect
|
||||
- `Sepia`, applies a reddish-brown monochrome tint that imitates an old photograph
|
||||
- `SubtractConstant`, subtract a constant color from the source color
|
||||
|
||||
### Color conversion
|
||||
- `OkLabToRgb`
|
||||
- `RgbToOkLab`
|
||||
|
||||
### Distortion
|
||||
|
||||
All distortion effects are opacity preserving
|
||||
@@ -82,7 +89,8 @@ All distortion effects are opacity preserving
|
||||
### Dither
|
||||
- `ADither` - a selection of dithering effects
|
||||
- `CMYKHalftone` - a configurable CMYK halftoning effect
|
||||
|
||||
- `Crosshatch` - crosshatching effect
|
||||
- `LumaHalftone` - a halftoning effect based on luminosity
|
||||
### Edges
|
||||
- `LumaSobel` - A Sobel-kernel based luminosity edge detector
|
||||
- `EdgesWork` - An edges filter doubling as erosion
|
||||
|
||||
@@ -33,6 +33,7 @@ kotlin {
|
||||
defaultSourceSet {
|
||||
kotlin.srcDir("src/demo")
|
||||
dependencies {
|
||||
implementation(project(":orx-color"))
|
||||
implementation(project(":orx-camera"))
|
||||
implementation("org.openrndr:openrndr-application:$openrndrVersion")
|
||||
implementation("org.openrndr:openrndr-extensions:$openrndrVersion")
|
||||
@@ -66,6 +67,8 @@ kotlin {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(project(":orx-parameters"))
|
||||
implementation(project(":orx-shader-phrases"))
|
||||
implementation(project(":orx-color"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinxSerializationVersion")
|
||||
implementation("org.openrndr:openrndr-application:$openrndrVersion")
|
||||
implementation("org.openrndr:openrndr-draw:$openrndrVersion")
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
package org.openrndr.extra.fx.color
|
||||
|
||||
import org.openrndr.draw.Filter
|
||||
import org.openrndr.extra.fx.*
|
||||
import org.openrndr.extra.fx.fx_rgb_to_oklab
|
||||
import org.openrndr.extra.fx.fx_rgb_to_ycbcr
|
||||
import org.openrndr.extra.fx.fx_ycbcr_to_rgb
|
||||
import org.openrndr.extra.fx.mppFilterShader
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.extras.color.phrases.ColorPhraseBook
|
||||
|
||||
class RgbToYCbcr : Filter(mppFilterShader(fx_rgb_to_ycbcr, "rgb-to-ycbcr"))
|
||||
class YcbcrToRgb : Filter(mppFilterShader(fx_ycbcr_to_rgb, "ycbcr_to_rgb"))
|
||||
class YcbcrToRgb : Filter(mppFilterShader(fx_ycbcr_to_rgb, "ycbcr_to_rgb"))
|
||||
|
||||
class RgbToOkLab : Filter(mppFilterShader(run {
|
||||
ColorPhraseBook.register()
|
||||
fx_rgb_to_oklab.preprocess()
|
||||
}, "rgb-to-oklab"))
|
||||
|
||||
class OkLabToRgb : Filter(mppFilterShader(run {
|
||||
ColorPhraseBook.register()
|
||||
fx_oklab_to_rgb.preprocess()
|
||||
}, "oklab-to-rgb"))
|
||||
|
||||
37
orx-fx/src/commonMain/kotlin/color/Duotone.kt
Normal file
37
orx-fx/src/commonMain/kotlin/color/Duotone.kt
Normal file
@@ -0,0 +1,37 @@
|
||||
package org.openrndr.extra.fx.color
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.Filter
|
||||
import org.openrndr.draw.filterShaderFromCode
|
||||
import org.openrndr.extra.fx.fx_duotone
|
||||
import org.openrndr.extra.parameters.BooleanParameter
|
||||
|
||||
import org.openrndr.extra.parameters.ColorParameter
|
||||
import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.extras.color.phrases.ColorPhraseBook
|
||||
import org.openrndr.extras.color.presets.CORAL
|
||||
import org.openrndr.extras.color.presets.DARK_GRAY
|
||||
import org.openrndr.extras.color.presets.NAVY
|
||||
|
||||
@Description("Duotone")
|
||||
class Duotone : Filter(filterShaderFromCode(run {
|
||||
ColorPhraseBook.register()
|
||||
fx_duotone.preprocess()
|
||||
}, "duotone")) {
|
||||
|
||||
@ColorParameter("background", order = 0)
|
||||
var backgroundColor: ColorRGBa by parameters
|
||||
|
||||
@ColorParameter("foreground", order = 1)
|
||||
var foregroundColor: ColorRGBa by parameters
|
||||
|
||||
@BooleanParameter("LAB interpolation", order = 2)
|
||||
var labInterpolation: Boolean by parameters
|
||||
|
||||
init {
|
||||
backgroundColor = ColorRGBa.NAVY
|
||||
foregroundColor = ColorRGBa.CORAL
|
||||
labInterpolation = true
|
||||
}
|
||||
}
|
||||
49
orx-fx/src/commonMain/kotlin/color/DuotoneGradient.kt
Normal file
49
orx-fx/src/commonMain/kotlin/color/DuotoneGradient.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.openrndr.extra.fx.color
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.Filter
|
||||
import org.openrndr.draw.filterShaderFromCode
|
||||
import org.openrndr.extra.fx.fx_duotone_gradient
|
||||
import org.openrndr.extra.parameters.BooleanParameter
|
||||
|
||||
import org.openrndr.extra.parameters.ColorParameter
|
||||
import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.DoubleParameter
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.extras.color.phrases.ColorPhraseBook
|
||||
import org.openrndr.extras.color.presets.CORAL
|
||||
import org.openrndr.extras.color.presets.NAVY
|
||||
|
||||
@Description("Duotone Gradient")
|
||||
class DuotoneGradient : Filter(filterShaderFromCode(run {
|
||||
ColorPhraseBook.register()
|
||||
fx_duotone_gradient.preprocess()
|
||||
}, "duotone-gradient")) {
|
||||
|
||||
@ColorParameter("background 0", order = 0)
|
||||
var backgroundColor0: ColorRGBa by parameters
|
||||
|
||||
@ColorParameter("foreground 0", order = 1)
|
||||
var foregroundColor0: ColorRGBa by parameters
|
||||
|
||||
@ColorParameter("background 1", order = 2)
|
||||
var backgroundColor1: ColorRGBa by parameters
|
||||
|
||||
@ColorParameter("foreground 1", order = 3)
|
||||
var foregroundColor1: ColorRGBa by parameters
|
||||
|
||||
@BooleanParameter("LAB interpolation", order = 4)
|
||||
var labInterpolation: Boolean by parameters
|
||||
|
||||
@DoubleParameter("rotation", -180.0, 180.0, order = 5)
|
||||
var rotation: Double by parameters
|
||||
|
||||
init {
|
||||
backgroundColor0 = ColorRGBa.NAVY
|
||||
foregroundColor0 = ColorRGBa.CORAL
|
||||
backgroundColor1 = ColorRGBa.BLACK
|
||||
foregroundColor1 = ColorRGBa.WHITE
|
||||
rotation = 0.0
|
||||
labInterpolation = true
|
||||
}
|
||||
}
|
||||
32
orx-fx/src/commonMain/kotlin/color/Posterize.kt
Normal file
32
orx-fx/src/commonMain/kotlin/color/Posterize.kt
Normal file
@@ -0,0 +1,32 @@
|
||||
package org.openrndr.extra.fx.color
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.Filter
|
||||
import org.openrndr.draw.filterShaderFromCode
|
||||
import org.openrndr.extra.fx.fx_duotone
|
||||
import org.openrndr.extra.fx.fx_posterize
|
||||
import org.openrndr.extra.parameters.BooleanParameter
|
||||
|
||||
import org.openrndr.extra.parameters.ColorParameter
|
||||
import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.IntParameter
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.extras.color.phrases.ColorPhraseBook
|
||||
import org.openrndr.extras.color.presets.CORAL
|
||||
import org.openrndr.extras.color.presets.DARK_GRAY
|
||||
import org.openrndr.extras.color.presets.NAVY
|
||||
|
||||
@Description("Posterize")
|
||||
class Posterize : Filter(filterShaderFromCode(fx_posterize, "posterize")) {
|
||||
|
||||
@IntParameter("levels", 2, 32, order = 0)
|
||||
var levels: Int by parameters
|
||||
|
||||
@IntParameter("window", 1, 8, order = 0)
|
||||
var window: Int by parameters
|
||||
|
||||
init {
|
||||
levels = 4
|
||||
window = 1
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,8 @@ class Lenses : Filter(mppFilterShader(fx_lenses, "block-repeat")) {
|
||||
rows = 6
|
||||
columns = 8
|
||||
distort = 0.0
|
||||
|
||||
scale = 1.0
|
||||
rotation = 0.0
|
||||
bicubicFiltering = true
|
||||
}
|
||||
}
|
||||
|
||||
53
orx-fx/src/commonMain/kotlin/dither/LumaHalftone.kt
Normal file
53
orx-fx/src/commonMain/kotlin/dither/LumaHalftone.kt
Normal file
@@ -0,0 +1,53 @@
|
||||
package org.openrndr.extra.fx.dither
|
||||
|
||||
import org.openrndr.draw.Filter
|
||||
import org.openrndr.draw.filterShaderFromCode
|
||||
import org.openrndr.extra.fx.fx_luma_halftone
|
||||
import org.openrndr.extra.parameters.BooleanParameter
|
||||
import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.DoubleParameter
|
||||
|
||||
|
||||
@Description("Luma Halftone")
|
||||
class LumaHalftone: Filter(filterShaderFromCode(fx_luma_halftone, "luma-halftone")) {
|
||||
@DoubleParameter("scale", 1.0, 30.0, precision = 4)
|
||||
var scale: Double by parameters
|
||||
|
||||
@DoubleParameter("threshold", 0.0, 1.0, precision = 4)
|
||||
var threshold: Double by parameters
|
||||
|
||||
@DoubleParameter("rotation", -180.0, 180.0)
|
||||
var rotation: Double by parameters
|
||||
|
||||
@DoubleParameter("freq0", 1.0, 400.0)
|
||||
var freq0: Double by parameters
|
||||
|
||||
@DoubleParameter("freq1", 1.0, 400.0)
|
||||
var freq1: Double by parameters
|
||||
|
||||
@DoubleParameter("gain1", -2.0, 2.0)
|
||||
var gain1: Double by parameters
|
||||
|
||||
@DoubleParameter("phase0", -1.0, 1.0)
|
||||
var phase0: Double by parameters
|
||||
|
||||
@DoubleParameter("phase1", -1.0, 1.0)
|
||||
var phase1: Double by parameters
|
||||
|
||||
|
||||
@BooleanParameter("invert")
|
||||
var invert: Boolean by parameters
|
||||
|
||||
|
||||
init {
|
||||
scale = 3.0
|
||||
rotation = 0.0
|
||||
threshold = 0.5
|
||||
freq1 = 20.0
|
||||
freq0 = 10.0
|
||||
gain1 = 0.1
|
||||
phase0 = 0.0
|
||||
phase1 = 0.0
|
||||
invert = true
|
||||
}
|
||||
}
|
||||
26
orx-fx/src/demo/kotlin/DemoColorDuotone01.kt
Normal file
26
orx-fx/src/demo/kotlin/DemoColorDuotone01.kt
Normal file
@@ -0,0 +1,26 @@
|
||||
import org.openrndr.extra.fx.color.Duotone
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.math.mod_
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val duotone = Duotone()
|
||||
|
||||
extend {
|
||||
|
||||
duotone.labInterpolation = seconds.mod_(2.0) < 1.0
|
||||
duotone.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
orx-fx/src/demo/kotlin/DemoColorDuotoneGradient01.kt
Normal file
25
orx-fx/src/demo/kotlin/DemoColorDuotoneGradient01.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.color.DuotoneGradient
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val duotone = DuotoneGradient()
|
||||
duotone.labInterpolation = false
|
||||
|
||||
extend {
|
||||
duotone.labInterpolation = true
|
||||
duotone.backgroundColor0 = ColorRGBa.BLACK
|
||||
duotone.foregroundColor0 = ColorRGBa.RED
|
||||
duotone.backgroundColor1 = ColorRGBa.BLUE
|
||||
duotone.foregroundColor1 = ColorRGBa.WHITE
|
||||
duotone.rotation = seconds * 45.0
|
||||
duotone.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
25
orx-fx/src/demo/kotlin/DemoColorPosterize01.kt
Normal file
25
orx-fx/src/demo/kotlin/DemoColorPosterize01.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
import org.openrndr.extra.fx.color.Duotone
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.color.Posterize
|
||||
import org.openrndr.math.mod_
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val posterize = Posterize()
|
||||
|
||||
extend {
|
||||
posterize.levels = 2
|
||||
posterize.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
26
orx-fx/src/demo/kotlin/DemoDitherLumaHalftone01.kt
Normal file
26
orx-fx/src/demo/kotlin/DemoDitherLumaHalftone01.kt
Normal file
@@ -0,0 +1,26 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.dither.LumaHalftone
|
||||
import org.openrndr.math.mod_
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val lumaHalftone = LumaHalftone()
|
||||
extend {
|
||||
lumaHalftone.rotation = -15.0
|
||||
lumaHalftone.freq0 = 100.0
|
||||
lumaHalftone.gain1 = 1.0
|
||||
lumaHalftone.threshold = 0.5
|
||||
lumaHalftone.phase0 = seconds*0.1
|
||||
lumaHalftone.phase1 = -seconds*0.1
|
||||
lumaHalftone.apply(image, filteredImage)
|
||||
lumaHalftone.invert = seconds.mod_(2.0) < 1.0
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
orx-fx/src/demo/kotlin/DemoOkLab01.kt
Normal file
27
orx-fx/src/demo/kotlin/DemoOkLab01.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
import org.openrndr.extra.fx.color.RgbToOkLab
|
||||
import org.openrndr.extra.fx.color.OkLabToRgb
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.ColorType
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
|
||||
/**
|
||||
* This demonstrates converting a [ColorBuffer] from and to (OK)LAB color space using the [RgbToOkLab] and [OkLabToRgb]
|
||||
* filters. The (OK)Lab representation is signed and requires a floating point representation.
|
||||
*/
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val rgbToOkLab = RgbToOkLab()
|
||||
val okLabToRgb = OkLabToRgb()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val labImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
rgbToOkLab.apply(image, labImage)
|
||||
okLabToRgb.apply(labImage, image)
|
||||
extend {
|
||||
drawer.image(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
orx-fx/src/shaders/glsl/color/duotone-gradient.frag
Normal file
64
orx-fx/src/shaders/glsl/color/duotone-gradient.frag
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma import color.oklab_to_linear_rgb
|
||||
#pragma import color.linear_rgb_to_oklab
|
||||
#pragma import color.linear_rgb_to_srgb
|
||||
#pragma import color.srgb_to_linear_rgb
|
||||
|
||||
uniform vec4 tint;
|
||||
in vec2 v_texCoord0;
|
||||
uniform sampler2D tex0;
|
||||
uniform vec4 backgroundColor0;
|
||||
uniform vec4 foregroundColor0;
|
||||
|
||||
uniform vec4 backgroundColor1;
|
||||
uniform vec4 foregroundColor1;
|
||||
|
||||
uniform bool labInterpolation;
|
||||
uniform float rotation;
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
vec4 c = texture(tex0, v_texCoord0);
|
||||
if (c.a != 0.0) {
|
||||
c.rgb /= c.a;
|
||||
}
|
||||
float ca = cos(radians(rotation));
|
||||
float sa = sin(radians(rotation));
|
||||
mat2 rm = mat2(vec2(ca, sa), vec2(-sa, ca));
|
||||
|
||||
float f = (rm * (v_texCoord0 - vec2(0.5)) + vec2(0.5)).x;
|
||||
|
||||
vec4 bg0 = backgroundColor0;
|
||||
bg0.rgb *= backgroundColor0.a;
|
||||
vec4 fg0 = foregroundColor0;
|
||||
fg0.rgb *= foregroundColor0.a;
|
||||
|
||||
vec4 bg1 = backgroundColor1;
|
||||
bg1.rgb *= backgroundColor1.a;
|
||||
vec4 fg1 = foregroundColor1;
|
||||
fg1.rgb *= foregroundColor1.a;
|
||||
|
||||
|
||||
if (!labInterpolation) {
|
||||
vec4 bg = mix(bg0, bg1, f);
|
||||
vec4 fg = mix(fg0, fg1, f);
|
||||
|
||||
o_color = mix(bg, fg, c.r) * c.a;
|
||||
} else {
|
||||
bg0 = srgb_to_linear_rgb(bg0);
|
||||
bg0 = linear_rgb_to_oklab(bg0);
|
||||
fg0 = srgb_to_linear_rgb(fg0);
|
||||
fg0 = linear_rgb_to_oklab(fg0);
|
||||
bg1 = srgb_to_linear_rgb(bg1);
|
||||
bg1 = linear_rgb_to_oklab(bg1);
|
||||
fg1 = srgb_to_linear_rgb(fg1);
|
||||
fg1 = linear_rgb_to_oklab(fg1);
|
||||
|
||||
vec4 bg = mix(bg0, bg1, f);
|
||||
vec4 fg = mix(fg0, fg1, f);
|
||||
|
||||
vec4 m = mix(bg, fg, c.r);
|
||||
m = oklab_to_linear_rgb(m);
|
||||
m *= c.a;
|
||||
m = linear_rgb_to_srgb(m);
|
||||
o_color = m;
|
||||
}
|
||||
}
|
||||
38
orx-fx/src/shaders/glsl/color/duotone.frag
Normal file
38
orx-fx/src/shaders/glsl/color/duotone.frag
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma import color.oklab_to_linear_rgb
|
||||
#pragma import color.linear_rgb_to_oklab
|
||||
#pragma import color.linear_rgb_to_srgb
|
||||
#pragma import color.srgb_to_linear_rgb
|
||||
|
||||
uniform vec4 tint;
|
||||
in vec2 v_texCoord0;
|
||||
uniform sampler2D tex0;
|
||||
uniform vec4 backgroundColor;
|
||||
uniform vec4 foregroundColor;
|
||||
uniform bool labInterpolation;
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
vec4 c = texture(tex0, v_texCoord0);
|
||||
if (c.a != 0.0) {
|
||||
c.rgb /= c.a;
|
||||
}
|
||||
|
||||
vec4 bg = backgroundColor;
|
||||
bg.rgb *= backgroundColor.a;
|
||||
vec4 fg = foregroundColor;
|
||||
fg.rgb *= foregroundColor.a;
|
||||
|
||||
if (!labInterpolation) {
|
||||
o_color = mix(bg, fg, c.r) * c.a;
|
||||
} else {
|
||||
bg = srgb_to_linear_rgb(bg);
|
||||
bg = linear_rgb_to_oklab(bg);
|
||||
fg = srgb_to_linear_rgb(fg);
|
||||
fg = linear_rgb_to_oklab(fg);
|
||||
|
||||
vec4 m = mix(bg, fg, c.r);
|
||||
m = oklab_to_linear_rgb(m);
|
||||
m *= c.a;
|
||||
m = linear_rgb_to_srgb(m);
|
||||
o_color = m;
|
||||
}
|
||||
}
|
||||
12
orx-fx/src/shaders/glsl/color/oklab-to-rgb.frag
Normal file
12
orx-fx/src/shaders/glsl/color/oklab-to-rgb.frag
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma import color.oklab_to_linear_rgb
|
||||
#pragma import color.linear_rgb_to_srgb
|
||||
out vec4 o_output;
|
||||
|
||||
in vec2 v_texCoord0;
|
||||
uniform sampler2D tex0;
|
||||
|
||||
void main() {
|
||||
vec4 lab = texture(tex0, v_texCoord0);
|
||||
vec4 rgba = oklab_to_linear_rgb(lab);
|
||||
o_output = linear_rgb_to_srgb(rgba);
|
||||
}
|
||||
26
orx-fx/src/shaders/glsl/color/posterize.frag
Normal file
26
orx-fx/src/shaders/glsl/color/posterize.frag
Normal file
@@ -0,0 +1,26 @@
|
||||
in vec2 v_texCoord0;
|
||||
uniform int window;
|
||||
uniform sampler2D tex0;
|
||||
uniform int levels;
|
||||
out vec4 o_output;
|
||||
void main() {
|
||||
vec4 c = texture(tex0, v_texCoord0);
|
||||
vec2 step = 1.0 / textureSize(tex0, 0);
|
||||
float w = 0.0;
|
||||
vec3 s = vec3(0.0);
|
||||
for (int v = -window; v <= window; ++v) {
|
||||
for (int u = -window; u <= window; ++u) {
|
||||
vec4 c = texture(tex0, v_texCoord0 + (step/(2*window)) * vec2(u,v) );
|
||||
if (c.a != 0.0) {
|
||||
c.rgb /= c.a;
|
||||
}
|
||||
vec3 q = min(floor(c.rgb * (levels))/(levels-1), vec3(1.0));
|
||||
s += q;
|
||||
w += 1.0;
|
||||
}
|
||||
}
|
||||
vec3 q = s / w;
|
||||
|
||||
|
||||
o_output = vec4(q*c.a, c.a);
|
||||
}
|
||||
12
orx-fx/src/shaders/glsl/color/rgb-to-oklab.frag
Normal file
12
orx-fx/src/shaders/glsl/color/rgb-to-oklab.frag
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma import color.linear_rgb_to_oklab
|
||||
#pragma import color.srgb_to_linear_rgb
|
||||
out vec4 o_output;
|
||||
|
||||
in vec2 v_texCoord0;
|
||||
uniform sampler2D tex0;
|
||||
|
||||
void main() {
|
||||
vec4 srgba = texture(tex0, v_texCoord0);
|
||||
vec4 rgba = srgb_to_linear_rgb(srgba);
|
||||
o_output = linear_rgb_to_oklab(rgba);
|
||||
}
|
||||
@@ -128,10 +128,8 @@ float snoise(vec3 v)
|
||||
}
|
||||
|
||||
vec3 segment(vec3 t, int x, int y) {
|
||||
|
||||
float sx = x == 0? t.x : floor(t.x * x) / x;
|
||||
float sy = y == 0? t.y : floor(t.y * y) / y;
|
||||
|
||||
return vec3(sx,sy, t.z);
|
||||
}
|
||||
|
||||
|
||||
62
orx-fx/src/shaders/glsl/dither/luma-halftone.frag
Normal file
62
orx-fx/src/shaders/glsl/dither/luma-halftone.frag
Normal file
@@ -0,0 +1,62 @@
|
||||
uniform float scale;
|
||||
uniform float rotation;
|
||||
in vec2 v_texCoord0;
|
||||
uniform sampler2D tex0;
|
||||
out vec4 o_color;
|
||||
uniform float threshold;
|
||||
|
||||
uniform float freq0;
|
||||
uniform float freq1;
|
||||
uniform float gain1;
|
||||
uniform float phase0;
|
||||
uniform float phase1;
|
||||
uniform bool invert;
|
||||
|
||||
float cosine_sample(vec2 uv){
|
||||
float ca = cos(radians(rotation));
|
||||
float sa = sin(radians(rotation));
|
||||
|
||||
vec2 ts = textureSize(tex0, 0);
|
||||
mat2 rm = mat2(1.0, 0.0, 0.0, ts.x/ts.y) * mat2(vec2(ca, sa), vec2(-sa, ca)) * mat2(1.0, 0.0, 0.0, ts.y/ts.x);
|
||||
|
||||
vec2 cuv = (rm * (uv - vec2(0.5))) + vec2(0.5);
|
||||
|
||||
float m = fract(phase0 + cuv.x*freq0 + cos(cuv.y*freq1+phase1*3.141592653)*gain1);
|
||||
vec4 c = texture(tex0, v_texCoord0);
|
||||
if (c.a != 0.0) {
|
||||
c.rgb /= c.a;
|
||||
}
|
||||
float l = dot(vec3(1.0/3.0), c.rgb);
|
||||
if (invert) {
|
||||
l = 1 - l;
|
||||
}
|
||||
|
||||
float t = 0.0;
|
||||
t = step(threshold, l * m);
|
||||
return t;
|
||||
}
|
||||
|
||||
float cosine_halftone(vec2 uv) {
|
||||
int w = 3;
|
||||
vec2 step = 1.0 / textureSize(tex0, 0);
|
||||
step /= (2*w);
|
||||
float weight = 0.0;
|
||||
float sum = 0.0;
|
||||
for (int v = -w; v <= w; ++v) {
|
||||
for (int u = -w; u <= w; ++u) {
|
||||
sum += cosine_sample(uv + step * vec2(u, v));
|
||||
weight+=1;
|
||||
}
|
||||
}
|
||||
return sum / weight;
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 c = texture(tex0, v_texCoord0);
|
||||
float t = cosine_halftone(v_texCoord0);
|
||||
if (invert) {
|
||||
t = 1 - t;
|
||||
}
|
||||
o_color = vec4(t, t, t, 1.0) * c.a;
|
||||
}
|
||||
Reference in New Issue
Block a user