Builtin Library
- ..
- README.md2.8 KB
- preview.png20.1 KB
- properties.yaml728 B
- shader.wgsl4.5 KB
README.md
ps1
A full PS1-style retro shader and a worked example of a self-shading
fragment() shader — one that returns the final pixel itself instead of
describing a PBR surface. It emulates the three signature traits of original
PlayStation hardware, each mapped onto a generic engine capability:
- Vertex snapping (
vertex_clip) — the integer-grid vertex wobble, snapping NDC xy to a low-res grid set bysnap_resolution(low = chunkier). - Per-vertex (Gouraud) lighting (
vertex_clipwritesClipVertex.color) — the PS1 lit at vertices and the rasterizer interpolated the colour; there was no per-pixel lighting. The shader computes Lambert sun + ambient from the world normal at each vertex and writes it into the vertex colour, which the engine forwards into the interpolatedvertex_colorthe fragment reads. Flat, gradient-banded shading — never a per-pixel highlight. - Affine texture mapping (
FragmentData.affine_uv) — the PS1 had no perspective-correct UV interpolation, so textures "swim" / warp across triangles. We sample with the engine's non-perspective-correctaffine_uvchannel instead ofuv, reproducing the warp exactly.
On top of those: the texture is quantized to a tex_resolution×tex_resolution
texel grid (the PS1 256×256 texture page) and the final colour is run through a
4×4 Bayer ordered dither + colour-level quantization (the PS1 banded look). No
shadow-map sampling — the PS1 had none.
Properties
| Property | Type | Default | Meaning |
|---|---|---|---|
base_color | color | [1,1,1,1] | Tint multiplied into the texture. |
snap_resolution | float | 160 | Vertex-snap grid resolution (lower = chunkier wobble). |
tex_resolution | float | 256 | Texture sampled at tex_resolution×tex_resolution texels (PS1 256×256 page). |
dither_amount | float | 0.06 | Strength of the Bayer dither applied before quantization. |
color_levels | float | 16 | Number of quantization levels per channel (lower = more banding). |
base_color_texture | texture (white) | — | Albedo texture, sampled affinely in fragment(). |
Framework capabilities this exercises
ClipVertexis a post-transform vertex-shading hook: it carries world-space geometry (world_normal,world_position) and the sun/ambient light context, and writing itscolorfield performs per-vertex (Gouraud) shading — the engine forwards it to the interpolatedvertex_color. Leavecoloruntouched and the mesh's per-vertex colour passes through.FragmentData.affine_uvis the primary UV interpolated without perspective correction — always available alongside the perspective-correctuv. Sample with it for the PS1 swim; sample withuvfor normal mapping.