[orx-fx] Add comments to demos

This commit is contained in:
Abe Pazos
2025-09-23 19:20:42 +02:00
parent 857f3458e3
commit fd022e9d0e
16 changed files with 203 additions and 70 deletions

View File

@@ -4,6 +4,14 @@ import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.blur.ApproximateGaussianBlur
import org.openrndr.extra.imageFit.imageFit
/**
* Demonstrates how to use the [ApproximateGaussianBlur] effect to blur
* a `colorBuffer`, in this case, an image loaded from disk.
*
* Notice the use of `createEquivalent()`, which creates a new `colorBuffer`
* with the same size and properties as a source `colorBuffer`.
*
*/
fun main() = application {
configure {
width = 720

View File

@@ -5,6 +5,14 @@ import org.openrndr.extra.fx.blur.*
import org.openrndr.math.Polar
import kotlin.math.sin
/**
* Demonstrates 9 different blur effects.
* The program draws two moving circles into a [RenderTarget],
* then applies various blurs drawing them in 3 columns and 3 rows.
*
* Each type of blur has different parameters.
* Not all parameters are demonstrated.
*/
fun main() = application {
program {
// In this buffer we will draw some simple shapes
@@ -21,7 +29,8 @@ fun main() = application {
GaussianBloom(),
FrameBlur(),
ZoomBlur(),
LaserBlur()
LaserBlur(),
LineBlur()
)
// On this buffer we will draw the dry buffer with an effect applied
@@ -32,15 +41,17 @@ fun main() = application {
extend {
// Draw two moving circles
drawer.isolatedWithTarget(dry) {
ortho(dry)
clear(ColorRGBa.BLACK)
fill = null
stroke = ColorRGBa.PINK
strokeWeight = 25.0
strokeWeight = 20.0
circle(
bounds.center +
Polar(seconds * 50.0, 100.0).cartesian,
200.0 + 50.0 * sin(seconds * 2.0)
100.0 + 50.0 * sin(seconds * 2.0)
)
fill = ColorRGBa.PINK
@@ -48,7 +59,7 @@ fun main() = application {
circle(
bounds.center +
Polar(seconds * 50.0 + 60, 100.0).cartesian,
100.0 + 20.0 * sin(seconds * 2.0 + 1)
70.0 + 20.0 * sin(seconds * 2.0 + 1)
)
}
@@ -100,6 +111,10 @@ fun main() = application {
blur.radius = 0.5
}
is LineBlur -> {
blur.blurAngle = seconds * 30.0
blur.spread = 8.0
}
}
// Apply the effect on `dry` writing the result to `wet`

View File

@@ -3,6 +3,10 @@ import org.openrndr.draw.createEquivalent
import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.edges.CannyEdgeDetector
/**
* Demonstrates the [CannyEdgeDetector] effect applied to a loaded
* color photograph.
*/
fun main() = application {
program {
val image = loadImage("demo-data/images/image-001.png")

View File

@@ -3,6 +3,13 @@ import org.openrndr.draw.createEquivalent
import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.color.Duotone
/**
* This demo shows how to use the [Duotone] filter,
* toggling the `labInterpolation` parameter every second on and off.
*
* The `foregroundColor` and `backgroundColor` parameters are
* left to their defaults.
*/
fun main() = application {
program {

View File

@@ -4,6 +4,15 @@ import org.openrndr.draw.createEquivalent
import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.color.DuotoneGradient
/**
* The [DuotoneGradient] effect combines the Duotone effect
* and a linear gradient: two duotone colors are applied on
* one part of the image, and those colors are interpolated
* to two other colors, applied in a different part of the image.
*
* The `rotation` parameter lets us specify in which direction
* the interpolation happens (vertical, horizontal, or something else).
*/
fun main() = application {
program {
val image = loadImage("demo-data/images/image-001.png")

View File

@@ -3,6 +3,10 @@ import org.openrndr.draw.createEquivalent
import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.color.Posterize
/**
* Demonstration of the [Posterize] effect to reduce the number of colors
* present in an image.
*/
fun main() = application {
program {
val image = loadImage("demo-data/images/image-001.png")

View File

@@ -5,6 +5,12 @@ import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.colormap.GrayscaleColormap
import kotlin.math.sin
/**
* The [GrayscaleColormap] uses the red channel of a colorBuffer
* to produce a gray scale image. The `curve` parameter is used as
* an exponent to bias the result up or down. 1.0 produces a linear
* transformation.
*/
fun main() = application {
program {
val colormap = GrayscaleColormap()

View File

@@ -5,6 +5,13 @@ import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.colormap.SpectralZucconiColormap
import kotlin.math.sin
/**
* Demonstrates the [SpectralZucconiColormap], which
* maps values of the RED color channel to the natural light dispersion
* spectrum as described by Alan Zucconi in his
* [Improving the Rainbow](https://www.alanzucconi.com/2017/07/15/improving-the-rainbow/)
* article.
*/
fun main() = application {
program {
val colormap = SpectralZucconiColormap()

View File

@@ -5,6 +5,12 @@ import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.colormap.TurboColormap
import kotlin.math.sin
/**
* Demonstrates the use of the [TurboColormap] effect, which
* maps values of the RED color channel to Turbo Colormap according to
* [Turbo, An Improved Rainbow Colormap for Visualization](https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html)
* by Google.
*/
fun main() = application {
program {
val colormap = TurboColormap()

View File

@@ -10,49 +10,69 @@ import org.openrndr.extra.fx.grain.FilmGrain
import org.openrndr.extra.noise.*
import org.openrndr.math.smoothstep
import kotlin.math.cos
import kotlin.math.sin
/**
* Advanced demonstration of composite filters, created by chaining
* several filters together using the `.then()` operator.
*
* The demo applies a [FilmGrain] effect and a [DirectionalBlur] effect twice
* with different parameters.
*
* The [DirectionalBlur] requires a color buffer to define the displacement
* directions. In this program, the direction color buffer is populated by writing
* into its `shadow` property pixel by pixel.
*
* Notice the use of `frameCount` and `seconds` to animate the effects.
*
* The composite effect is installed as a post-processing effect
* using `extend(Post())`, so anything drawn in following `extend`
* blocks is affected by it.
*/
fun main() = application {
program {
// -- create a color buffer and fill it with random direction vectors
val direction = colorBuffer(width, height, type = ColorType.FLOAT32)
val s = direction.shadow
val n = simplex2D.bipolar().fbm().scaleShiftInput(0.01, 0.0, 0.01, 0.0).withVector2Output()
val ng = simplex2D.unipolar().scaleShiftInput(0.005, 0.0, 0.005, 0.0)
for (y in 0 until height) {
for (x in 0 until width) {
val nv = n(2320, x.toDouble(), y.toDouble()) * smoothstep(
0.45,
0.55,
ng(1032, x.toDouble(), y.toDouble())
)
s[x, y] = ColorRGBa(nv.x, nv.y, 0.0, 1.0)
}
}
s.upload()
val directional = DirectionalBlur()
// -- create a bidirectional composite filter by using a directional filter twice
val bidirectional = directional.then(directional) {
firstParameters {
window = 50
spread = 1.5 + sin(seconds)
perpendicular = false
}
secondParameters {
window = 3
spread = 1.5 + cos(seconds)
perpendicular = true
}
}
val grain = FilmGrain()
grain.grainStrength = 1.0
// -- create a grain-blur composite filter
val grainBlur = bidirectional.then(grain)
extend(Post()) {
// -- create a color buffer and fill it with random direction vectors
val direction = colorBuffer(width, height, type = ColorType.FLOAT32)
val s = direction.shadow
val n = simplex2D.bipolar().fbm().scaleShiftInput(0.01, 0.0, 0.01, 0.0).withVector2Output()
val ng = simplex2D.unipolar().scaleShiftInput(0.005, 0.0, 0.005, 0.0)
for (y in 0 until height) {
for (x in 0 until width) {
val a = smoothstep(0.4, 0.6, cos((x + y) * 0.01) * 0.5 + 0.5)
val nv = n(2320, x.toDouble(), y.toDouble()) * smoothstep(
0.45,
0.55,
ng(1032, x.toDouble(), y.toDouble())
)
s[x, y] = ColorRGBa(nv.x, nv.y, 0.0, 1.0)
}
}
s.upload()
val directional = DirectionalBlur()
// -- create a bidirectional composite filter by using a directional filter twice
val bidirectional = directional.then(directional) {
firstParameters {
window = 50
perpendicular = false
}
secondParameters {
window = 3
perpendicular = true
}
}
val grain = FilmGrain()
grain.grainStrength = 1.0
// -- create a grain-blur composite filter
val grainBlur = grain.then(bidirectional)
post { input, output ->
grain.time = frameCount * 1.0
grainBlur.apply(arrayOf(input, direction), output)
}
}

View File

@@ -1,8 +1,3 @@
/**
* Demonstrate the Contour filter
* @author Edwin Jakobs
*/
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.createEquivalent
@@ -11,6 +6,20 @@ import org.openrndr.extra.fx.edges.Contour
import org.openrndr.extra.imageFit.imageFit
import org.openrndr.extra.shapes.primitives.grid
/**
* Demonstrates the [Contour] filter.
* @author Edwin Jakobs
*
* This demo creates a grid of 2x2 to draw a loaded image four times,
* each using the [Contour] effect with different parameters.
*
* `actions` is a variable containing a list of 4 functions.
* Each of these functions sets the effect parameters to different values.
*
* The 4 grid cells and the 4 actions are used in pairs:
* first the action is called to set the effect parameters, the
* effect is applied, and the result is drawn in a cell.
*/
fun main() = application {
configure {
width = 720
@@ -19,33 +28,32 @@ fun main() = application {
program {
val image = loadImage("demo-data/images/image-001.png")
val contour = Contour()
contour.levels = 4.0
contour.window = 1
contour.outputBands = true
contour.contourColor = ColorRGBa.PINK
contour.backgroundOpacity = 0.0
val edges = image.createEquivalent()
val cells = drawer.bounds.grid(2, 2).flatten()
val actions = listOf(
{
contour.outputBands = true
contour.levels = 2.0
},
{
contour.outputBands = false
contour.levels = 2.0
},
{
contour.outputBands = false
contour.levels = 8.0
},
{
contour.outputBands = true
contour.levels = 8.0
},
)
extend {
val cells = drawer.bounds.grid(2, 2).flatten()
val actions = listOf(
{
contour.outputBands = true
contour.levels = 2.0
},
{
contour.outputBands = false
contour.levels = 2.0
},
{
contour.outputBands = false
contour.levels = 8.0
},
{
contour.outputBands = true
contour.levels = 8.0
},
)
for ((cell, action) in cells zip actions) {
action()
contour.apply(image, edges)

View File

@@ -3,6 +3,12 @@ import org.openrndr.draw.createEquivalent
import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.distort.Lenses
/**
* Demonstrates the [Lenses] effect, which by default subdivides a color buffer
* in 8 columns and 6 rows, and displaces the source texture inside each rectangle.
* Try experimenting with some of the other parameters, like `distort`.
* You can even animate them.
*/
fun main() = application {
configure {
width = 640
@@ -14,7 +20,7 @@ fun main() = application {
val lenses = Lenses()
val edges = image.createEquivalent()
extend {
lenses.rotation = 0.0
lenses.rotation = 30.0
lenses.scale = 1.5
lenses.apply(image, edges)

View File

@@ -3,6 +3,12 @@ import org.openrndr.draw.createEquivalent
import org.openrndr.draw.loadImage
import org.openrndr.extra.fx.dither.LumaHalftone
/**
* Demonstrates the [LumaHalftone] effect and moste of its parameters.
* The `invert` parameter toggles between true and false once per second.
* The `phase0` and `phase1` parameters depend on `seconds`, which makes
* the pattern wobble slowly.
*/
fun main() = application {
program {
val image = loadImage("demo-data/images/image-001.png")

View File

@@ -5,6 +5,10 @@ import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.fx.distort.FluidDistort
import org.openrndr.extra.fx.patterns.Checkers
/**
* Demonstrates [FluidDistort], a fluid simulation real time effect.
* All pixels are slowly displaced in a turbulent manner as if they were a gas or a liquid.
*/
fun main() = application {
program {
val fd = FluidDistort()

View File

@@ -4,6 +4,15 @@ import org.openrndr.extra.fx.blend.Add
import org.openrndr.extra.fx.blur.ApproximateGaussianBlur
import kotlin.math.cos
/**
* Demonstrates how to create an `extend` block to apply a post-processing effect.
* The effect is an [ApproximateGaussianBlur] and its `sigma` parameter
* is animated. The Blur effect is combined with whatever the user draws
* in the regular `extend` block using the `Add` filter, resulting in
* an additive composition.
*
* This demo also shows how to make a program window resizable.
*/
fun main() = application {
configure {
windowResizable = true

View File

@@ -8,6 +8,20 @@ import org.openrndr.extra.fx.patterns.Checkers
import org.openrndr.math.Vector2
import kotlin.math.sin
/**
* Demonstration of how to use the [BlendSpectral] filter to combine two images, using
* this pigment-simulation color mixing approach.
*
* The program:
* - generates two images
* - blurs one of them
* - creates and draws a checkers-pattern as the background
* - mixes and draws both images
*
* The `fill` factor, which controls how the top and the bottom colors are mixed, is animated.
*
* The `clip` parameter is also animated and toggles every 6 seconds.
*/
fun main() = application {
configure {
width = 800
@@ -35,7 +49,7 @@ fun main() = application {
extend {
drawer.image(checked)
blendSpectral.fill = sin(seconds) * 0.5 + 0.5
blendSpectral.clip = seconds.mod(4.0) > 2.0
blendSpectral.clip = seconds.mod(12.0) > 6.0
blendSpectral.apply(a, b, mixed)
drawer.image(mixed)
}