The renderer
Everything here comes from package:orblit_filament/orblit_filament.dart. A
scene is stated whole, every frame. See
stating a scene for why.
OrblitScene
Section titled “OrblitScene”| Field | What it is |
|---|---|
camera |
Where the view is, and its exposure. Required. |
objects |
Individually tracked things, each keyed and compared against last frame. Required. |
populations |
Bulk instanced things: a buffer of transforms, drawn 64 to a call |
splats |
Gaussian splat clouds, from a capture file or from memory. See splats |
sprites |
Layers of flat pictures, drawn after the solid scene. See 2D |
lights |
Directional, point and spot, in photometric units |
materials |
Shared material definitions, referred to by key from an object |
videos |
Video playing onto a surface |
sky |
The procedural sky |
fog |
Distance fog |
precipitation |
Rain and snow |
environment |
Image-based lighting and an HDRI skybox, baked or filtered from an .hdr or .exr while it runs |
pipeline |
Shadows, resolution, sampling, culling |
post |
Bloom, depth of field, grading, occlusion, vignette, tone mapping, anti-aliasing |
graph |
The passes, their targets, and the order they run in |
OrblitObject
Section titled “OrblitObject”| Field | Default | |
|---|---|---|
key |
required | Stable across frames, unique within the scene |
transform |
required | A Matrix4 |
colour |
required | A Vector3, used when no material is named |
mesh |
null | A path or resource name for a .gltf, .glb, .fbx or .obj. Null is the built-in cube. |
material |
null | The key of an entry in OrblitScene.materials |
castShadows |
true | |
receiveShadows |
true | |
visible |
true | Hidden is not deleted. The key and the loaded mesh are kept |
layer |
0 | Which render layer it belongs to |
animation |
null | One of the file’s own clips, and where it is. See models |
variant |
null | Which of the file’s material variants it wears, by position |
joints |
null | Skin joints set by hand, after any clip |
morphWeights |
null | How far each of the file’s morph targets is dialled in, 0 to 1 |
A mesh path that cannot be read is drawn as the cube, and the reason comes back
through OrblitView.onSceneNotes. What a file holds once it has loaded, meaning
its clips, skins, variants, lights and cameras, comes back through
OrblitView.onAssetInfo.
OrblitCamera
Section titled “OrblitCamera”| Field | Default | |
|---|---|---|
position, target |
required | Vector3 |
fieldOfView |
50 | Degrees. Ignored when orthographic. |
orthographic |
false | |
viewHeight |
10 | World units, when orthographic |
aperture |
16 | f-stop |
shutterSpeed |
1/125 | Seconds |
sensitivity |
100 | ISO |
The last three are a real exposure. Defaults are “sunny 16”, correct for a scene lit at 100,000 lux.
OrblitLight
Section titled “OrblitLight”| Field | Default | |
|---|---|---|
key, kind, intensity |
required | Lux for directional, lumens otherwise |
colour |
Vector3 |
|
position |
Point and spot | |
direction |
Directional and spot | |
falloffRadius |
10 | Metres. Also what lets a light be culled. |
innerConeAngle |
0.5 | Radians. Spot. Full brightness inside. |
outerConeAngle |
0.6 | Radians. Spot. Zero outside; the gap is the soft edge. |
sunAngularRadius |
0.263 | Degrees. The sun’s apparent size, so how soft its shadows are. |
sourceRadius |
0.1 | Metres. A larger source casts softer shadows. |
castShadows |
true |
Filament honours one directional light per scene. A second is reported back
rather than quietly ignored.
OrblitPopulation
Section titled “OrblitPopulation”| Field | |
|---|---|
key |
Required |
transforms |
Float32List, 16 floats each |
colours |
Float32List, 3 floats each |
minimum, maximum |
The bounds the whole population sits inside, so the lot can be culled at once |
mesh |
Optional; the built-in cube otherwise |
revision |
Bump it when the buffers change, so unchanged frames cost nothing |
castShadows |
Default false, since a hundred thousand shadow casters is rarely what anyone meant |
Measuring
Section titled “Measuring”final cost = await OrblitView.gpuMilliseconds(textureId);Milliseconds, not a frame rate. How often a frame is presented is the display’s business, and a renderer with twice the headroom it needs looks identical there. The value is the median of the last handful rather than the mean, because a mean is dragged about by the one frame in thirty that hits a hitch.
textureId comes from OrblitView.onViewport, which is called once with the
view’s own number.
Per-pass costs are available too, which is the point of declaring passes rather than hard-coding them: which passes ran, in what order, and what each cost are the three questions asked of a renderer that is too slow, and a fixed pipeline cannot answer any of them without being instrumented by hand every time somebody asks.
