mirror of
https://github.com/DramaticShape/DramaticShapeVoxelMod.git
synced 2026-08-12 09:50:50 +02:00
update readme, mod card
This commit is contained in:
+349
-375
@@ -1,6 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## 1.0.0
|
||||
|
||||
First release, ported from the engine-internal voxel branch onto the
|
||||
`render_pipelines` mod API.
|
||||
|
||||
Interior furniture gets the shapes it depicts
|
||||
(mods/DRAMATIC_SHAPE/tools/voxel-survey.md is the procedure that found and
|
||||
verified these).
|
||||
|
||||
Buildings stop being boxes wearing their own elevation. A profiled
|
||||
building is voxelized from its own sprite, band by band -- the pipeline
|
||||
written up in `assets/docs/buidling_to_voxel/`.
|
||||
|
||||
Terrain meshing goes asynchronous, instanced and bounded. The first voxel
|
||||
frame used to build every neighbourhood map synchronously (a ~2.4s
|
||||
freeze), retain every map's analysis forever (gigabytes over a
|
||||
cross-region trek), and string stray pixels along map seams.
|
||||
|
||||
Real shadows. The sun moves to the southeast and drops to 45 degrees, so
|
||||
shadows fall northwest -- up and to the left on screen -- and run about as
|
||||
@@ -8,6 +24,136 @@ long as the thing throwing them is tall.
|
||||
|
||||
### Added
|
||||
|
||||
- `voxel` render pipeline: 3D diorama overworld with extruded terrain,
|
||||
depth-buffered occlusion, leaning sprite billboards, drop shadows and
|
||||
contact AO. VOXEL options row and hotkey `3` (OFF / 15 / 35 / 50 / 75).
|
||||
- `tiltshift` render pipeline: a `worldPresent` post-process giving the
|
||||
miniature-photo look. T-SHIFT options row and hotkey `6` (OFF / 1 / 2 / 3).
|
||||
- Carved voxel models for 67 overworld sprites, plus the
|
||||
`tools/build_voxels.py` that produced them.
|
||||
- `data/voxel_heights.lua`, the hand-authored tile shape profile.
|
||||
|
||||
- Furniture shape classes in the profile: `bed` (a low slab wearing its
|
||||
top-down art), `table` and `desk` (boxes at their drawn height whose
|
||||
faces fold the artwork up), `relief` (a prop drawn from above -- a
|
||||
game console -- lying flat and extruding a few voxels inside its
|
||||
outline), the standee pools `billboard` (10px) / `prop` (5px) /
|
||||
`stool` (5px, and characters standing on its walkable cell sit at
|
||||
seat height) / `cutout` (one voxel: pure profile, for the vase on the
|
||||
table), and the stair archetypes `stair_e`/`stair_w` (a rising flight
|
||||
of real steps) and `stair_down_e`/`stair_down_w` (a sunken stairwell
|
||||
descending below the floor -- stairs that lead down). Separate pools
|
||||
cluster separately, so touching drawings never merge into one cutout.
|
||||
- Standee clusters split into per-pixel connected components, each
|
||||
standing on its own feet in the depth band of the row it is drawn in:
|
||||
two stools stacked in adjacent cells become two stools, and no
|
||||
fragment of a drawing ever floats at its bounding-box height. A
|
||||
`cutout` keeps only its largest component -- a cast shadow's drawn
|
||||
edge is background, not a floating scrap.
|
||||
- `bookcase` class: free-standing shelf drawings collapse in ranks onto
|
||||
one-cell-deep boxes at their full drawn height, back rows becoming
|
||||
hidden floor; the trim row above a rank -- undetected structure or a
|
||||
row pinned `table`, since the same trim tiles cap other furniture --
|
||||
is adopted as its cap. Pinned for Oak's Lab (`DOJO`).
|
||||
- Oak's Lab tables pinned `table`: the starter-ball display and the
|
||||
north tables stand at real table height, the display frame's black
|
||||
corner brackets no longer auto-extract into standing prisms, and the
|
||||
Poke Ball / Pokedex sprites ride the authored height onto the
|
||||
tabletops.
|
||||
- Pinned props drawn directly above a pinned box stand ON it: the PC
|
||||
monitor on its desk, the flower pot on the dining table.
|
||||
- Profile pins for `REDS_HOUSE_1` / `REDS_HOUSE_2` (Red's house and the
|
||||
Copycat's, both floors): bed, stools, tables, PC desk with its
|
||||
standing monitor, bookcases, TV standing on the floor behind the game
|
||||
console's relief, potted plant, flower pot, both staircases, and the
|
||||
wall/window band.
|
||||
- `mods/DRAMATIC_SHAPE/tests/voxel_survey.lua`: screenshot-survey driver
|
||||
behind the repeatable inspection procedure (SURVEY_MAP / SURVEY_SPOTS /
|
||||
SURVEY_LEVELS / SHOT_DIR), documented in
|
||||
mods/DRAMATIC_SHAPE/tools/voxel-survey.md.
|
||||
|
||||
- `lib/Buildings.lua`: a building archetype. Where the volume path folds a
|
||||
whole drawing upright (roof, facade and sloped ends alike) into one box,
|
||||
this classifies each BAND of the drawing by the 3D surface it depicts and
|
||||
applies the matching operation: top-facing rows lay flat over the
|
||||
footprint, the facade extrudes straight back, an awning band juts past
|
||||
the walls, and the drawn taper at the ends becomes a stepped slope in
|
||||
elevation. Every visible voxel carries a real texel of the drawing, so
|
||||
the model recolours with the atlas.
|
||||
- A `buildings` section in `data/voxel_heights.lua`. A building is matched
|
||||
by its exact tile grid (the drawings are catalogued in `assets/docs/buildings/`),
|
||||
so one entry covers every map that places the same art -- Red's house,
|
||||
Blue's house, Bill's, the Copycat's and the two Fuchsia houses are one
|
||||
seven-placement entry, and Oak's lab is a second. Only the band table is
|
||||
authored; the silhouette, the taper rate, the eave height and every
|
||||
window and doorway are measured off the pixels.
|
||||
- The flat-roofed civic block and its sixteen relatives -- every Pokemon
|
||||
Center and every Poke Mart, Fuchsia Gym, the museum, the Game Corner,
|
||||
Celadon Mansion and its department store, the Power Plant, the Route 5
|
||||
and Route 22 gates, Silph Co and five anonymous scenery blocks. They are
|
||||
one architecture drawn at eleven different footprints, from 4x4 cells up
|
||||
to Silph Co's 8x12, and they share one band table: their lattice is drawn
|
||||
from straight above, so the measured taper comes out flat and the whole
|
||||
band is depth under one level roof. No new roof mode was needed -- the
|
||||
drawn profile was always the shape, and a drawing with no taper simply
|
||||
yields a level one.
|
||||
- Pewter's museum hall (`assets/docs/buildings/B24`). It is the one
|
||||
sloped-roof building in this pass, and the only one so far whose roof
|
||||
texture is not a plain repeat: the drawing states its own period by
|
||||
repeating the whole lattice-and-course motif, rows 8..31 again at 32..55,
|
||||
so the cycle is 24 rows and the roof carries its drawn courses across the
|
||||
depth instead of a bare lattice. The band below them is the roof's
|
||||
fascia, wider than the wall it covers, so it belongs to the roof and
|
||||
lands on the south rim. Note the museum is TWO drawings: this hall and
|
||||
the east entrance beside it, which is B18 and shares its drawing with the
|
||||
Route 2 gate.
|
||||
- The rest of the 2:1 sloped-roof buildings: both gym drawings (the
|
||||
standard one at Cinnabar, Pewter, Vermilion and Viridian plus the
|
||||
Fighting Dojo, and the wider Celadon / Cerulean / Saffron one), the 4x2
|
||||
cottage that houses Mr Fuji, the Cubone house, Bill's grandpa, the Name
|
||||
Rater and the Viridian school, Cerulean's three wide houses, the day
|
||||
care, and three scenery blocks -- among them B01, which at 19 placements
|
||||
is the commonest drawing in the game. Each one's roof band is pixel for
|
||||
pixel one of the three already authored, so they take that sibling's band
|
||||
table unchanged: 16 rows for Red's house's, 32 for Oak's lab's, 64 for
|
||||
the museum's.
|
||||
- The Safari Zone rest houses and the Victory Road entrance, the first
|
||||
buildings outside the `OVERWORLD` tileset -- `buildings` is keyed by
|
||||
tileset and until now only had the one section. The rest house's
|
||||
corrugated roof repeats every 5 rows rather than the overworld lattice's
|
||||
8, which is the point of `roofCycle` being authored per building.
|
||||
- Route 10's scenery block, via a new `seal` field. Its drawing has no
|
||||
black base course -- it ends on a row of light brick -- so the silhouette
|
||||
flood climbed in from the south border through the mortar and hollowed
|
||||
the wall out, leaving 72% of the sprite in 65 pieces. `seal` names the
|
||||
sides a drawing runs off rather than closing, and the flood does not seed
|
||||
there: sealed, it is 95% in one piece, and the model is its twin the
|
||||
museum's. No other building sets it, and none changes by a voxel.
|
||||
- Together these take the mod to 31 of the catalogue's 34 drawings and 144
|
||||
of its 147 placements. The last three, and why each resists, are written
|
||||
up in `assets/docs/buildings/REMAINING.md`.
|
||||
- A roof no longer runs past the drawing's own silhouette. These sprites
|
||||
are inset from their boxes, and the columns outside the inset carry no
|
||||
roof: they now get none, and the fascia belongs to the outermost columns
|
||||
the drawing actually paints. Before, they raised a four-voxel slab of
|
||||
black kerb the full depth of the building, flanking its walls at ground
|
||||
level. Nothing shipped hit this -- Red's house and Oak's lab are drawn
|
||||
edge to edge -- so no existing model changes by a single voxel.
|
||||
- Windows and doorways sink a voxel behind their frames, found rather than
|
||||
listed: a pane is a non-black region the drawing seals off behind its own
|
||||
black outline. A nested frame (the door's own little window) layers for
|
||||
free.
|
||||
- `tools/building_voxels.py`: the reference implementation of the same
|
||||
algorithm, with the geometric asserts and isometric previews Stage 5 of
|
||||
the methodology calls for. It and the runtime agree exactly on voxel and
|
||||
shell counts for all 19 templates -- 96,617 / 12,866 for Red's house up
|
||||
to 3,715,963 / 146,762 for Silph Co, which ship as 3,410 and 13,994
|
||||
quads. Its slope asserts read the drawn columns only and stand down for a
|
||||
roof with no taper, where the check is that the roof is level instead;
|
||||
its previews fit the projection to the model rather than to a fixed
|
||||
camera, so a building taller or deeper than the first two still lands on
|
||||
the canvas.
|
||||
|
||||
- A sky at the 75-degree rung. Pitched that far over, the horizon comes
|
||||
into frame and a good part of the picture is void, so the void gets
|
||||
filled instead of reading as the black plate it does at every rung below.
|
||||
@@ -30,12 +176,12 @@ long as the thing throwing them is tall.
|
||||
- The mod's four controls sit on adjacent keys, and the two that never had
|
||||
one now have a hotkey at all:
|
||||
|
||||
| key | control | was |
|
||||
| --- | --- | --- |
|
||||
| 3 | VOXEL, the camera ladder | 6 |
|
||||
| 5 | V-GRID, the wireframe | menu only |
|
||||
| 6 | T-SHIFT, the blur ladder | 9 |
|
||||
| 7 | V-CURVE, the horizon bend | menu only |
|
||||
| key | control |
|
||||
| --- | --- |
|
||||
| 3 | VOXEL, the camera ladder |
|
||||
| 5 | V-GRID, the wireframe |
|
||||
| 6 | T-SHIFT, the blur ladder |
|
||||
| 7 | V-CURVE, the horizon bend |
|
||||
|
||||
Only 6 arrives by the documented route. `Game:keypressed` answers the
|
||||
engine's own display keys first and returns -- 2 COLORS, 3 TILT, 4 ZOOM,
|
||||
@@ -160,8 +306,203 @@ long as the thing throwing them is tall.
|
||||
whatever the player left in `options.lua`, and the world view size (which
|
||||
the light frustum is fitted to) swings 3x across that range.
|
||||
|
||||
- A `counter` class (8px, upright): half-cell furniture. One 8px band,
|
||||
so exactly the drawing's bottom row stands up as the front and every
|
||||
row above it rides the top face in drawn order. `table`'s 12px could
|
||||
not be retuned for it; the houses share that class.
|
||||
|
||||
- `tilesets.POKECENTER` in `data/voxel_heights.lua`. Before it, the
|
||||
detector merged the wall-touching counters and healing machines into
|
||||
the wall band and towered them 3-6 blocks, flattened the machines'
|
||||
near-black screens to void, read the pillar bases, plant pots and
|
||||
machine bodies as ponds (the $14/$32/$48 stale-cache water fallback),
|
||||
boxed each plant pair into one hedge cube, and extruded the lounge
|
||||
seat -- a PERSON is drawn into its tile art -- into a monolith wearing
|
||||
his face.
|
||||
- The pins, by shape: the wall band, windows, poster, pillars and the
|
||||
16px machine bodies are `wall`; the counters (with the nurse's tray)
|
||||
are `counter` and the PC's desk is `table`; the machine screens and
|
||||
the PC are `billboard`, standing on the pinned boxes below them; the
|
||||
potted plants are `prop` standees like every other interior plant.
|
||||
- The lounge couch with the man sitting on it is a `counter` box: its
|
||||
bottom row stands up as the couch's front and the cushion and the man
|
||||
ride the top face, each drawn exactly once.
|
||||
He cannot be stood upright, and the reason is structural rather than a
|
||||
tuning question. His skin pixels span two tile rows and stop dead at
|
||||
the row 9/10 seam; folding two rows upright requires both to share a
|
||||
class, which makes the box two tiles deep, and a fully folded box
|
||||
repeats its north row across its whole top face. So every upright
|
||||
arrangement puts his head on screen two or three times -- as a 16px
|
||||
seat-back, on the front and twice more on the top; as a 32px bookcase,
|
||||
a cabinet taller than the room's own walls. Dropping the seat in front
|
||||
of him to floor level only changes which copy you see. Nor can he be a
|
||||
standee: the drawing has no floor margin, so all three non-black
|
||||
shades touch the cluster rim and the mask drains 307 of its 420
|
||||
interior pixels -- 46% of him even segmented alone, because his skin
|
||||
is the same light shade as the couch behind him.
|
||||
- Survey evidence: full before/after passes of VIRIDIAN_POKECENTER at
|
||||
15/35/50 degrees, plus spot-checks of CELADON_POKECENTER and
|
||||
CELADON_HOTEL (shared tileset, both inherit correctly) and of
|
||||
REDS_HOUSE_1F, OAKS_LAB and VIRIDIAN_CITY (unchanged -- the new class
|
||||
is additive and no other tileset lists it).
|
||||
|
||||
### Changed
|
||||
|
||||
- Pinned props are segmented the way the art is authored: objects wear a
|
||||
black outline, so background is the shades touching the cluster's edge
|
||||
(white floor around a TV, grey tabletop around a vase) flooded in from
|
||||
the aprons; the outline, its interior, paint whites and anything they
|
||||
enclose survive -- pixel-perfect cutouts on any surface.
|
||||
- Indoor structure analysis floods background from all four aprons and
|
||||
accepts ground contact on any side (outdoors keeps the south-only rule
|
||||
that protects roofs), so face-on furniture drawings voxelize per pixel
|
||||
instead of rising as wall-height volumes.
|
||||
- Profile-pinned standees are 10px deep (detected props stay 6px), so a
|
||||
deliberate object like a TV keeps a body at shallow camera angles.
|
||||
- Authored upright boxes fold their artwork up every face (flanks and
|
||||
back wear the front stack darkened) and top faces keep the drawn
|
||||
tabletop: face-on rows wear the row above the fold instead of
|
||||
repeating their front art lying flat, and a run that folded entirely
|
||||
tops with the furniture row drawn above it (a bookcase's shelf trim).
|
||||
- Characters no longer ride a pinned stair tile's class height: stairs
|
||||
are walked through at floor level, fixing the step-up onto thin air in
|
||||
front of stairwells.
|
||||
|
||||
- A voxelized building is as tall as its facade plus its roof slab rather
|
||||
than as tall as its drawing: the roof rows are DEPTH now, not height, so
|
||||
Red's house is 36px over a 4x3-cell plot instead of a 48px cube.
|
||||
- Round trees (the `cylinder` pin: lone canopies and the border tree
|
||||
wall) stop being lathes -- the sprite wrapped around a 12-segment
|
||||
column read as exactly that, art smeared on a barrel. Each cell is now
|
||||
a real voxel hull: the canopy is segmented out of its cell as the
|
||||
darkest-pixel outline plus everything it encloses (which also drops
|
||||
the background grass that used to inflate every row to full width, and
|
||||
the cast shadow under the ball), and each mask row runs its own span's
|
||||
circular chord in depth -- the front view is the sprite pixel for
|
||||
pixel, the plan view is the sprite's width profile turned in depth.
|
||||
Dithered art with no closed outline (the tree wall) falls back to
|
||||
light-shades-only flooding, per the methodology doc's boundary rule.
|
||||
Sides de-outline like building extrusions so flanks read as canopy
|
||||
rather than solid black, and dome caps keep their outline on the rim
|
||||
while the interior samples the canopy a couple of rows deeper.
|
||||
- A `post` standee pool, pinned for the overworld's vertical fence-post
|
||||
cell (tiles 14/85 -- across every map the pair appears only as this
|
||||
cell). The detector already turns HORIZONTAL fence runs (tile 57) into
|
||||
per-post standees, but a vertical run of repeated cells trips its
|
||||
scenery-repetition guard and fell to the volume path as a
|
||||
fence-textured tower (Viridian's west line, Route 25).
|
||||
`post` extracts every CELL as its own cluster -- pooled clustering
|
||||
would stand the whole line up as one drawing-tall slab at one depth --
|
||||
and classifies pixels the way the detector does (non-white is body)
|
||||
rather than by the pinned-prop outline rule, which would strip the
|
||||
posts to black skeletons; at the detector's own 6px depth, pinned and
|
||||
detected fences look alike.
|
||||
- Town signs move from the `billboard` pool to a new `signpost` pool: the
|
||||
same per-pixel standing slab, but 2 voxels thin instead of 10. A sign
|
||||
is a plate on a stick, and the standee body that keeps a TV from
|
||||
vanishing at shallow angles read as a solid block of furniture here.
|
||||
- The ground under a round tree matches the tree's own drawn background
|
||||
instead of the map's commonest ground tile. The hull's segmentation
|
||||
already knows which pixels are NOT the tree; those pixels are scored
|
||||
against every flat ground tile the map places and the closest art
|
||||
wins, per template -- so border trees drawn over checker grass stand
|
||||
on checker grass even on a map that is mostly pale path (the old
|
||||
fallback painted path under every mid-forest tree, which has no flat
|
||||
neighbour to vote with). The drawn cast shadow stays out of the score:
|
||||
no ground tile carries a shadow, and its darks would drag every match.
|
||||
|
||||
- Mesh builds stream in the background. `ChunkMesher` queues per-map
|
||||
build jobs and `pump()` -- driven from the pipeline's update -- runs
|
||||
them inside a few-millisecond frame budget (`lib/BuildBudget.lua`
|
||||
suspends the build coroutine mid-loop when the slice is spent). The
|
||||
camera tween holds at flat until the current map's terrain exists, so
|
||||
toggling voxel mode shows a handful of flat frames instead of a frozen
|
||||
one; neighbours pop in as they finish. Warp fades prefetch the
|
||||
destination (the pipeline update ticks while the Transition covers the
|
||||
screen, with a wider pump slice), so a door exit lands on terrain that
|
||||
is already built.
|
||||
- Vertex packing goes through FFI into one native buffer
|
||||
(`Mesh:setVertices(ByteData)`) instead of a Lua table per vertex --
|
||||
the headless table path remains for the pure `geometry()` API and its
|
||||
suite.
|
||||
- Round-tree hulls are carved once per (tileset, art, ground set) and
|
||||
kept as stamps -- template plus cell offset, expanded during vertex
|
||||
packing -- instead of materialized per-cell quad tables. A route's
|
||||
border forest was ~500 quads x hundreds of cells of retained heap.
|
||||
- Mesh and analysis caches evict down to the live neighbourhood (current
|
||||
map + rendered neighbours, plus one set of history so a house
|
||||
round-trip keeps the town warm). Evicted meshes are released
|
||||
explicitly. Memory over Pallet -> Mt Moon: was ~2.9GB and monotonic,
|
||||
now oscillates between ~90 and 200MB.
|
||||
|
||||
- `Voxel3D.SHADOW_KX/KZ` are -0.85 / -0.55, from +0.30 / +0.45: the sun
|
||||
crosses to the southeast and drops from 62 degrees to 45. The bearing
|
||||
leans WEST of northwest on purpose -- a character is drawn as a slab
|
||||
leaning away from the camera, which covers the ground due north of its
|
||||
feet, so a shadow thrown straight up-screen lands entirely underneath
|
||||
the figure casting it and is never seen.
|
||||
- `Voxel3D.SHADOW_ALPHA` 0.32 -> 0.40, a quarter darker.
|
||||
- `FACE_SHADE` east 0.78 -> 0.84 and west 0.78 -> 0.72. The two were equal
|
||||
because the old sun sat due northwest and they were symmetric about it;
|
||||
under a southeastern sun east is a lit flank and west a shaded one.
|
||||
- A character's shadow lookup runs off the UPRIGHT card the sun saw, not
|
||||
the leaning slab the camera sees (`Voxel3D.draw`'s `sunModel`). Casting
|
||||
the leaning slab instead would shrink every shadow to nothing as the
|
||||
camera flattened toward top-down; looking up with the leaned position
|
||||
put each sprite's own card across its front.
|
||||
- The contact-shadow term in `ChunkMesher` was a one-directional stripe
|
||||
keyed to a northwestern sun -- two neighbours, one corner, top faces
|
||||
only. It is now the ambient occlusion above.
|
||||
- The light frustum is fitted to the ground the CAMERA CAN SEE rather than
|
||||
to a view-sized box around the focus, and both of its margins are now
|
||||
asymmetric -- for opposite reasons. The camera sits south of its focus
|
||||
and looks north, so the ground it sees runs far north and barely south;
|
||||
the sun sits southeast, so the casters for that ground stand south and
|
||||
east of it. Paying for a view-sized box plus caster margin on all four
|
||||
sides covered about a third of what was on screen at 75 degrees, and
|
||||
overpaid at 15.
|
||||
- Shadows ease off at the frustum's rim instead of ending on it. Past the
|
||||
low rungs the horizon is further out than any box worth paying for, and
|
||||
a covered region that simply stops draws a hard line across the middle
|
||||
distance where every shadow ends at once.
|
||||
|
||||
The Pokemon Center interiors. One `POKECENTER` group in
|
||||
`data/voxel_heights.lua` plus one new class, and because
|
||||
VIRIDIAN_POKECENTER places every tile the tileset's other maps use, the
|
||||
one pin set covers all eleven Centers and the Celadon Hotel.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The generic town-house tileset (`HOUSE` -- Blue's house, Daisy at her
|
||||
table, and eighteen more homes, the schoolhouse and the trashed house
|
||||
among them) is now pinned in `data/voxel_heights.lua` the way Red's
|
||||
rooms already were: the dining table stops towering as a wall-height
|
||||
volume and sits at table height with its front folded upright, stools
|
||||
become seat-high boxes that characters sit on, the corner potted
|
||||
plants become per-pixel standees instead of texture-smeared box
|
||||
stacks, the bookcases get clean capped tops, and the wall band (with
|
||||
its window, picture and the schoolhouse blackboard) stays one 16px
|
||||
face. The schoolhouse's open book stands on the pinned tabletop as a
|
||||
cutout, and the trashed house's ransacked table corner keeps table
|
||||
height.
|
||||
- Interior door mats lie flat again in Red's and the generic houses.
|
||||
Their collision tile is $14, which the engine's stale-cache fallback
|
||||
counts as water in every tileset, so the rug recessed into a pond lip;
|
||||
a `ground` pin now overrides the water read.
|
||||
|
||||
- Stray pixels along map seams: ring props (border-tree hulls) whose
|
||||
quad CENTER sat exactly on a neighbour body's edge line escaped the
|
||||
strict point-in-rect mask and survived as fragments of otherwise
|
||||
dropped trees. Object quads now keep/drop by their full extent,
|
||||
boundary inclusive; props straddling the body edge also stay whole
|
||||
instead of shedding their outer half.
|
||||
- The one-step "ledge hop" when crossing a connection into a tree-ringed
|
||||
map: the seam step stands the player one cell off the new map, where
|
||||
`Map:cellTile` border-extends into the borderBlock -- a raised tile on
|
||||
maps ringed with trees. Off-map ground now reads as height 0 (the
|
||||
departed neighbour's flat walkway, which is what is actually rendered
|
||||
there).
|
||||
|
||||
- Cycling palette modes with voxel mode on eventually killed the pipeline
|
||||
outright: `attempt to call field 'atlasImageData' (a nil value) --
|
||||
disabled for this session`. Nothing brought it back short of a restart.
|
||||
@@ -297,373 +638,6 @@ long as the thing throwing them is tall.
|
||||
Nothing showed the fault until the voxel wireframe drew the grid those
|
||||
pixels were supposed to be sitting on.
|
||||
|
||||
### Changed
|
||||
|
||||
- `Voxel3D.SHADOW_KX/KZ` are -0.85 / -0.55, from +0.30 / +0.45: the sun
|
||||
crosses to the southeast and drops from 62 degrees to 45. The bearing
|
||||
leans WEST of northwest on purpose -- a character is drawn as a slab
|
||||
leaning away from the camera, which covers the ground due north of its
|
||||
feet, so a shadow thrown straight up-screen lands entirely underneath
|
||||
the figure casting it and is never seen.
|
||||
- `Voxel3D.SHADOW_ALPHA` 0.32 -> 0.40, a quarter darker.
|
||||
- `FACE_SHADE` east 0.78 -> 0.84 and west 0.78 -> 0.72. The two were equal
|
||||
because the old sun sat due northwest and they were symmetric about it;
|
||||
under a southeastern sun east is a lit flank and west a shaded one.
|
||||
- A character's shadow lookup runs off the UPRIGHT card the sun saw, not
|
||||
the leaning slab the camera sees (`Voxel3D.draw`'s `sunModel`). Casting
|
||||
the leaning slab instead would shrink every shadow to nothing as the
|
||||
camera flattened toward top-down; looking up with the leaned position
|
||||
put each sprite's own card across its front.
|
||||
- The contact-shadow term in `ChunkMesher` was a one-directional stripe
|
||||
keyed to a northwestern sun -- two neighbours, one corner, top faces
|
||||
only. It is now the ambient occlusion above.
|
||||
- The light frustum is fitted to the ground the CAMERA CAN SEE rather than
|
||||
to a view-sized box around the focus, and both of its margins are now
|
||||
asymmetric -- for opposite reasons. The camera sits south of its focus
|
||||
and looks north, so the ground it sees runs far north and barely south;
|
||||
the sun sits southeast, so the casters for that ground stand south and
|
||||
east of it. Paying for a view-sized box plus caster margin on all four
|
||||
sides covered about a third of what was on screen at 75 degrees, and
|
||||
overpaid at 15.
|
||||
- Shadows ease off at the frustum's rim instead of ending on it. Past the
|
||||
low rungs the horizon is further out than any box worth paying for, and
|
||||
a covered region that simply stops draws a hard line across the middle
|
||||
distance where every shadow ends at once.
|
||||
|
||||
The Pokemon Center interiors. One `POKECENTER` group in
|
||||
`data/voxel_heights.lua` plus one new class, and because
|
||||
VIRIDIAN_POKECENTER places every tile the tileset's other maps use, the
|
||||
one pin set covers all eleven Centers and the Celadon Hotel.
|
||||
|
||||
### Added
|
||||
|
||||
- A `counter` class (8px, upright): half-cell furniture. One 8px band,
|
||||
so exactly the drawing's bottom row stands up as the front and every
|
||||
row above it rides the top face in drawn order. `table`'s 12px could
|
||||
not be retuned for it; the houses share that class.
|
||||
|
||||
- `tilesets.POKECENTER` in `data/voxel_heights.lua`. Before it, the
|
||||
detector merged the wall-touching counters and healing machines into
|
||||
the wall band and towered them 3-6 blocks, flattened the machines'
|
||||
near-black screens to void, read the pillar bases, plant pots and
|
||||
machine bodies as ponds (the $14/$32/$48 stale-cache water fallback),
|
||||
boxed each plant pair into one hedge cube, and extruded the lounge
|
||||
seat -- a PERSON is drawn into its tile art -- into a monolith wearing
|
||||
his face.
|
||||
- The pins, by shape: the wall band, windows, poster, pillars and the
|
||||
16px machine bodies are `wall`; the counters (with the nurse's tray)
|
||||
are `counter` and the PC's desk is `table`; the machine screens and
|
||||
the PC are `billboard`, standing on the pinned boxes below them; the
|
||||
potted plants are `prop` standees like every other interior plant.
|
||||
- The lounge couch with the man sitting on it is a `counter` box: its
|
||||
bottom row stands up as the couch's front and the cushion and the man
|
||||
ride the top face, each drawn exactly once.
|
||||
He cannot be stood upright, and the reason is structural rather than a
|
||||
tuning question. His skin pixels span two tile rows and stop dead at
|
||||
the row 9/10 seam; folding two rows upright requires both to share a
|
||||
class, which makes the box two tiles deep, and a fully folded box
|
||||
repeats its north row across its whole top face. So every upright
|
||||
arrangement puts his head on screen two or three times -- as a 16px
|
||||
seat-back, on the front and twice more on the top; as a 32px bookcase,
|
||||
a cabinet taller than the room's own walls. Dropping the seat in front
|
||||
of him to floor level only changes which copy you see. Nor can he be a
|
||||
standee: the drawing has no floor margin, so all three non-black
|
||||
shades touch the cluster rim and the mask drains 307 of its 420
|
||||
interior pixels -- 46% of him even segmented alone, because his skin
|
||||
is the same light shade as the couch behind him.
|
||||
- Survey evidence: full before/after passes of VIRIDIAN_POKECENTER at
|
||||
15/35/50 degrees, plus spot-checks of CELADON_POKECENTER and
|
||||
CELADON_HOTEL (shared tileset, both inherit correctly) and of
|
||||
REDS_HOUSE_1F, OAKS_LAB and VIRIDIAN_CITY (unchanged -- the new class
|
||||
is additive and no other tileset lists it).
|
||||
|
||||
## 1.3.0
|
||||
|
||||
Terrain meshing goes asynchronous, instanced and bounded. The first voxel
|
||||
frame used to build every neighbourhood map synchronously (a ~2.4s
|
||||
freeze), retain every map's analysis forever (gigabytes over a
|
||||
cross-region trek), and string stray pixels along map seams.
|
||||
|
||||
### Changed
|
||||
|
||||
- Mesh builds stream in the background. `ChunkMesher` queues per-map
|
||||
build jobs and `pump()` -- driven from the pipeline's update -- runs
|
||||
them inside a few-millisecond frame budget (`lib/BuildBudget.lua`
|
||||
suspends the build coroutine mid-loop when the slice is spent). The
|
||||
camera tween holds at flat until the current map's terrain exists, so
|
||||
toggling voxel mode shows a handful of flat frames instead of a frozen
|
||||
one; neighbours pop in as they finish. Warp fades prefetch the
|
||||
destination (the pipeline update ticks while the Transition covers the
|
||||
screen, with a wider pump slice), so a door exit lands on terrain that
|
||||
is already built.
|
||||
- Vertex packing goes through FFI into one native buffer
|
||||
(`Mesh:setVertices(ByteData)`) instead of a Lua table per vertex --
|
||||
the headless table path remains for the pure `geometry()` API and its
|
||||
suite.
|
||||
- Round-tree hulls are carved once per (tileset, art, ground set) and
|
||||
kept as stamps -- template plus cell offset, expanded during vertex
|
||||
packing -- instead of materialized per-cell quad tables. A route's
|
||||
border forest was ~500 quads x hundreds of cells of retained heap.
|
||||
- Mesh and analysis caches evict down to the live neighbourhood (current
|
||||
map + rendered neighbours, plus one set of history so a house
|
||||
round-trip keeps the town warm). Evicted meshes are released
|
||||
explicitly. Memory over Pallet -> Mt Moon: was ~2.9GB and monotonic,
|
||||
now oscillates between ~90 and 200MB.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Stray pixels along map seams: ring props (border-tree hulls) whose
|
||||
quad CENTER sat exactly on a neighbour body's edge line escaped the
|
||||
strict point-in-rect mask and survived as fragments of otherwise
|
||||
dropped trees. Object quads now keep/drop by their full extent,
|
||||
boundary inclusive; props straddling the body edge also stay whole
|
||||
instead of shedding their outer half.
|
||||
- The one-step "ledge hop" when crossing a connection into a tree-ringed
|
||||
map: the seam step stands the player one cell off the new map, where
|
||||
`Map:cellTile` border-extends into the borderBlock -- a raised tile on
|
||||
maps ringed with trees. Off-map ground now reads as height 0 (the
|
||||
departed neighbour's flat walkway, which is what is actually rendered
|
||||
there).
|
||||
|
||||
## 1.2.0
|
||||
|
||||
Buildings stop being boxes wearing their own elevation. A profiled
|
||||
building is voxelized from its own sprite, band by band -- the pipeline
|
||||
written up in `assets/docs/buidling_to_voxel/`.
|
||||
|
||||
### Added
|
||||
|
||||
- `lib/Buildings.lua`: a building archetype. Where the volume path folds a
|
||||
whole drawing upright (roof, facade and sloped ends alike) into one box,
|
||||
this classifies each BAND of the drawing by the 3D surface it depicts and
|
||||
applies the matching operation: top-facing rows lay flat over the
|
||||
footprint, the facade extrudes straight back, an awning band juts past
|
||||
the walls, and the drawn taper at the ends becomes a stepped slope in
|
||||
elevation. Every visible voxel carries a real texel of the drawing, so
|
||||
the model recolours with the atlas.
|
||||
- A `buildings` section in `data/voxel_heights.lua`. A building is matched
|
||||
by its exact tile grid (the drawings are catalogued in `assets/docs/buildings/`),
|
||||
so one entry covers every map that places the same art -- Red's house,
|
||||
Blue's house, Bill's, the Copycat's and the two Fuchsia houses are one
|
||||
seven-placement entry, and Oak's lab is a second. Only the band table is
|
||||
authored; the silhouette, the taper rate, the eave height and every
|
||||
window and doorway are measured off the pixels.
|
||||
- The flat-roofed civic block and its sixteen relatives -- every Pokemon
|
||||
Center and every Poke Mart, Fuchsia Gym, the museum, the Game Corner,
|
||||
Celadon Mansion and its department store, the Power Plant, the Route 5
|
||||
and Route 22 gates, Silph Co and five anonymous scenery blocks. They are
|
||||
one architecture drawn at eleven different footprints, from 4x4 cells up
|
||||
to Silph Co's 8x12, and they share one band table: their lattice is drawn
|
||||
from straight above, so the measured taper comes out flat and the whole
|
||||
band is depth under one level roof. No new roof mode was needed -- the
|
||||
drawn profile was always the shape, and a drawing with no taper simply
|
||||
yields a level one.
|
||||
- Pewter's museum hall (`assets/docs/buildings/B24`). It is the one
|
||||
sloped-roof building in this pass, and the only one so far whose roof
|
||||
texture is not a plain repeat: the drawing states its own period by
|
||||
repeating the whole lattice-and-course motif, rows 8..31 again at 32..55,
|
||||
so the cycle is 24 rows and the roof carries its drawn courses across the
|
||||
depth instead of a bare lattice. The band below them is the roof's
|
||||
fascia, wider than the wall it covers, so it belongs to the roof and
|
||||
lands on the south rim. Note the museum is TWO drawings: this hall and
|
||||
the east entrance beside it, which is B18 and shares its drawing with the
|
||||
Route 2 gate.
|
||||
- The rest of the 2:1 sloped-roof buildings: both gym drawings (the
|
||||
standard one at Cinnabar, Pewter, Vermilion and Viridian plus the
|
||||
Fighting Dojo, and the wider Celadon / Cerulean / Saffron one), the 4x2
|
||||
cottage that houses Mr Fuji, the Cubone house, Bill's grandpa, the Name
|
||||
Rater and the Viridian school, Cerulean's three wide houses, the day
|
||||
care, and three scenery blocks -- among them B01, which at 19 placements
|
||||
is the commonest drawing in the game. Each one's roof band is pixel for
|
||||
pixel one of the three already authored, so they take that sibling's band
|
||||
table unchanged: 16 rows for Red's house's, 32 for Oak's lab's, 64 for
|
||||
the museum's.
|
||||
- The Safari Zone rest houses and the Victory Road entrance, the first
|
||||
buildings outside the `OVERWORLD` tileset -- `buildings` is keyed by
|
||||
tileset and until now only had the one section. The rest house's
|
||||
corrugated roof repeats every 5 rows rather than the overworld lattice's
|
||||
8, which is the point of `roofCycle` being authored per building.
|
||||
- Route 10's scenery block, via a new `seal` field. Its drawing has no
|
||||
black base course -- it ends on a row of light brick -- so the silhouette
|
||||
flood climbed in from the south border through the mortar and hollowed
|
||||
the wall out, leaving 72% of the sprite in 65 pieces. `seal` names the
|
||||
sides a drawing runs off rather than closing, and the flood does not seed
|
||||
there: sealed, it is 95% in one piece, and the model is its twin the
|
||||
museum's. No other building sets it, and none changes by a voxel.
|
||||
- Together these take the mod to 31 of the catalogue's 34 drawings and 144
|
||||
of its 147 placements. The last three, and why each resists, are written
|
||||
up in `assets/docs/buildings/REMAINING.md`.
|
||||
- A roof no longer runs past the drawing's own silhouette. These sprites
|
||||
are inset from their boxes, and the columns outside the inset carry no
|
||||
roof: they now get none, and the fascia belongs to the outermost columns
|
||||
the drawing actually paints. Before, they raised a four-voxel slab of
|
||||
black kerb the full depth of the building, flanking its walls at ground
|
||||
level. Nothing shipped hit this -- Red's house and Oak's lab are drawn
|
||||
edge to edge -- so no existing model changes by a single voxel.
|
||||
- Windows and doorways sink a voxel behind their frames, found rather than
|
||||
listed: a pane is a non-black region the drawing seals off behind its own
|
||||
black outline. A nested frame (the door's own little window) layers for
|
||||
free.
|
||||
- `tools/building_voxels.py`: the reference implementation of the same
|
||||
algorithm, with the geometric asserts and isometric previews Stage 5 of
|
||||
the methodology calls for. It and the runtime agree exactly on voxel and
|
||||
shell counts for all 19 templates -- 96,617 / 12,866 for Red's house up
|
||||
to 3,715,963 / 146,762 for Silph Co, which ship as 3,410 and 13,994
|
||||
quads. Its slope asserts read the drawn columns only and stand down for a
|
||||
roof with no taper, where the check is that the roof is level instead;
|
||||
its previews fit the projection to the model rather than to a fixed
|
||||
camera, so a building taller or deeper than the first two still lands on
|
||||
the canvas.
|
||||
|
||||
### Changed
|
||||
|
||||
- A voxelized building is as tall as its facade plus its roof slab rather
|
||||
than as tall as its drawing: the roof rows are DEPTH now, not height, so
|
||||
Red's house is 36px over a 4x3-cell plot instead of a 48px cube.
|
||||
- Round trees (the `cylinder` pin: lone canopies and the border tree
|
||||
wall) stop being lathes -- the sprite wrapped around a 12-segment
|
||||
column read as exactly that, art smeared on a barrel. Each cell is now
|
||||
a real voxel hull: the canopy is segmented out of its cell as the
|
||||
darkest-pixel outline plus everything it encloses (which also drops
|
||||
the background grass that used to inflate every row to full width, and
|
||||
the cast shadow under the ball), and each mask row runs its own span's
|
||||
circular chord in depth -- the front view is the sprite pixel for
|
||||
pixel, the plan view is the sprite's width profile turned in depth.
|
||||
Dithered art with no closed outline (the tree wall) falls back to
|
||||
light-shades-only flooding, per the methodology doc's boundary rule.
|
||||
Sides de-outline like building extrusions so flanks read as canopy
|
||||
rather than solid black, and dome caps keep their outline on the rim
|
||||
while the interior samples the canopy a couple of rows deeper.
|
||||
- A `post` standee pool, pinned for the overworld's vertical fence-post
|
||||
cell (tiles 14/85 -- across every map the pair appears only as this
|
||||
cell). The detector already turns HORIZONTAL fence runs (tile 57) into
|
||||
per-post standees, but a vertical run of repeated cells trips its
|
||||
scenery-repetition guard and fell to the volume path as a
|
||||
fence-textured tower (Viridian's west line, Route 25).
|
||||
`post` extracts every CELL as its own cluster -- pooled clustering
|
||||
would stand the whole line up as one drawing-tall slab at one depth --
|
||||
and classifies pixels the way the detector does (non-white is body)
|
||||
rather than by the pinned-prop outline rule, which would strip the
|
||||
posts to black skeletons; at the detector's own 6px depth, pinned and
|
||||
detected fences look alike.
|
||||
- Town signs move from the `billboard` pool to a new `signpost` pool: the
|
||||
same per-pixel standing slab, but 2 voxels thin instead of 10. A sign
|
||||
is a plate on a stick, and the standee body that keeps a TV from
|
||||
vanishing at shallow angles read as a solid block of furniture here.
|
||||
- The ground under a round tree matches the tree's own drawn background
|
||||
instead of the map's commonest ground tile. The hull's segmentation
|
||||
already knows which pixels are NOT the tree; those pixels are scored
|
||||
against every flat ground tile the map places and the closest art
|
||||
wins, per template -- so border trees drawn over checker grass stand
|
||||
on checker grass even on a map that is mostly pale path (the old
|
||||
fallback painted path under every mid-forest tree, which has no flat
|
||||
neighbour to vote with). The drawn cast shadow stays out of the score:
|
||||
no ground tile carries a shadow, and its darks would drag every match.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The generic town-house tileset (`HOUSE` -- Blue's house, Daisy at her
|
||||
table, and eighteen more homes, the schoolhouse and the trashed house
|
||||
among them) is now pinned in `data/voxel_heights.lua` the way Red's
|
||||
rooms already were: the dining table stops towering as a wall-height
|
||||
volume and sits at table height with its front folded upright, stools
|
||||
become seat-high boxes that characters sit on, the corner potted
|
||||
plants become per-pixel standees instead of texture-smeared box
|
||||
stacks, the bookcases get clean capped tops, and the wall band (with
|
||||
its window, picture and the schoolhouse blackboard) stays one 16px
|
||||
face. The schoolhouse's open book stands on the pinned tabletop as a
|
||||
cutout, and the trashed house's ransacked table corner keeps table
|
||||
height.
|
||||
- Interior door mats lie flat again in Red's and the generic houses.
|
||||
Their collision tile is $14, which the engine's stale-cache fallback
|
||||
counts as water in every tileset, so the rug recessed into a pond lip;
|
||||
a `ground` pin now overrides the water read.
|
||||
|
||||
## 1.1.0
|
||||
|
||||
Interior furniture gets the shapes it depicts
|
||||
(mods/DRAMATIC_SHAPE/tools/voxel-survey.md is the procedure that found and
|
||||
verified these).
|
||||
|
||||
### Added
|
||||
|
||||
- Furniture shape classes in the profile: `bed` (a low slab wearing its
|
||||
top-down art), `table` and `desk` (boxes at their drawn height whose
|
||||
faces fold the artwork up), `relief` (a prop drawn from above -- a
|
||||
game console -- lying flat and extruding a few voxels inside its
|
||||
outline), the standee pools `billboard` (10px) / `prop` (5px) /
|
||||
`stool` (5px, and characters standing on its walkable cell sit at
|
||||
seat height) / `cutout` (one voxel: pure profile, for the vase on the
|
||||
table), and the stair archetypes `stair_e`/`stair_w` (a rising flight
|
||||
of real steps) and `stair_down_e`/`stair_down_w` (a sunken stairwell
|
||||
descending below the floor -- stairs that lead down). Separate pools
|
||||
cluster separately, so touching drawings never merge into one cutout.
|
||||
- Standee clusters split into per-pixel connected components, each
|
||||
standing on its own feet in the depth band of the row it is drawn in:
|
||||
two stools stacked in adjacent cells become two stools, and no
|
||||
fragment of a drawing ever floats at its bounding-box height. A
|
||||
`cutout` keeps only its largest component -- a cast shadow's drawn
|
||||
edge is background, not a floating scrap.
|
||||
- `bookcase` class: free-standing shelf drawings collapse in ranks onto
|
||||
one-cell-deep boxes at their full drawn height, back rows becoming
|
||||
hidden floor; the trim row above a rank -- undetected structure or a
|
||||
row pinned `table`, since the same trim tiles cap other furniture --
|
||||
is adopted as its cap. Pinned for Oak's Lab (`DOJO`).
|
||||
- Oak's Lab tables pinned `table`: the starter-ball display and the
|
||||
north tables stand at real table height, the display frame's black
|
||||
corner brackets no longer auto-extract into standing prisms, and the
|
||||
Poke Ball / Pokedex sprites ride the authored height onto the
|
||||
tabletops.
|
||||
- Pinned props drawn directly above a pinned box stand ON it: the PC
|
||||
monitor on its desk, the flower pot on the dining table.
|
||||
- Profile pins for `REDS_HOUSE_1` / `REDS_HOUSE_2` (Red's house and the
|
||||
Copycat's, both floors): bed, stools, tables, PC desk with its
|
||||
standing monitor, bookcases, TV standing on the floor behind the game
|
||||
console's relief, potted plant, flower pot, both staircases, and the
|
||||
wall/window band.
|
||||
- `mods/DRAMATIC_SHAPE/tests/voxel_survey.lua`: screenshot-survey driver
|
||||
behind the repeatable inspection procedure (SURVEY_MAP / SURVEY_SPOTS /
|
||||
SURVEY_LEVELS / SHOT_DIR), documented in
|
||||
mods/DRAMATIC_SHAPE/tools/voxel-survey.md.
|
||||
|
||||
### Changed
|
||||
|
||||
- Pinned props are segmented the way the art is authored: objects wear a
|
||||
black outline, so background is the shades touching the cluster's edge
|
||||
(white floor around a TV, grey tabletop around a vase) flooded in from
|
||||
the aprons; the outline, its interior, paint whites and anything they
|
||||
enclose survive -- pixel-perfect cutouts on any surface.
|
||||
- Indoor structure analysis floods background from all four aprons and
|
||||
accepts ground contact on any side (outdoors keeps the south-only rule
|
||||
that protects roofs), so face-on furniture drawings voxelize per pixel
|
||||
instead of rising as wall-height volumes.
|
||||
- Profile-pinned standees are 10px deep (detected props stay 6px), so a
|
||||
deliberate object like a TV keeps a body at shallow camera angles.
|
||||
- Authored upright boxes fold their artwork up every face (flanks and
|
||||
back wear the front stack darkened) and top faces keep the drawn
|
||||
tabletop: face-on rows wear the row above the fold instead of
|
||||
repeating their front art lying flat, and a run that folded entirely
|
||||
tops with the furniture row drawn above it (a bookcase's shelf trim).
|
||||
- Characters no longer ride a pinned stair tile's class height: stairs
|
||||
are walked through at floor level, fixing the step-up onto thin air in
|
||||
front of stairwells.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
First release, ported from the engine-internal voxel branch onto the
|
||||
`render_pipelines` mod API.
|
||||
|
||||
### Added
|
||||
|
||||
- `voxel` render pipeline: 3D diorama overworld with extruded terrain,
|
||||
depth-buffered occlusion, leaning sprite billboards, drop shadows and
|
||||
contact AO. VOXEL options row and hotkey `6` (OFF / 15 / 35 / 50).
|
||||
- `tiltshift` render pipeline: a `worldPresent` post-process giving the
|
||||
miniature-photo look. T-SHIFT options row and hotkey `9` (OFF / 1 / 2 / 3).
|
||||
- Carved voxel models for 67 overworld sprites, plus the
|
||||
`tools/build_voxels.py` that produced them.
|
||||
- `data/voxel_heights.lua`, the hand-authored tile shape profile.
|
||||
|
||||
### Changed from the pre-mod version
|
||||
|
||||
- The level is no longer the mod's to keep. The engine owns the ladder, the
|
||||
@@ -671,7 +645,7 @@ First release, ported from the engine-internal voxel branch onto the
|
||||
keeps only the camera-angle tween.
|
||||
- Persistence moved from `save.options.voxel` / `save.options.tiltshift` to
|
||||
`save.options.pipelines.voxel` / `.tiltshift`.
|
||||
- Hotkeys moved from `4`/`9` to `6`/`9`: the fork already uses `4` for
|
||||
- Hotkeys moved from `4`/`9` to `3`/`6`: the fork already uses `4` for
|
||||
survey zoom.
|
||||
- The tilt-shift pass is a declared `worldPresent` stage rather than a call
|
||||
spliced into the world draw, so it composes with any world pipeline
|
||||
|
||||
Reference in New Issue
Block a user