Skip to the content
Materials

Materials

A caster’s KausticsMaterial says how it sends light on: reflected off its surface, or bent through it. There are three kinds.

Kind Made with What the light does
Metal .metal(_:roughness:) Reflects, with Schlick’s Fresnel.
Water .water(ior:roughness:tint:abbe:) Bends through one surface and carries on inside the medium, as sunlight through the surface of a pool on to its floor.
Glass .glass(_:dispersion:) or .glass(ior:roughness:tint:abbe:) Bends into a closed solid, through it, and out of its far side, as through a glass ball, followed through its reflections inside.

#Metal

Swift
.metal(.gold, roughness: 0.04)
.metal(f0: [0.95, 0.64, 0.54], roughness: 0.1)

Metal reflects the light with Schlick’s Fresnel, using its reflectance at normal incidence (f0). The presets are well known metals:

Preset f0, linear
.gold [1.00, 0.71, 0.29]
.silver [0.95, 0.93, 0.88]
.copper [0.95, 0.64, 0.54]
.aluminium [0.91, 0.92, 0.92]
.chrome [0.55, 0.56, 0.55]
.brass [0.91, 0.78, 0.42]

#Roughness

roughness runs from 0, polished, to 1. A rougher surface blurs its caustics more the further the light travels after it leaves the surface. The default for metal is 0.05, and the demo’s slider for it runs from 0 to 0.3.

#Water

Swift
.water(ior: 1.333, roughness: 0, tint: [0.82, 0.94, 0.96])
.water(abbe: 55.7)

Water is one refracting surface, such as the surface of a pool over its floor. The receivers are inside the medium, and the light is refracted once with the exact Fresnel transmittance, then absorbed as it carries on.

#Glass

Swift
.glass(.crown)                        // crown glass, dispersing
.glass(.diamond, dispersion: false)   // diamond's index, every color bent alike
.glass(ior: 1.5, roughness: 0.01, tint: [0.93, 0.97, 0.95])

Glass is a closed solid with two interfaces. The light is refracted in, and at the face it meets inside it is split as Fresnel has it. The share that gets out leaves. The share reflected back inside (all of it, past the critical angle) goes on to the next face and is split there again, up to internalReflections times. Light still inside after that is dropped.

internalReflections runs from 0 to 4. Each is another copy of the triangles to draw. One is plenty for a ball, which reflects little inside; a prism or a cut gem, whose faces reflect much of the light back in, wants three. The presets follow how much their faces reflect back in, and a plain .glass(ior:) follows one.

Preset Index at 587.6 nm Abbe number Reflections inside
.water 1.333 55.7 1
.crown 1.517 64.2 1
.flint 1.620 36.4 2
.denseFlint 1.785 25.7 3
.diamond 2.417 55.3 3

Glass is meant for a closed solid. The light finds its faces in the light’s view of the solid’s front and back faces, which is exact for convex solids and an approximation for concave ones.

Water and glass also throw the share of the light their surface reflects, weighed by Fresnel, as a faint caustic of its own: on a pool’s walls just above the water, a faint shimmer of the sun off its surface. KausticsRenderer.throwsReflections turns it off.

#Dispersion

Give water or glass an Abbe number and white light splits into its colors: through a prism into a spectrum, at the edges of a glass ball’s caustic as fringes. The presets disperse unless told not to with dispersion: false.

The light is then traced at eight wavelengths from 400 to 700 nm. Each is bent by its own index of refraction, from Cauchy’s equation fitted to the index at 587.6 nm and the Abbe number, and carries its share of the CIE 1931 color matching functions, so the eight add up to exactly white. The lower the Abbe number, the further apart the colors spread. material.ior(at:) gives the index at any wavelength, in nanometres.

Without an Abbe number every wavelength is bent alike, which costs an eighth as much. What dispersion costs is in Limits.

#Index of refraction and tint

ior is the index of refraction, 1.333 for water and 1.5 for ordinary glass by default. The demo’s slider for it runs from 1.1 to 2.2.

tint is the color light keeps after travelling one world unit inside the medium, following the Beer-Lambert law, so two units keep tint * tint. White is perfectly clear.

#All together

You can build a material from its parts:

Swift
var material = KausticsMaterial(kind: .refractiveSolid, f0: [0.04, 0.04, 0.04], roughness: 0, ior: 1.7, tint: [1, 1, 1], abbe: 30)
material.internalReflections = 2

kind is .metal, .refractiveSurface or .refractiveSolid. f0 only matters for metal, and abbe and internalReflections only for water and glass.