Multiple samples per pixel + focus effect

This commit is contained in:
Sven Weidauer 2025-05-12 20:56:09 +02:00
parent 9ac3ce01b8
commit 876586ee9d
2 changed files with 36 additions and 5 deletions

View file

@ -42,14 +42,34 @@ fun main() {
for (y in 0 until bmp.height) {
for (x in 0 until bmp.width) {
val point = Point(x.toFloat(), y.toFloat(), 0f)
val ray = origin.rayTo(point)
var r = 0f
var g = 0f
var b = 0f
val color = scene.colorForRay(ray)
if (color != null) {
bmp.setPixel(x, y, color.toColor())
repeat(samplesPerPixel) {
val point = Point(x.toFloat(), y.toFloat(), 0f) + Vector.randomInCircleXY() * blurriness
val ray = origin.rayTo(point)
val color = scene.colorForRay(ray)
if (color != null) {
r += color.r
g += color.g
b += color.b
}
}
bmp.setPixel(
x, y,
MaterialColor(
r = r / samplesPerPixel,
g = g / samplesPerPixel,
b = b / samplesPerPixel
).toColor()
)
}
}
File("test.tga").writeBitmap(bmp)
}
const val samplesPerPixel = 5
const val blurriness = 1f

View file

@ -1,6 +1,9 @@
package math
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
import kotlin.random.Random
data class Vector(val x: Float, val y: Float, val z: Float) {
val length: Float get() = sqrt(squaredLength)
@ -21,6 +24,14 @@ data class Vector(val x: Float, val y: Float, val z: Float) {
)
infix fun dot(rhs: Vector): Float = x * rhs.x + y * rhs.y + z * rhs.z
companion object {
fun randomInCircleXY(): Vector {
val r = sqrt(Random.Default.nextFloat())
val theta = Random.Default.nextFloat() * 2 * Math.PI.toFloat()
return Vector(r * sin(theta), r * cos(theta), 0f)
}
}
}
operator fun Float.times(rhs: Vector): Vector = rhs * this