Builtin Library
- ..
- README.md2.7 KB
- preview.png26.0 KB
- properties.yaml1.5 KB
- shader.wgsl13.4 KB
README.md
PBR Parallax Occlusion
Surface shader that extends the engine's Cook-Torrance PBR pipeline with
Parallax Occlusion Mapping. Per fragment it ray-marches a height texture
in tangent space, discards pixels whose intersection escapes the [0,1]
UV tile, softly fades a horizon margin so the discard isn't a hard step,
and runs a second short ray-march toward the directional light for
self-shadowing. The rest of the fragment shader is the standard PBR you get from
@builtin::shaders.standard — directional + point lights + their
shadows + procedural-sky IBL approximation — so a material using
this shader still receives full scene lighting.
Domain
surface — bind to a .material.
Files
shader.wgsl— vertex + fragment shader. Naga-validated.README.md— this file.
Texture slots
Standard PBR slots plus a sixth height_texture:
@group(1) binding | Slot name | Notes |
|---|---|---|
| 1/2 | base_color_texture | albedo |
| 3/4 | normal_texture | tangent-space normals |
| 5/6 | roughness_metallic_texture | G = roughness, B = metallic (glTF) |
| 7/8 | emissive_texture | optional emissive |
| 9/10 | occlusion_texture | optional AO |
| 11/12 | height_texture | R = depth into surface (0 = at face, 1 = deep) |
The engine reflects @group(1) bindings via naga and builds the bind-group layout per shader, so adding the sixth slot needs no Rust changes.
Parameters
The standard StandardMaterial uniform fields apply unchanged; the two
fields that drive POM are:
parallax_depth_scale: f32— max UV offset, in UV-space units. Useful range ~0.05–0.15. POM is gated on this being > 0 — set it to 0 and the shader degrades to plain textured PBR. It is also the width of the band the tile clip trims inward from the border of the [0,1] tile, since the march never offsets the UV further.max_parallax_layer_count: f32— ray-march iteration cap. 16 reads as stair-stepped at oblique angles; 48–64 is the smooth-quality band; 128 is the cost ceiling.
Notes
- Heightmap convention: black = at surface, white = deep. If you bring in a heightmap authored the other way (white = high), invert it in your import step or you'll get inside-out parallax.
- The vertex shader is the engine-standard one; the parallax effect is entirely in the fragment shader and uses no extra vertex attributes.
- The march runs in the forward
fragmententry point, so a material using this shader under a deferred camera renders as plain textured PBR. - For curved meshes, tangent-space POM produces mild distortion at high curvature. For roughly-planar surfaces (walls, floors, signs) it looks correct.