From ec4032c452451509d4ff831bfbdedc199df6842c Mon Sep 17 00:00:00 2001 From: Abe Pazos Date: Sat, 20 Sep 2025 19:07:38 +0200 Subject: [PATCH] [orx-shade-styles] Write comments on demos --- .../src/commonMain/kotlin/fills/FillEnums.kt | 25 ++++++++++++++++ .../src/jvmDemo/kotlin/clip/DemoClip01.kt | 12 ++++++-- .../src/jvmDemo/kotlin/clip/DemoClip02.kt | 18 +++++++++-- .../src/jvmDemo/kotlin/clip/DemoClip03.kt | 11 +++++++ .../jvmDemo/kotlin/composed/DemoComposed01.kt | 17 ++++------- .../kotlin/gradients/DemoGradient01.kt | 9 +++++- .../kotlin/gradients/DemoGradient02.kt | 30 +++++++++++++++---- .../kotlin/gradients/DemoGradient03.kt | 5 ++++ .../kotlin/gradients/DemoGradient04.kt | 9 ++++++ .../kotlin/gradients/DemoGradient05.kt | 11 +++++++ .../kotlin/gradients/DemoGradient06.kt | 9 ++++++ .../kotlin/gradients/DemoGradient07.kt | 10 ++++++- .../kotlin/gradients/DemoGradient08.kt | 13 ++++++-- .../kotlin/gradients/DemoGradient09.kt | 11 +++++++ .../jvmDemo/kotlin/image/DemoImageFill01.kt | 5 ++++ .../jvmDemo/kotlin/image/DemoImageFill02.kt | 9 ++++-- .../jvmDemo/kotlin/image/DemoImageFill03.kt | 5 ++++ .../jvmDemo/kotlin/noise/DemoBlueNoise01.kt | 22 ++++++++++---- .../src/jvmDemo/kotlin/noise/DemoSimplex01.kt | 15 +++++++--- .../jvmDemo/kotlin/noise/DemoWhiteNoise01.kt | 9 +++++- .../jvmDemo/kotlin/patterns/DemoPatterns01.kt | 16 ++++++++-- .../jvmDemo/kotlin/patterns/DemoPatterns02.kt | 4 +++ .../jvmDemo/kotlin/patterns/DemoPatterns03.kt | 9 ++++-- .../kotlin/spatial/DemoHemisphere01.kt | 5 ++++ .../kotlin/spatial/DemoVisualizeNormals01.kt | 5 ++++ .../src/jvmDemo/kotlin/frames/DemoFrames01.kt | 14 +++++++++ .../kotlin/hobbycurve/DemoHobbyCurve01.kt | 15 ++++++++-- .../kotlin/hobbycurve/DemoHobbyCurve02.kt | 11 +++++-- .../kotlin/hobbycurve/DemoHobbyCurve03.kt | 25 ++++++++-------- 29 files changed, 298 insertions(+), 61 deletions(-) diff --git a/orx-shade-styles/src/commonMain/kotlin/fills/FillEnums.kt b/orx-shade-styles/src/commonMain/kotlin/fills/FillEnums.kt index 37c7151d..9d5842ce 100644 --- a/orx-shade-styles/src/commonMain/kotlin/fills/FillEnums.kt +++ b/orx-shade-styles/src/commonMain/kotlin/fills/FillEnums.kt @@ -1,20 +1,45 @@ package org.openrndr.extra.shadestyles.fills + +/** + * Specifies how to fill shapes with the gradient + */ enum class FillFit { + /** Deforms the gradient to match the bounds of the shape */ STRETCH, + + /** Resizes the gradient to cover the bounds of the shape */ COVER, + + /** Resizes the gradient to fit inside the bounds of the shape */ CONTAIN } +/** + * Specifies what units are coordinates given in + */ enum class FillUnits { + /** Normalized coordinates, with (0.5, 0.5) at the center of the gradient. */ BOUNDS, + + /** Screen coordinates in pixels */ WORLD, + VIEW, + SCREEN, } +/** + * Specifies how to extend a gradient when outside the normalized range + */ enum class SpreadMethod { + /** Stretches the edge color */ PAD, + + /** Mirrors the color in a ping-pong fashion, as if traveling through the gradient back and forth */ REFLECT, + + /** Loops through the gradient as needed */ REPEAT } diff --git a/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip01.kt b/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip01.kt index 750ec3c4..bc1f2c3d 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip01.kt @@ -11,6 +11,16 @@ import org.openrndr.math.transforms.transform import kotlin.math.PI import kotlin.math.cos +/** + * Animated demonstration on how to use the `clip` shade style to mask-out + * part of an image (or anything else drawn while the shade style is active). + * The clipping uses the `CONTAIN` fit mode. + * + * This example uses a rotating `star`-shaped clipping with 24 sides. + * Other available clipping shapes are `circle`, `rectangle`, `line` and `ellipse`. + * + * Press a mouse button to toggle the `feather` property between 0.0 and 0.5. + */ fun main() = application { configure { width = 720 @@ -25,10 +35,8 @@ fun main() = application { val image = loadImage("demo-data/images/image-001.png") extend { - val grid = drawer.bounds.grid(3, 3) for ((index, cell) in grid.flatten().withIndex()) { - drawer.shadeStyle = clip { clipFit = FillFit.CONTAIN feather = gf diff --git a/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip02.kt b/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip02.kt index 2b4321fd..88814ad2 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip02.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip02.kt @@ -12,6 +12,17 @@ import org.openrndr.math.transforms.transform import kotlin.math.PI import kotlin.math.cos +/** + * Animated demonstration on how to use the `clip` shade style to mask-out + * part of an image (or anything else drawn while the shade style is active). + * The clipping uses different fit modes on each row, and different aspect + * ratios in each column. + * + * This example uses a rotating `star`-shaped clipping with 24 sides. + * Other available clipping shapes are `circle`, `rectangle`, `line` and `ellipse`. + * + * Press a mouse button to toggle the `feather` property between 0.0 and 0.5. + */ fun main() = application { configure { width = 720 @@ -31,7 +42,7 @@ fun main() = application { for ((index, cell) in grid.flatten().withIndex()) { drawer.shadeStyle = clip { - clipFit = FillFit.entries[index/3] + clipFit = FillFit.entries[index / 3] feather = gf clipTransform = transform { @@ -43,12 +54,13 @@ fun main() = application { star { radius = 0.5 center = Vector2(0.5, 0.5) - sharpness = cos( 2 * PI * index / 9.0 + seconds) * 0.25 + 0.5 + sharpness = cos(2 * PI * index / 9.0 + seconds) * 0.25 + 0.5 sides = 24 } } - val acell = when(val i = index%3) { + // Use sub() on squares to create vertical or horizontal rectangles + val acell = when (val i = index % 3) { 1 -> cell.sub(0.0..0.5, 0.0..1.0) 2 -> cell.sub(0.0..1.0, 0.0..0.5) else -> cell diff --git a/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip03.kt b/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip03.kt index 4e2105c2..fb8f301a 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip03.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/clip/DemoClip03.kt @@ -10,6 +10,17 @@ import org.openrndr.extra.shapes.primitives.placeIn import org.openrndr.math.Vector2 import org.openrndr.math.transforms.transform +/** + * Animated demonstration on how to use the `clip` shade style to mask-out + * part of an image (or anything else drawn while the shade style is active). + * The clipping uses different fit modes on each row, and different aspect + * ratios in each column. + * + * This example uses a rotating `ellipse`-shaped clipping. + * Other available clipping shapes are `circle`, `rectangle`, `line` and `star`. + * + * Press a mouse button to toggle the `feather` property between 0.0 and 0.5. + */ fun main() = application { configure { width = 720 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/composed/DemoComposed01.kt b/orx-shade-styles/src/jvmDemo/kotlin/composed/DemoComposed01.kt index dd2b7c6e..cf5fd530 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/composed/DemoComposed01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/composed/DemoComposed01.kt @@ -6,19 +6,12 @@ import org.openrndr.extra.shadestyles.fills.clip.clip import org.openrndr.extra.shadestyles.fills.gradients.gradient /** - * The main entry point of the application that sets up the visual program. + * Demonstrates how to combine two shade styles + * (a conic gradient and a rounded star clipping) + * by using the `+` operator. * - * This method creates a graphical program with a 720x720 window and uses a rotating - * gradient-shaded rectangle as the primary visual element. It demonstrates the use - * of gradient shading and clipping through a compositional approach. - * - * The method performs the following actions: - * 1. Configures the application window size. - * 2. Constructs a conic gradient with a rotation of 54 degrees and full circular coverage. - * 3. Creates a star-shaped clip with configurable sharpness, radius, and number of sides. - * 4. Combines the gradient and clip into a composite shading style. - * 5. Defines a program loop where the rectangle with the gradient and clip combination - * rotates around the center of the canvas while being redrawn continuously. + * The design is animated by applying a rotation transformation matrix + * based in the `seconds` variable. */ fun main() = application { configure { diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt index 31b61c0e..f5553c53 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt @@ -7,6 +7,14 @@ import org.openrndr.extra.shadestyles.fills.gradients.gradient import org.openrndr.math.Vector2 import kotlin.math.cos +/** + * Demonstrates how to create 4 animated gradient shade-styles with 5 colors: + * - a linear gradient + * - a stellar gradient + * - a radial gradient + * - a linear gradient with `SpreadMethod.REPEAT` + * Each gradient style has different adjustable attributes. + */ fun main() { application { configure { @@ -25,7 +33,6 @@ fun main() { linear { start = Vector2(0.1, 0.1).rotate(seconds * 36.0, Vector2(0.5, 0.5)) end = Vector2(0.9, 0.9).rotate(seconds * 36.0, Vector2(0.5, 0.5)) - } } drawer.rectangle(0.0, 0.0, 360.0, 360.0) diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient02.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient02.kt index 6e46ea94..2eb17771 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient02.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient02.kt @@ -8,6 +8,18 @@ import org.openrndr.extra.shadestyles.fills.FillUnits import org.openrndr.extra.shadestyles.fills.SpreadMethod import org.openrndr.extra.shadestyles.fills.gradients.gradient +/** + * An application with two animated layers of slightly different stellar shade styles. + * + * The bottom layer features a rectangle, while the top layer includes a large text + * repeated 5 times. + * + * The only different between the two shade styles is a minor change in the `levelWarp` + * function, which is used to alter the gradient's level (its normalized `t` value) + * based on the current coordinates being processed, and the original level at this location. + * + * Without this difference, the shader would look identical, and the text would be invisible. + */ fun main() { application { configure { @@ -24,18 +36,22 @@ fun main() { quantization = 10 fillUnits = FillUnits.WORLD spreadMethod = SpreadMethod.REFLECT - levelWarpFunction = """float levelWarp(vec2 p, float level) { return level + cos(p.x*0.01 + level)*0.1; } """ + levelWarpFunction = """ + float levelWarp(vec2 p, float level) { + return level + cos(p.x * 0.01 + level) * 0.1; + } + """.trimIndent() stellar { - radius = drawer.bounds.width/4.0 + radius = drawer.bounds.width / 4.0 center = drawer.bounds.position(0.5, 0.0) sides = 6 sharpness = 0.5 rotation = seconds * 36.0 } } - drawer.rectangle(drawer.bounds) + drawer.shadeStyle = gradient { stops[0.0] = ColorRGBa.BLUE_STEEL stops[0.75] = ColorRGBa.WHITE @@ -44,10 +60,14 @@ fun main() { quantization = 10 fillUnits = FillUnits.WORLD spreadMethod = SpreadMethod.REFLECT - levelWarpFunction = """float levelWarp(vec2 p, float level) { return level + 0.1 + cos(p.x*0.01 + level)*0.1; } """ + levelWarpFunction = """ + float levelWarp(vec2 p, float level) { + return level + 0.1 + cos(p.x * 0.01 + level) * 0.1; + } + """.trimIndent() stellar { - radius = drawer.bounds.width/4.0 + radius = drawer.bounds.width / 4.0 center = drawer.bounds.position(0.5, 0.0) sides = 6 sharpness = 0.5 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient03.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient03.kt index 1c91ecbd..16c960a1 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient03.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient03.kt @@ -8,6 +8,11 @@ import org.openrndr.extra.shadestyles.fills.SpreadMethod import org.openrndr.extra.shadestyles.fills.gradients.gradient import org.openrndr.math.Vector2 +/** + * Demonstrates how to create a rainbow-like rotating `conic` gradient in `OKHSV` color space. + * The gradient consists of ten evenly spaced colors, achieved by shifting the hue of a base color. + * Since the conic gradient covers 360 degrees, changing the `spreadMethod` does not affect the result. + */ fun main() { application { configure { diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient04.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient04.kt index 2d99f71b..4564d715 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient04.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient04.kt @@ -11,6 +11,15 @@ import org.openrndr.extra.shapes.primitives.grid import org.openrndr.extra.shapes.primitives.placeIn import org.openrndr.math.Vector2 +/** + * Creates a 3x3 grid of gradients demonstrating how the same gradient can look different depending on + * the aspect ratio of the target shape and the fit method used. + * + * The first column features a vertical rectangle. + * The second one, a square, and the third one a horizontal rectangle. + * + * The rows feature the different fit methods: `FillFit.STRETCH`, `FillFit.COVER` and `FillFit.CONTAIN`. + */ fun main() { application { configure { diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient05.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient05.kt index ff8c4c31..a29dbbd4 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient05.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient05.kt @@ -6,7 +6,18 @@ import org.openrndr.extra.color.presets.BLUE_STEEL import org.openrndr.extra.shadestyles.fills.FillUnits import org.openrndr.extra.shadestyles.fills.SpreadMethod import org.openrndr.extra.shadestyles.fills.gradients.gradient +import org.openrndr.math.Vector2 +/** + * Reveals the effect of using quantization on a `conic` gradient. + * By using a `quantization` of 10 we get 9 color bands. + * + * Notice how the center of the `conic` gradient is specified in + * screen coordinates. To make this possible, we need to set the + * `fillUnits` to `FillUnits.WORLD`. By default, the center of + * the gradient coordinates is `Vector2(0.5, 0.5)`. + * + */ fun main() { application { configure { diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient06.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient06.kt index bb433679..5dbb5d58 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient06.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient06.kt @@ -10,6 +10,15 @@ import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin +/** + * Demonstrates how to animate the `radiusX` and `radiusY` elliptic gradient arguments separately. + * They are animated in a circular fashion, making the ellipse transition between a thin vertical shape, + * a round shape, and a thin horizontal shape. + * + * The `SpreadMethod.REPEAT` setting makes the gradient cover the available space repeating the gradient + * as many times as needed. + * + */ fun main() = application { configure { width = 720 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient07.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient07.kt index bf8f6d79..e7e2a4fc 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient07.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient07.kt @@ -10,6 +10,14 @@ import org.openrndr.extra.shadestyles.fills.gradients.gradient import org.openrndr.extra.shapes.primitives.grid import org.openrndr.math.Vector2 +/** + * A design with 48 vertical bands with gradients. Each one has a unique `quantization` + * value based on the index of the band. All bands have 2 color `stops`: + * `WHITE` at the top (position 0.0), and `BLACK` near the bottom (near position 1.0), + * with the exact value depending on the `quantization` value. + * + * Demonstrates how to produce a quantized gradient with a specific number of equal color bands. + */ fun main() = application { configure { width = 720 @@ -25,7 +33,7 @@ fun main() = application { drawer.shadeStyle = gradient { quantization = index + 2 stops[0.0] = ColorRGBa.WHITE - stops[ (quantization) / (quantization+1.0)] = ColorRGBa.BLACK + stops[(quantization) / (quantization + 1.0)] = ColorRGBa.BLACK fillUnits = FillUnits.BOUNDS fillFit = FillFit.COVER diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt index dcb7fffd..f08bc7d6 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt @@ -12,6 +12,13 @@ import org.openrndr.math.Vector2 import org.openrndr.math.asDegrees import kotlin.math.atan2 +/** + * Demonstrates the creation of a grid-based design with 13x13 cells, each with an elliptic gradient + * pointing towards the center of the window. The center cell features a circular gradient (by having + * `radiusX` equal to `radiusY`). The farther a cell is from the center, the higher the aspect ratio + * of the ellipse is, becoming closer to a line than to a circle near the corners. + * + */ fun main() = application { configure { @@ -32,10 +39,10 @@ fun main() = spreadMethod = SpreadMethod.REPEAT elliptic { - val v = Vector2(x-6.0, y-6.0) - rotation = atan2(y- 6.0, x - 6.0).asDegrees + 180.0 + val v = Vector2(x - 6.0, y - 6.0) + rotation = atan2(y - 6.0, x - 6.0).asDegrees + 180.0 radiusX = 1.0 - radiusY = 1.0 / (1.0 + v.length*0.25) + radiusY = 1.0 / (1.0 + v.length * 0.25) } } drawer.rectangle(cell) diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient09.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient09.kt index dd38937d..3acc4289 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient09.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient09.kt @@ -11,6 +11,17 @@ import org.openrndr.extra.shadestyles.fills.SpreadMethod import org.openrndr.extra.shadestyles.fills.gradients.gradient import org.openrndr.extra.shadestyles.fills.patterns.pattern +/** + * Demonstrates two types of shade styles: `pattern` and `luma`. + * + * The `pattern` shade style is used to generate a checkers-pattern. + * + * This example also loads and draws an image using the `luma` shade style + * to map pixel brightnesses to gradient colors. Dark colors are + * mapped to transparent, revealing the checkers-pattern behind it + * in parts of the image. + * + */ fun main() = application { configure { width = 720 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill01.kt b/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill01.kt index 8ba9177a..4e838600 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill01.kt @@ -4,6 +4,11 @@ import org.openrndr.application import org.openrndr.draw.loadImage import org.openrndr.extra.shadestyles.fills.image.imageFill +/** + * A minimal demonstration of the `imageFill` shade style, used to texture + * shapes using a loaded image (or generated color buffer). + * + */ fun main() = application { configure { width = 720 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill02.kt b/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill02.kt index 8a5b5713..6e3831b3 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill02.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill02.kt @@ -6,20 +6,25 @@ import org.openrndr.extra.shadestyles.fills.image.imageFill import org.openrndr.math.transforms.transform import kotlin.math.cos +/** + * Demonstrates the use of the `imageFill` shade style, applied to 10 concentric + * circles. The rotation of each circle depends on the cosine of time, with + * a varying time offset applied per circle, for a fun wavy effect. + */ fun main() = application { configure { width = 720 height = 720 } program { - var img = loadImage("demo-data/images/image-001.png") + val img = loadImage("demo-data/images/image-001.png") extend { for (i in 0 until 10) { drawer.shadeStyle = imageFill { image = img fillTransform = transform { translate(0.5, 0.5) - rotate( cos(i * 0.5 + seconds*10.0) *10.0 ) + rotate(cos(i * 0.5 + seconds * 10.0) * 10.0) scale(1.0 - i * 0.05) translate(-0.5, -0.5) } diff --git a/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill03.kt b/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill03.kt index 3bf3d498..cd673285 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill03.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/image/DemoImageFill03.kt @@ -5,6 +5,11 @@ import org.openrndr.draw.loadImage import org.openrndr.extra.shadestyles.fills.SpreadMethod import org.openrndr.extra.shadestyles.fills.image.imageFill +/** + * Demonstrates the use of the `domainWarpFunction` in an `imageFill` shade style, used to deform + * the coordinate system of the shader. A `time` parameter is passed to the shader and used + * to alter the deformation in real time. + */ fun main() = application { configure { width = 720 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoBlueNoise01.kt b/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoBlueNoise01.kt index a19e5cab..07b91c21 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoBlueNoise01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoBlueNoise01.kt @@ -7,6 +7,12 @@ import org.openrndr.extra.imageFit.imageFit import org.openrndr.extra.shaderphrases.noise.simplex13 import org.openrndr.extra.shadestyles.fills.noise.noise +/** + * Demonstrates the use of the `blueNois` variant of the `noise` shade style + * to render an image as black and white with a pointillist luma-based effect. + * + * More computationally heavy than other shade styles. + */ fun main() { application { configure { @@ -21,17 +27,23 @@ fun main() { phase = seconds * 10.0 filterWindow = 5 - domainWarpFunction = - """$simplex13 - vec3 domainWarp(vec3 p) { float px = simplex13(p*0.01); float py = simplex13(p.yxz*-0.01); return p + 10.25 * vec3(px, py, 0.0); }""".trimIndent() + domainWarpFunction = """$simplex13 + vec3 domainWarp(vec3 p) { + float px = simplex13(p * 0.01); + float py = simplex13(p.yxz * -0.01); + return p + 10.25 * vec3(px, py, 0.0); + } + """.trimIndent() blueNoise { bits = 17 bilinear() } - blendFunction = """vec4 blend(vec4 o, float n) { float luma = dot(o.rgb, vec3(1.0/3.0)); - |return vec4(vec3(smoothstep(luma+0.01, luma-0.01, n)), 1.0); + blendFunction = """ + |vec4 blend(vec4 o, float n) { + | float luma = dot(o.rgb, vec3(1.0 / 3.0)); + | return vec4(vec3(smoothstep(luma + 0.01, luma - 0.01, n)), 1.0); |}""".trimMargin() } diff --git a/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoSimplex01.kt b/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoSimplex01.kt index 9325c9a6..0ffb044d 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoSimplex01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoSimplex01.kt @@ -11,6 +11,11 @@ import org.openrndr.math.Vector3 import org.openrndr.math.transforms.transform import kotlin.math.cos +/** + * Demonstrates the use of the `simplex` variant of the `noise` shade style. + * It generates a gray-scale pattern, which is then colorized by using a `luma` + * `gradient` shade style. + */ fun main() { application { configure { @@ -23,10 +28,13 @@ fun main() { drawer.shadeStyle = noise { phase = seconds * 0.01 simplex { - } - domainWarpFunction = - """vec3 domainWarp(vec3 p) { float px = simplex13(p*4.0); float py = simplex13(p.yxz*-4.0); return p + 0.25 * vec3(px, py, px*py); }""" + domainWarpFunction = """ + vec3 domainWarp(vec3 p) { + float px = simplex13(p*4.0); + float py = simplex13(p.yxz*-4.0); + return p + 0.25 * vec3(px, py, px*py); + }""".trimIndent() anisotropicFbm { octaves = 10 @@ -46,7 +54,6 @@ fun main() { stops[0.75] = ColorRGBa.BLACK stops[1.0] = ColorRGBa.PEACH_PUFF luma { - } } drawer.circle(drawer.bounds.center, 300.0) diff --git a/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoWhiteNoise01.kt b/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoWhiteNoise01.kt index 7cd30c4c..285ba839 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoWhiteNoise01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/noise/DemoWhiteNoise01.kt @@ -6,6 +6,13 @@ import org.openrndr.extra.camera.Camera2D import org.openrndr.extra.imageFit.imageFit import org.openrndr.extra.shadestyles.fills.noise.noise +/** + * Demonstrates how to render a color image as black and white + * using the `whiteNoise` variant of the `noise` shade style. + * + * A custom `blendFunction` is used to control how pixel colors are + * transformed. + */ fun main() { application { configure { @@ -22,7 +29,7 @@ fun main() { } blendFunction = """vec4 blend(vec4 o, float n) { | float luma = dot(o.rgb, vec3(1.0/3.0)); - | return vec4(vec3(smoothstep(luma+0.01, luma-0.01, n)), 1.0); + | return vec4(vec3(smoothstep(luma+0.05, luma-0.05, n)), 1.0); |}""".trimMargin() } drawer.imageFit(image, drawer.bounds) diff --git a/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns01.kt b/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns01.kt index b86a4695..b753f8d2 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns01.kt @@ -10,6 +10,17 @@ import org.openrndr.extra.imageFit.imageFit import org.openrndr.extra.shadestyles.fills.FillUnits import org.openrndr.extra.shadestyles.fills.patterns.pattern +/** + * Demonstrates the use of the `checkers` variant of the `pattern` shade style. + * + * The style is used twice with different parameters: once for a background image + * and then for a text displayed on top of it. + * + * The text shade style features a `domainWarpFunction`, which is used to deform + * the coordinate system of the shade style. + * + * Try reducing the `scale` parameter to make the checkers more obvious. + */ fun main() = application { configure { width = 720 @@ -23,7 +34,7 @@ fun main() = application { backgroundColor = ColorRGBa.NAVY foregroundColor = ColorRGBa.WHITE patternUnits = FillUnits.WORLD - parameter("time", seconds*0.1) + parameter("time", seconds * 0.1) // domainWarpFunction = """vec2 patternDomainWarp(vec2 uv) { return uv + vec2(cos(uv.y * 0.1 + p_time), sin(uv.x * 0.1 + p_time)) * 30.05; }""" scale = 0.4 @@ -39,7 +50,8 @@ fun main() = application { foregroundColor = ColorRGBa.WHITE patternUnits = FillUnits.WORLD parameter("time", seconds) - domainWarpFunction = """vec2 patternDomainWarp(vec2 uv) { return uv + vec2(cos(uv.y * 0.1 + p_time), sin(uv.x * 0.1 + p_time)) * 30.05; }""" + domainWarpFunction = + """vec2 patternDomainWarp(vec2 uv) { return uv + vec2(cos(uv.y * 0.1 + p_time), sin(uv.x * 0.1 + p_time)) * 30.05; }""" scale = 0.2 checkers { } diff --git a/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns02.kt b/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns02.kt index 35cbe1a0..218860e6 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns02.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns02.kt @@ -8,6 +8,10 @@ import org.openrndr.extra.color.presets.PEACH_PUFF import org.openrndr.extra.shadestyles.fills.FillUnits import org.openrndr.extra.shadestyles.fills.patterns.pattern +/** + * Demonstrates the use of the `xorMod2` variant of the `pattern` shade style; + * an algorithmic and intricate pattern. + */ fun main() = application { configure { width = 720 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns03.kt b/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns03.kt index bc8d6754..856d8de1 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns03.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/patterns/DemoPatterns03.kt @@ -11,6 +11,10 @@ import org.openrndr.extra.shadestyles.fills.gradients.gradient import org.openrndr.extra.shadestyles.fills.patterns.pattern import kotlin.math.cos +/** + * Demonstrates the use of a complex shade style made by combining an + * animated `pattern`, a `gradient` and a `clip`. + */ fun main() = application { configure { width = 720 @@ -23,7 +27,7 @@ fun main() = application { backgroundColor = ColorRGBa.DARK_GRAY foregroundColor = ColorRGBa.PEACH_PUFF patternUnits = FillUnits.WORLD - parameter("time", seconds*0.1) + parameter("time", seconds * 0.1) scale = 0.2 crosses { width = 1.0 @@ -35,7 +39,7 @@ fun main() = application { stops[1.0] = ColorRGBa.BLACK stops[0.5] = ColorRGBa.WHITE stops[0.0] = ColorRGBa.WHITE - conic { } + conic { } } + clip { star { sides = 36 @@ -53,7 +57,6 @@ fun main() = application { // drawer.text("Patterns", 10.0, height / 2.0) - } } } \ No newline at end of file diff --git a/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoHemisphere01.kt b/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoHemisphere01.kt index 1ff8c0cf..c233b9e4 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoHemisphere01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoHemisphere01.kt @@ -10,6 +10,11 @@ import org.openrndr.extra.objloader.loadOBJasVertexBuffer import org.openrndr.extra.shadestyles.spatial.HemisphereLight import org.openrndr.math.Vector3 +/** + * Demonstrates the [HemisphereLight] shade style, a simple shader + * that can be used for simple illumination of 3D meshes. + * + */ fun main() { application { configure { diff --git a/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoVisualizeNormals01.kt b/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoVisualizeNormals01.kt index 30748fb1..3afe4db2 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoVisualizeNormals01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/spatial/DemoVisualizeNormals01.kt @@ -8,6 +8,11 @@ import org.openrndr.extra.objloader.loadOBJasVertexBuffer import org.openrndr.extra.shadestyles.spatial.visualizeNormals import org.openrndr.math.Vector3 +/** + * Demonstrates the use of the [visualizeNormals] shade style, which can help + * debug the normals of a 3D mesh. + * + */ fun main() { application { configure { diff --git a/orx-shapes/src/jvmDemo/kotlin/frames/DemoFrames01.kt b/orx-shapes/src/jvmDemo/kotlin/frames/DemoFrames01.kt index c8800768..8113e789 100644 --- a/orx-shapes/src/jvmDemo/kotlin/frames/DemoFrames01.kt +++ b/orx-shapes/src/jvmDemo/kotlin/frames/DemoFrames01.kt @@ -15,6 +15,20 @@ import org.openrndr.math.Vector3 import org.openrndr.shape.path3D import kotlin.random.Random +/** + * Demonstrates how to create a 3D path and attach cylinders to it at regular intervals with the correct orientation. + * + * - The path is constructed using the `path3D` builder. + * - A rectified copy is created to be able to sample it at equal-length intervals. + * - We call the `frames` method on the rectified contour to generate a list with 100 transformation matrices which + * make it possible to attach oriented 3D objects at specific locations in the curve. + * - We finally use the transformation matrices to draw cylinders along the 3D path. + * + * The orbital camera extension enables interactive 3D view manipulation. + * + * A fixed random seed is used to make sure this demo outputs a specific output. We can delete the + * `random` arguments to get a unique result each time the program runs. + */ fun main() = application { configure { width = 720 diff --git a/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve01.kt b/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve01.kt index 6c987845..fa407fa4 100644 --- a/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve01.kt +++ b/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve01.kt @@ -5,13 +5,24 @@ import org.openrndr.color.ColorRGBa import org.openrndr.extra.shapes.hobbycurve.hobbyCurve import org.openrndr.math.Vector2 +/** + * Demonstrates how to use the hobbyCurve function to render a smooth closed contour + * passing through a predefined set of points. + */ fun main() = application { program { extend { - val points = listOf(Vector2(150.0, 350.0), Vector2(325.0, 100.0), Vector2(500.0, 350.0), Vector2(325.0, 250.0)) + val points = listOf( + Vector2(150.0, 350.0), + Vector2(325.0, 100.0), + Vector2(500.0, 350.0), + Vector2(325.0, 250.0) + ) + drawer.stroke = ColorRGBa.BLACK drawer.fill = ColorRGBa.PINK - drawer.contour(hobbyCurve(points, closed=true)) + drawer.contour(hobbyCurve(points, closed = true)) + drawer.fill = ColorRGBa.WHITE drawer.circles(points, 4.0) } diff --git a/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve02.kt b/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve02.kt index 7d8dfd24..1ce37be0 100644 --- a/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve02.kt +++ b/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve02.kt @@ -7,6 +7,10 @@ import org.openrndr.extra.shapes.hobbycurve.hobbyCurve import org.openrndr.math.Vector2 import kotlin.random.Random +/** + * This demo creates a list of random 2D points, finds the alpha shape contour for those points, + * and finally makes that contour smooth by calling `hobbyCurve()`. + */ fun main() = application { configure { width = 720 @@ -15,16 +19,17 @@ fun main() = application { program { val points = List(40) { Vector2( - Random.nextDouble(width*0.25, width*0.75), - Random.nextDouble(height*0.25, height*0.75) + Random.nextDouble(width * 0.25, width * 0.75), + Random.nextDouble(height * 0.25, height * 0.75) ) } val alphaShape = AlphaShape(points) val c = alphaShape.createContour() - val hobby = hobbyCurve(c.segments.map { it.start }, closed=true) + val hobby = c.hobbyCurve() extend { drawer.fill = ColorRGBa.PINK drawer.contour(hobby) + drawer.fill = ColorRGBa.WHITE drawer.circles(points, 4.0) } diff --git a/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve03.kt b/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve03.kt index 8b542fe2..ac328799 100644 --- a/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve03.kt +++ b/orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve03.kt @@ -2,27 +2,28 @@ package hobbycurve import org.openrndr.application import org.openrndr.color.ColorRGBa -import org.openrndr.extra.noise.scatter import org.openrndr.extra.shapes.hobbycurve.hobbyCurve -import org.openrndr.extra.shapes.ordering.hilbertOrder -import kotlin.random.Random +import org.openrndr.extra.shapes.primitives.regularStar +/** + * This demo shows how the [org.openrndr.shape.ShapeContour]'s method `hobbyCurve()` can be used + * to round contours with linear segments. + */ fun main() = application { configure { width = 720 height = 720 } program { + val star = regularStar(5, 100.0, 300.0, drawer.bounds.center) + val hobby = star.hobbyCurve() extend { - for (i in -20..20) { - val t = i / 10.0 - val points = drawer.bounds.offsetEdges(-50.0).scatter(25.0, random = Random(0)).hilbertOrder() - drawer.stroke = ColorRGBa.WHITE.opacify(0.5) - drawer.fill = null - drawer.contour(hobbyCurve(points, closed = false, tensions = { i, inAngle, outAngle -> - Pair(t, t) - })) - } + drawer.fill = ColorRGBa.PINK + drawer.contour(hobby) + + drawer.fill = null + drawer.stroke = ColorRGBa.WHITE.opacify(0.5) + drawer.contour(star) } } } \ No newline at end of file