Last active
May 8, 2020 21:27
-
-
Save ylegall/82c24bad475bc8a1463d52095d649f8d to your computer and use it in GitHub Desktop.
demo of depth of field blur using OpenRNDR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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