Skip to content

Instantly share code, notes, and snippets.

@ylegall
Last active September 20, 2021 04:44
Show Gist options
  • Save ylegall/0f264aef6671b3c83e4d6e9049e54d4a to your computer and use it in GitHub Desktop.
Save ylegall/0f264aef6671b3c83e4d6e9049e54d4a to your computer and use it in GitHub Desktop.
openRNDR slit scan example. each pixel can come from a different frame in the image sequence.
import org.openrndr.WindowMultisample
import org.openrndr.application
import org.openrndr.draw.ImageFileFormat
import org.openrndr.draw.arrayTexture
import org.openrndr.draw.loadImage
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.compositor.compose
import org.openrndr.extra.compositor.draw
import org.openrndr.extra.compositor.layer
import org.openrndr.extra.compositor.post
import org.openrndr.extra.fx.blur.FrameBlur
import org.openrndr.ffmpeg.MP4Profile
import org.openrndr.ffmpeg.ScreenRecorder
fun main() = application {
configure {
width = 1080
height = 1080
}
program {
val totalFrames = 150
val inputDir = "frames/"
val outputDir = "frames-out/"
val arrayTexture = arrayTexture(width, height, totalFrames)
fun loadFrames() {
println("loading frames...")
for (frame in 1 .. totalFrames) {
val file = "${inputDir}frame_%04d.png".format(frame)
val colorBuffer = loadImage(file, formatHint = ImageFileFormat.PNG)
colorBuffer.copyTo(arrayTexture, frame - 1)
colorBuffer.destroy()
}
println("done loading frames")
}
loadFrames()
val composite = compose {
layer {
draw {
val frame = (frameCount - 1) % totalFrames
val t = frame / totalFrames.toDouble()
drawer.shadeStyle = shadeStyle {
fragmentPreamble = """
float rand(vec2 co){
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
}
""".trimIndent()
fragmentTransform = """
vec2 pos = c_boundsPosition.xy;
float dist = distance(pos, vec2(0.5, 0.5));
dist += 0.010 * rand(pos) - 0.005;
float timeOffset = fract(p_time - dist + 2.0);
float framePct = p_totalFrames * timeOffset;
int frame1 = (p_frame + int(framePct)) % p_totalFrames;
int frame2 = (frame1 + 1) % p_totalFrames;
x_fill = mix(
texture(p_arrayTexture, vec3(pos, frame1)),
texture(p_arrayTexture, vec3(pos, frame2)),
fract(framePct)
);
""".trimIndent()
parameter("arrayTexture", arrayTexture)
parameter("frame", frame)
parameter("totalFrames", totalFrames)
parameter("time", t)
}
drawer.rectangle(drawer.bounds)
}
post(FrameBlur()) {
blend = 0.5
}
}
}
extend(ScreenRecorder()) {
outputFile = outputDir + "cross-swap.mp4"
profile = MP4Profile().apply { mode(MP4Profile.WriterMode.Lossless) }
frameRate = 30
frameSkip = 10
maximumFrames = totalFrames.toLong()
quitAfterMaximum = true
}
extend {
composite.draw(drawer)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment