Skip to main content

Module surface_style

Module surface_style 

Source
Expand description

Surface styles: WGSL of a game’s own, compiled into the engine’s forward shader.

A surface style is a type: its fields are the values its WGSL reads, its PASS is where its draws land in the frame, and its SURFACE and DISPLACE are the WGSL it runs. Name it in Game::SurfaceStyles through surface_styles!, draw with it through Instance::surface_style, and pass it its values with set_surface_style.

§What the engine declares

A style’s WGSL is compiled into the forward shader, which declares what each of the two is passed:

struct Surface {
    color: vec4<f32>,     // the base color, tint and texel together
    normal: vec3<f32>,    // world space, unit length
    emissive: vec3<f32>,  // the light this surface adds of its own
    world: vec3<f32>,     // where the fragment is, in world space
    uv: vec2<f32>,        // held within the draw's own frame window
}

struct Placed {
    world: vec3<f32>,     // where the transform placed this vertex
    normal: vec3<f32>,    // world space, unit length
    uv: vec2<f32>,        // the raw window, held within none
    local: vec3<f32>,     // where the mesh was built, in object space
}

The engine reads color, normal and emissive back from a Surface, and nothing else: world and uv are there to read. It lights by the normal as it is returned, so a style that turns one keeps it unit length.

§What a style declares

Either of the two, or neither:

fn surface(surface: Surface) -> Surface;   // SURFACE, fragment stage
fn displace(placed: Placed) -> vec3<f32>;  // DISPLACE, vertex stage

None on either leaves the engine’s own code there: a style with neither compiles and draws exactly as the built-in look does, which is what a style declared for its DrawPass alone is for. displace returns how far to move the vertex in world space.

A style’s values are bound as style, in a WGSL struct named after the Rust type. A style is Default because a frame that never passes it values draws with the default value of every field — where a PostEffect is not, since an effect no frame submits never runs at all.

A styled draw lands in its style’s own pass whatever its material holds. In DrawPass::Translucent the color.a a style returns is what the draw is blended over the frame by; in DrawPass::Cutout a returned color.a under 0.5 drops the texel, whatever the draw’s own material declares; in DrawPass::Additive the draw is added and that alpha is dropped.

A style may declare whatever else it needs beside the two: its own code, its own constant values, its own struct types. The forward shader it is compiled into declares over 100 names of its own, and declaring any of them again stops startup under the style’s name; the ones a style would reach for first are Surface, Placed, Fragment, surface_of, received, shading_of, scaled_by, held_inside, placed, columns, cofactor, unit, lit, shaded, dropped, styled, displaced, THRESHOLD, HALF, frame, lights, base_color, shading, relief and emissive_map. Every name the frame’s own sky declares starts with sky, sky_light and sky_reflection among them.

A game may name any number of styles, each one pipeline built at startup.

Enums§

DrawPass
The pass a style’s draws land in, and the way it draws them.
NoSurfaceStyles
The set of a game that draws with the built-in look alone.

Traits§

SurfaceStyle
A look of a game’s own, written in WGSL and stitched into the engine’s shader at startup.
SurfaceStyles
The styles one game draws with, named together as Game::SurfaceStyles.