CauldronGPU.Material (CauldronGPU v0.3.3)

Copy Markdown View Source

How a surface reflects light, in glTF's metallic-roughness terms.

Textures are CauldronGPU.Handles from CauldronGPU.texture/2, or nil.

  • base_texture multiplies base_color
  • metallic_roughness_texture multiplies roughness by its green channel and metallic by its blue
  • emissive_texture multiplies emissive (times emissive_strength)
  • normal_texture bends the surface normal by a tangent-space normal map (red right, green up), its sideways part scaled by normal_scale
  • occlusion_texture darkens ambient and reflected light by its red channel
  • lightmap replaces ambient light with baked light read at the vertices' lightmap coordinates, scaled by lightmap_scale; with lightmap_styles above 1 it holds that many slots side by side, slot k lit by the vertex's k-th light style (CauldronGPU.Mesh) at its brightness from {:light_styles, …}

Pixels whose base alpha is below alpha_cutoff are not drawn. alpha_mode: :blend draws the surface see-through by its base alpha, after the opaque scene, farthest instances first; it casts no shadow. :add adds its colour times its alpha to what is behind it, and :multiply multiplies what is behind it by its colour, as far as its alpha goes; both are drawn as :blend surfaces are. unlit surfaces show their base colour as is.

uv_scroll, {u, v} in repeats a second, moves the texture coordinates over time. uv_from: :reflection takes them from the view reflected in the surface instead of the mesh: with r the reflected direction, u = 0.5 - r.z / 2 and v = 0.5 - r.y / 2 (environment mapping); :mesh is the default. double_sided surfaces are drawn from behind too.

A sky surface shows the environment's sky (CauldronGPU.Environment) seen along the view through it, in place of its own colours; it casts no shadow, and rays that reach it see the sky. A warp surface's texture ripples: each texel is moved by up to 8 texels along sin(texel / 8 + seconds) of the other axis, as liquids do.

A surface with smear above 0 shows the finished picture behind it instead of its texture, times its base colour: the frame is cut into square blocks smear of its height tall, and each block shows the picture smear above or below it, the choice changing every frame. Its base texture's alpha below alpha_cutoff still cuts it out. It is drawn after the opaque scene, as see-through surfaces are.

Summary

Functions

The texture handles material uses.

Types

rgb()

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

t()

@type t() :: %CauldronGPU.Material{
  alpha_cutoff: number(),
  alpha_mode: :opaque | :blend | :add | :multiply,
  base_color: {number(), number(), number(), number()},
  base_texture: texture(),
  double_sided: boolean(),
  emissive: rgb(),
  emissive_strength: number(),
  emissive_texture: texture(),
  lightmap: texture(),
  lightmap_scale: number(),
  lightmap_styles: 1..4,
  metallic: number(),
  metallic_roughness_texture: texture(),
  normal_scale: number(),
  normal_texture: texture(),
  occlusion_texture: texture(),
  roughness: number(),
  sky: boolean(),
  smear: number(),
  unlit: boolean(),
  uv_from: :mesh | :reflection,
  uv_scroll: {number(), number()},
  warp: boolean()
}

texture()

@type texture() :: CauldronGPU.Handle.t() | nil

Functions

textures(material)

@spec textures(t()) :: [CauldronGPU.Handle.t()]

The texture handles material uses.