Skip to the content

Real-time caustics for iOS.

.package(url: "https://github.com/dovas-net/kaustics-ios.git", from: "0.1.0")

Where a curved surface gathers light into a smaller patch it gets brighter, and where it spreads it, dimmer. That ratio is the whole caustic.

The light that objects throw.

Five passes, every frame.

The light’s view
The throw
Triangles
Blur by distance
The texture

Read how it works

Built to move, and to fit your own rendering.

Moving meshes
A light with a size

Soft shadows, and caustics that soften the further the light travels.

Textures you can use anywhere

Each receiver gets its own irradiance texture, for your own shaders, SceneKit or RealityKit.

Two levels of API.A whole scene in one view, or your own Metal.

Swift
import Kaustics
import SwiftUI

struct RingView: View {
    @State private var scene = KausticsScene(
        light: KausticsLight(
            position: [1.6, 0.7, 1.4], intensity: 12, radius: 0.025),
        casters: [
            KausticsCaster(
                mesh: try! .ring(),
                material: .metal(.gold, roughness: 0.04))
        ],
        surfaces: [
            .init(.floor(size: [2, 2]), color: [0.75, 0.73, 0.7])
        ],
        camera: .init(
            position: [0, 1.15, 1.45],
            target: [0, 0, 0],
            fieldOfView: 0.95))

    var body: some View {
        KausticsView(scene: scene).ignoresSafeArea()
    }
}
Swift
let kaustics = try KausticsRenderer(device: device)
kaustics.light = KausticsLight(position: [1, 2, 1], intensity: 6, radius: 0.03)
kaustics.casters = [
    KausticsCaster(mesh: mesh, material: .glass(ior: 1.5), transform: model)
]
kaustics.receivers = [
    .floor(size: [2, 2]),
    .wall(center: [0, 1, -1], facing: [0, 0, 1], size: [2, 2])
]

// Every frame, before the passes that use it:
kaustics.encode(into: commandBuffer)

// rgba16Float, covering the floor's rectangle
let floorLight = kaustics.irradiance(for: 0)

Measured against the real light.Within 3% where the answer is exact.

How it is measured
  • Kaustics
  • Image-space caustics*
  • Caustic maps*
  • Path tracing, one sample*
0.089
0.240
0.310
0.550

Gold ring

0.163
0.330
0.380
0.470

Rough gold ring

0.010
0.090
0.120
0.410

Glass ball

0.017
0.140
0.170
0.480

Flint glass ball, colors split

0.257
0.460
0.520
0.740

Dense flint prism

0.052
0.170
0.210
0.620

Pool

Relative mean squared error against a photon trace, lower is better.

* Sample figures, not yet measured.

Honest about what it does not do yet.

  • Flat receiversLight lands on rectangles, at most eight.
  • One point lightNo directional light, area light or spotlight cone yet.
  • Few bouncesOnce off metal, once through water, and up to four reflections inside glass.
All the limits of v0.1.0

Add it to your project.