Skip to content

Fixed camera: bake a view into a background with depth tiles - #234

Open
rixnobis wants to merge 14 commits into
mainfrom
baked-backgrounds
Open

rixnobis wants to merge 14 commits into
mainfrom
baked-backgrounds

Conversation

@rixnobis

Copy link
Copy Markdown
Contributor

A Fixed camera component for #200: aim it, press Bake, and the editor renders that view into a 320x240 background with depth tiles cut from the same render, so the player can pass in front of and behind the scenery. Static meshes in view go into the image and are hidden while it shows; objects with a script, or named in a script, are kept 3D. Collision, nav and triggers come from the scene as before.

The bake projects through the engine's fixed-point math, so in Redux the background lines up with the same view rendered in 3D (flat-colour scene: 0.44% of pixels differ, edges at shift 0,0), and its render time is 12662 against 73443. The inspector shows the VRAM the bake takes (512 KB at 16 bpp, 192 KB at 8 bpp for the courtyard view) and a warning at 50% of VRAM. tests/fixedcameracheck.py covers bake, Look through and export.

Needs #95 (pack v28); a scene without a baked Fixed camera exports v27 as before. Part of #200.

A Fixed camera's bake (a .bgbake beside its image and layer mask) is
exported as splashpack v28: the image as two sprite columns, each depth
layer as the 64x64 cells it covers, the camera as psxsplash's
world-to-view rows and the static meshes it hides. Scenes without one
stay v27. The export warns when the scene changed since the bake and
fails when the bake does not fit in VRAM.
Bake renders the static meshes from the camera with psxsplash's
projection at 320x240, cuts the depth layers (floors stay in the image)
and writes the bake files; the inspector shows the result and whether
the scene moved on since. Look through puts the viewport at the camera,
and a mesh can opt out with Keep 3D in fixed cameras.
The GPU draws an untextured triangle in its vertex colour and modulates
only texels (colour / 128); the shared shader doubles every colour, so
the bake drew untextured meshes twice as bright as the game. The
viewport keeps its look.
The engine floors at every GTE step (camera and object translation, the
composed rotation, RTPS), which puts a corner up to about 2.5 px up and
left of the exact projection; a bake drawn exactly missed the 3D frame
along every edge. Bake corners now go through the same integer path from
the exporter's encodings, land on whole pixels with the PS1 fill rule,
and only triangles the GTE cannot project (under H / 2) fall back to the
clip matrix.
A bake now keeps each pixel's occluder depth (.depth beside the image;
sky and floors have none) and the export cuts it per 16x16 cell into
tiles no deeper than half a metre, at most Layers a cell, packed into
cutout sheets. One depth per screen-wide band painted a band's far
pixels over a character standing inside it. Over 1024 tiles the
smallest are dropped with a warning; the inspector shows the tile count
and VRAM from the last export, and the bump allocator grows to fit.
The inspector line says what part of the 1 MB of VRAM the bake takes.
The pack test's second cell now spans 300 to 315, so a tile drawn at its
farthest depth instead of its nearest fails it.
A triangle with one corner the GTE cannot project went wholly through
the exact clip matrix while its neighbours were snapped to the engine's
whole pixels, so their shared edge sat in two places and cracked onto
the floor's dark underside (717 black pixels in the courtyard bake, 4
now). Deciding per corner gives shared edges the same two ends.
A static mesh whose name a scene, object or trigger script has in quotes
can be found with Entity.Find and moved, so it stays 3D: it is neither
baked nor hidden. The bake, the scene-changed hash and the export use
the same rule, and the inspector lists the meshes it kept and the
script that names each.
The inspector showed the texels (294 KB for the courtyard bake) where
the export takes whole 256-row atlases (512 KB, as --stats counts).
Problems warns when one background takes half of VRAM or more, which
at 16 bpp is all four atlases beside the framebuffers.
The viewport kept its 0.95 rad lens, so Look through framed more than
the bake. It now draws with the camera's H until the view is turned,
zoomed or framed; fixedcameracheck compares the clean viewport's edges
with the bake's.
Main brings blob shadows, which also took splashpack v28 and header
byte 156. This merge keeps both writers side by side: a scene with
shadows writes the shadow slot first, a baked background its own slot
after it, and the version stays 28 for either. The next commit moves
baked backgrounds to v29 so the two no longer share a version.
Mesh JSON keeps keep3dInFixedCameras next to the shadow keys.
Blob shadows own v28 and header byte 156, so a pack with a baked Fixed
camera is now v29 with a 164-byte header: the shadow table offset stays
at 156 (0 when the scene has no shadows) and the background table
offset is appended at 160. Scenes without a bake write v27 or v28 as
before. The format doc and splashdiff.py follow; the pack test checks
both slots, alone and with a blob shadow in the same scene.
@rixnobis

Copy link
Copy Markdown
Contributor Author

Moved to pack v29 to match #95: shadowTableOffset stays at byte 156, backgroundTableOffset is now at 160, header 164 (95e9a45, after merging main in f92c0ae). testFixedCameraPack checks both slots, with and without a blob shadow in the scene. A courtyard bake exported by this branch boots on the #95 engine with the background matching the bake image. This merges after #95.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant