CauldronGPU.Environment (CauldronGPU v0.3.3)

Copy Markdown View Source

What surrounds the scene: a sky shaded from sky_top through sky_horizon to sky_ground, ambient light at ambient_intensity for surfaces without a lightmap, exponential fog of fog_color thickening at fog_density per unit, exposure before tone mapping, and shadow_distance, the half width of the square around the camera that the shadow-casting light covers, and reflections, how strongly surfaces mirror the sky. With ray-traced ambient occlusion requested, ao_radius is how far occluders are looked for and ao_strength how much they darken (0 to 1). With upscaling requested, frames are drawn at render_scale of the window's size (0.25 to

  1. and upscaled to it. Light brighter than bloom_threshold spreads into a glow added at bloom_strength (0 turns it off). tone_map turns light into screen colour: :aces (filmic, deep shadows), :neutral (keeps dark colours, rolls off highlights) or :clamp (no curve).

sky_picture puts a picture in the sky in place of the shading, seen wherever nothing is drawn and on sky surfaces (CauldronGPU.Material):

  • {:layers, back, front} — two texture handles on a low dome overhead: the view's direction with its height stretched three times picks the point, about three repeats from the dome's centre to its rim, front over back by its alpha. Each layer drifts diagonally at its sky_scroll ({back, front}, repeats a second)
  • {:box, %{pos_x:, neg_x:, pos_y:, neg_y:, pos_z:, neg_z:}} — six texture handles, the faces of a box around the camera, each seen from inside with its first row at the top: pos_x has -Z on its right, neg_x +Z, pos_z +X and neg_z -X, all four with +Y at the top; pos_y and neg_y have +X on their right, pos_y +Z at its bottom and neg_y -Z at its bottom

The caller keeps the handles a sky picture uses.

light_space: :display lights surfaces with baked light (lightmaps and instances' shading) as palette games do: the texture's display colour times the light, in place of physically lit linear colour. Point, spot and directional lights then add to that light by the same rule: colour * intensity * max(dot(normal, to_light), 0), times max(1 - distance² / range², 0) for point and spot lights, and for spot lights times max(1 - x² - y², 0), x and y the point's offsets across the cone divided by the cone's half width at its distance (the outer cone angle).

The finished picture's display values v become clamp(v ** gamma * contrast + brightness, 0, 1) before the screen tint and the overlay; a gamma below 1 brightens.

light_table, {texture, reach}, turns baked light into light that falls with distance: each channel of the light (0 to 1, after light styles and the lightmap's scale) picks the column and the depth along the camera's view over reach the row (clamped) of texture, whose same channel is the light shown. The caller keeps the handle.

Summary

Types

rgb()

@type rgb() :: {number(), number(), number()}

sky_picture()

@type sky_picture() ::
  nil
  | {:layers, CauldronGPU.Handle.t(), CauldronGPU.Handle.t()}
  | {:box, %{required(atom()) => CauldronGPU.Handle.t()}}

t()

@type t() :: %CauldronGPU.Environment{
  ambient: rgb(),
  ambient_intensity: number(),
  ao_radius: number(),
  ao_strength: number(),
  bloom_strength: number(),
  bloom_threshold: number(),
  brightness: number(),
  contrast: number(),
  exposure: number(),
  fog_color: rgb(),
  fog_density: number(),
  gamma: number(),
  light_space: :linear | :display,
  light_table: {CauldronGPU.Handle.t(), number()} | nil,
  reflections: number(),
  render_scale: number(),
  shadow_distance: number(),
  sky_ground: rgb(),
  sky_horizon: rgb(),
  sky_picture: sky_picture(),
  sky_scroll: {number(), number()},
  sky_top: rgb(),
  tone_map: :aces | :neutral | :clamp
}