Files
DramaticShapeVoxelMod/lib/VoxelGrid.lua
T
DramaticShape 326c595336 characters are flat sprite cards; drop the voxelized sprite path
Every figure is now its current 2D frame on one flat quad, the shader's
alpha discard cutting the silhouette. It still faces south and leans by
the camera's pitch, so it reads face-on at every tilt as before.

Removes the contoured slab and the carved visual-hull models --
lib/VoxelModels.lua, tools/build_voxels.py and ~70 generated files under
assets/voxels/ (2 MB). A sprite is a drawing, not an object seen from one
side: Gen 1's overworld figures are 16x16 icons with a fixed front-on
reading, and solidifying one invents a body the artist never drew. Those
files were also the one place this mod carried a description of the ROM
art, since a carve records a sprite's silhouette pixel for pixel.

The card needs no pixel access, and the solid draw, the sun pass and the
player's occlusion silhouette now share one mesh -- which the inverted
depth test the silhouette uses requires, since self-overlap would repaint
the figure on open ground. overrides/voxels/<name>.lua still wins where a
mod ships one.
2026-07-27 10:31:22 -04:00

72 lines
2.6 KiB
Lua

-- Voxel world mode: the voxel wireframe, 3D Dot Game Heroes style.
--
-- Every mesh in this mode is built on a one-unit-per-voxel grid in its OWN
-- model space -- terrain in world pixels, a character card in the sprite's
-- own pixels. So the seams are simply the
-- integer planes of that space, and drawing them is a pixel-shader job:
-- measure how far the fragment is from the nearest integer plane, in
-- DISPLAY pixels, and darken the ones within half a pixel of it. Sitting in
-- model space is what keeps the wireframe glued to a thing however it is
-- posed -- a character's card leans back by the camera's pitch and its
-- seams lean with it, instead of the world's grid sliding across the
-- sprite.
--
-- Deriving "in display pixels" needs shader derivatives (fwidth), which is
-- the one part of this that a driver can refuse. So the grid is a SECOND
-- COMPILATION of the scene shader rather than a branch inside the first
-- one: if it will not build, the mod loses the wireframe and nothing else
-- (see Voxel3D.shader).
--
-- This file owns the toggle rather than the drawing: the level, where it
-- persists, and the row the player finds it on.
-- the mod namespace (see main.lua): V.require loads a sibling module
local V = ...
local ModSetting = V.require("ModSetting")
local VoxelGrid = {}
-- the key under options.modOptions.DRAMATIC_SHAPE, shared by the row in
-- OPTIONS and the mod manager's own settings page for this mod
VoxelGrid.KEY = "grid"
VoxelGrid.LABEL = "V-GRID"
-- How far toward black a seam pulls the surface it cuts across. The
-- wireframe reads as a shading of the model rather than an overlay drawn
-- on top of it, so it darkens what is already there instead of painting a
-- colour -- a seam across dark grass and one across a white roof both stay
-- in the palette they belong to.
VoxelGrid.DARK = 0.45
-- Line width, in display pixels. The scene canvas renders at window
-- resolution and composites 1:1, so a canvas pixel IS a display pixel and
-- 1.0 here is the one-pixel wireframe.
VoxelGrid.WIDTH = 1.0
-- where it persists and the rows that cycle it (see ModSetting)
VoxelGrid.setting = ModSetting.new(VoxelGrid.KEY, VoxelGrid.LABEL,
{ false, true }, { "OFF", "ON" })
function VoxelGrid.enabled()
return VoxelGrid.setting:get() and true or false
end
function VoxelGrid.set(enabled, game)
return VoxelGrid.setting:setIndex(enabled and 2 or 1, game)
end
function VoxelGrid.toggle(game)
return VoxelGrid.setting:cycle(game)
end
function VoxelGrid.sync(value)
VoxelGrid.setting:sync(value and true or false)
end
function VoxelGrid.row()
return VoxelGrid.setting:row()
end
return VoxelGrid