Package limn.render3d

Record Class Material.Surface

java.lang.Object
java.lang.Record
limn.render3d.Material.Surface
Record Components:
key - the program cache key; equal keys must mean equal outputs
outputs - the surface expressions, in the neutral IR
textures - named samplers the IR may reference, bound in order
values - named vec4 uniforms the IR may reference
blend - null for an opaque surface
All Implemented Interfaces:
Material
Enclosing interface:
Material

public static record Material.Surface(String key, SurfaceOutputs outputs, List<Material.Surface.Texture> textures, List<Material.Surface.Value> values, BlendMode blend) extends Record implements Material
A surface the application builds itself, out of the same neutral shader IR the built-in materials are generated from, and lit by the same core.

This is the difference from Material.Raw, and it is the whole point. Raw GLSL is a shortcut past the engine: it sees no lights, no shadow map, no environment, and it is one shading language forever. A Surface is spliced into the same main() the built-in metallic-roughness material is, so it reaches every light on the pass, the shadow map and the IBL, and it compiles to every TargetProfile the toolkit supports. What it replaces is only the four surface expressions: base colour, metallic, roughness and emissive, plus the shading normal.

Reach for it when the built-in material cannot express what a surface *is*: a sprite sheet cross-fading between two cells, an erosion driven by a mask, a scrolling flow map. Not for a different lighting model: the BRDF belongs to the engine, and a material that wanted its own would be describing a different renderer.

Inputs are named, and the names are the contract. Each Material.Surface.Texture and Material.Surface.Value is declared to the generated shader under its own name, and the surface's IR reaches it with an Expr.Ref carrying that name and the matching type. A name that is declared and never referenced is harmless; a name referenced and never declared fails to compile, which is the right moment to find out.

key identifies the program, not the material. Two surfaces with the same key must generate the same shader: the key is what the compiled program is cached under, and the values and textures are free to differ per draw. Getting this wrong shows up as a material silently rendering with another one's shader. Note it is deliberately not the record's identity: Material.Raw caches by identity, so an application that rebuilds its material record every frame links a fresh program every frame, and this must not repeat that.

Per-vertex data beyond position, normal, UV and colour reaches a surface through VertexAttribute.UV1, VertexAttribute.PARAMS and VertexAttribute.PARAMS1, as v_uv1, v_params and v_params1. The framework also declares v_worldPos, v_normal, v_uv and v_color. Fill PARAMS before reaching for PARAMS1: two half-used streams cost bandwidth one full one does not.

  • Constructor Details

  • Method Details

    • of

      public static Material.Surface of(String key, SurfaceOutputs outputs)
      An opaque surface with no inputs of its own.
    • with

      A copy with different inputs; the key and therefore the program are unchanged.
    • blend

      public Material.Surface blend(BlendMode blend)
      null restores opaque.
    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared with Objects::equals(Object,Object).
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • key

      public String key()
      Returns the value of the key record component.
      Returns:
      the value of the key record component
    • outputs

      public SurfaceOutputs outputs()
      Returns the value of the outputs record component.
      Returns:
      the value of the outputs record component
    • textures

      public List<Material.Surface.Texture> textures()
      Returns the value of the textures record component.
      Returns:
      the value of the textures record component
    • values

      public List<Material.Surface.Value> values()
      Returns the value of the values record component.
      Returns:
      the value of the values record component
    • blend

      public BlendMode blend()
      Returns the value of the blend record component.
      Specified by:
      blend in interface Material
      Returns:
      the value of the blend record component