
OPENRNDR Code
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.ShadeStyle
import org.openrndr.math.Vector2
import kotlin.random.Random
data class CloudCircle(
var position: Vector2,
var velocity: Vector2,
val radius: Double,
val seed: Float
)
fun main() = application {
configure {
width = 800
height = 800
}
program {
val circles = List(15) {
CloudCircle(
position = Vector2(Random.nextDouble(100.0, 700.0), Random.nextDouble(100.0, 700.0)),
velocity = Vector2(Random.nextDouble(-1.0, 1.0), Random.nextDouble(-1.0, 1.0)),
radius = Random.nextDouble(40.0, 120.0),
seed = Random.nextFloat() * 100.0f
)
}
val cloudStyle = ShadeStyle().apply {
fragmentTransform = """
vec2 st = c_boundsPosition.xy;
vec2 coord = st * 4.0 + vec2(p_time * 0.2 + p_seed);
float n = sin(coord.x) * cos(coord.y) * 0.5 + 0.5;
float dist = length(st - vec2(0.5));
float mask = smoothstep(0.5, 0.4, dist);
vec3 cloudColor = mix(vec3(0.6, 0.7, 0.9), vec3(1.0, 1.0, 1.0), n);
x_fill = vec4(cloudColor, mask);
""".trimIndent()
}
extend {
drawer.clear(ColorRGBa(0.2, 0.3, 0.7))
for (circle in circles) {
circle.position += circle.velocity
if (circle.position.x < circle.radius || circle.position.x > width - circle.radius) {
circle.velocity = Vector2(-circle.velocity.x, circle.velocity.y)
}
if (circle.position.y < circle.radius || circle.position.y > height - circle.radius) {
circle.velocity = Vector2(circle.velocity.x, -circle.velocity.y)
}
cloudStyle.parameter("time", seconds)
cloudStyle.parameter("seed", circle.seed)
drawer.shadeStyle = cloudStyle
drawer.stroke = null
drawer.fill = ColorRGBa.WHITE
drawer.circle(circle.position, circle.radius)
}
drawer.shadeStyle = null
}
}
}