[orx-fx] Add comments to demos
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user