Skip to content

Instantly share code, notes, and snippets.

@ylegall
Last active May 8, 2020 21:27
Show Gist options
  • Save ylegall/82c24bad475bc8a1463d52095d649f8d to your computer and use it in GitHub Desktop.
Save ylegall/82c24bad475bc8a1463d52095d649f8d to your computer and use it in GitHub Desktop.
demo of depth of field blur using OpenRNDR
package org.ygl.openrndr.demos
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.BlendMode
import org.openrndr.draw.ColorType
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.VertexElementType
import org.openrndr.draw.isolatedWithTarget
import org.openrndr.draw.renderTarget
import org.openrndr.draw.shadeStyle
import org.openrndr.draw.vertexBuffer
import org.openrndr.draw.vertexFormat
import org.openrndr.extensions.Screenshots
import org.openrndr.extra.compositor.compose
import org.openrndr.extra.compositor.draw
import org.openrndr.extra.gui.GUI
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.extra.parameters.IntParameter
import org.openrndr.extras.camera.OrbitalCamera
import org.openrndr.extras.camera.OrbitalControls
import org.openrndr.extras.camera.applyTo
import org.openrndr.extras.meshgenerators.boxMesh
import org.openrndr.math.Spherical
import org.openrndr.math.Vector3
import org.openrndr.math.transforms.transform
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
fun main() = application {
configure {
width = 800
height = 800
}
program {
val boxGeometry = boxMesh(10.0, 10.0, 10.0)
val transforms = vertexBuffer(vertexFormat {
attribute("transform", VertexElementType.MATRIX44_FLOAT32)
}, 5)
val imageBuffer = renderTarget(width, height) { colorBuffer() }
val blurTarget = renderTarget(width, height) { colorBuffer(type = ColorType.FLOAT32) }
val camera = OrbitalCamera(eye = Vector3(36.0, 12.0, -10.0), lookAt = Vector3.ZERO)
val params = @Description("params") object {
@DoubleParameter("blur radius", 0.0, 2.0)
var blurRadius = 0.5
@IntParameter("blur iterations", 0, 40)
var blurIterations = 20
}
val composite = compose {
draw {
drawer.shadeStyle = shadeStyle {
vertexTransform ="""
x_viewMatrix *= i_transform;
x_modelNormalMatrix *= i_transform;
""".trimIndent()
fragmentTransform = """
float dot_prod = dot(v_worldNormal, p_light);
float normalized = (1 + dot_prod) / 2;
float light = clamp(normalized, 0.0, 1.0);
x_fill.rgb *= light;
""".trimIndent()
parameter("light", Vector3(0.0, 1.0, 0.0).normalized)
}
transforms.put {
for (i in 0 until transforms.vertexCount) {
val transform = transform {
translate(-30.0 + i * 15.0, 0.0, 0.0)
rotate(Vector3.UNIT_X, i * seconds * 8)
}
write(transform)
}
}
drawer.background(ColorRGBa.BLACK)
drawer.fill = ColorRGBa.PINK
drawer.vertexBufferInstances(
listOf(boxGeometry),
listOf(transforms),
DrawPrimitive.TRIANGLES,
transforms.vertexCount
)
}
}
fun computeFocalBlur(iterations: Int) {
val lookAt = camera.lookAt
val sphericalEye = camera.spherical
// initial image
drawer.isolatedWithTarget(blurTarget) {
drawStyle.blendMode = BlendMode.OVER
camera.applyTo(drawer)
composite.draw(drawer)
}
// move camera in a circle for blur
for (i in 0 until iterations) {
val angle = 2 * PI * i / iterations
val rx = params.blurRadius * cos(angle)
val ry = params.blurRadius * sin(angle)
val newPosition = sphericalEye + Spherical(rx, ry, 0.0)
// first draw to opaque buffer
drawer.isolatedWithTarget(imageBuffer) {
camera.setView(lookAt, newPosition, camera.fov)
camera.applyTo(drawer)
composite.draw(drawer)
}
// then copy to floating point render target using ADD blend mode
drawer.isolatedWithTarget(blurTarget) {
drawStyle.blendMode = BlendMode.ADD
image(imageBuffer.colorBuffer(0))
}
}
// reset camera
camera.setView(lookAt, sphericalEye, camera.fov)
}
extend(OrbitalControls(camera))
extend(Screenshots())
//extend(GUI()) {
// add(params)
//}
extend {
camera.update(deltaTime)
computeFocalBlur(params.blurIterations)
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill.rgba /= p_iterations;
""".trimIndent()
parameter("iterations", params.blurIterations)
}
drawer.image(blurTarget.colorBuffer(0))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment