luv

Workshop wiki

materials.lisp

luft/render/materials.lisp

system luft/renderer · 97 definitions · on GitHub

in-package#:luft.render

Semantic material definitions live here, above scene storage and mesh realization. The objects are the inspectable vocabulary; cells and GPU instances carry only dense offsets closed by an owning vocabulary.

defclassmaterial-kind
name:initarg:name:readermaterial-kind-name
base-tone:initarg:base-tone:readermaterial-kind-base-tone
roughness:initarg:roughness:readermaterial-kind-roughness
relief:initarg:relief:readermaterial-kind-relief
:documentation

A reusable substance and its renderer-facing response.

defclassmaterial-frame
name:initarg:name:readermaterial-frame-name
origin:initarg:origin:readermaterial-frame-origin
axes:initarg:axes:readermaterial-frame-axes
:documentation

A coherent coordinate frame for natural fields or authored construction.

defclassmaterial-placement
name:initarg:name:readermaterial-placement-name
kind:initarg:kind:readermaterial-placement-kind
finish:initarg:finish:readermaterial-placement-finish
frame:initarg:frame:readermaterial-placement-frame
role:initarg:role:readermaterial-placement-role
readings:initform
make-hash-table:test#'eq
:readermaterial-placement-readings
:documentation

Authored cell meaning: substance, deliberate finish, frame, and role.

defclasssurface-reading
name:initarg:name:readersurface-reading-name
kind:initarg:kind:readersurface-reading-kind
tone:initarg:tone:readersurface-reading-tone
finish:initarg:finish:readersurface-reading-finish
frame:initarg:frame:readersurface-reading-frame
role:initarg:role:readersurface-reading-role
:documentation

One exposed face's derived interpretation of an authored placement.

defclasssurface-assembly
name:initarg:name:readersurface-assembly-name
relation:initarg:relation:readersurface-assembly-relation
primary:initarg:primary:readersurface-assembly-primary
secondary:initarg:secondary:initformnil:readersurface-assembly-secondary
tertiary:initarg:tertiary:initformnil:readersurface-assembly-tertiary
kernel:initarg:kernel:readersurface-assembly-kernel
:documentation

An interned face, band, or fan material relation compiled for rendering.

defunensure-semantic-instance
currentclass&restinitargs

Reinitialize current when it still has class, preserving live identity.

if
andcurrent
eq
class-ofcurrent
find-classclass
progn
apply#'reinitialize-instancecurrentinitargs
current
apply#'make-instanceclassinitargs
setf*earth-material*
ensure-semantic-instance*earth-material*'earth-material-kind:name:earth:base-tone'
0.420.320.21
:roughness0.92:relief:granular
*limestone-material*
ensure-semantic-instance*limestone-material*'stone-material-kind:name:limestone:base-tone'
0.530.490.39
:roughness0.78:relief:weathered-stone
*highland-rock-material*
ensure-semantic-instance*highland-rock-material*'stone-material-kind:name:highland-rock:base-tone'
0.290.300.27
:roughness0.94:relief:weathered-stone
*world-material-frame**sanctuary-material-frame*
ensure-semantic-instance*sanctuary-material-frame*'material-frame:name:sanctuary:origin'
32240
:axes'
100
010
001
*beacon-material-frame*
ensure-semantic-instance*beacon-material-frame*'material-frame:name:ridge-beacon:origin'
90780
:axes'
0.707106770.707106770
-0.707106770.707106770
001
*terrain-material-placement**highland-rock-material-placement**sanctuary-material-placement**beacon-material-placement*
setf*grass-reading*
ensure-semantic-instance*grass-reading*'surface-reading:name:grass:kind*earth-material*:tone'
0.180.310.105
:finish:living:frame*world-material-frame*:role:exposed-top
*soil-reading*
ensure-semantic-instance*soil-reading*'surface-reading:name:soil:kind*earth-material*:tone'
0.420.320.21
:finish:cut:frame*world-material-frame*:role:exposed-side
*subsoil-reading*
ensure-semantic-instance*subsoil-reading*'surface-reading:name:subsoil:kind*earth-material*:tone'
0.240.180.13
:finish:broken:frame*world-material-frame*:role:underside
*stone-reading*
ensure-semantic-instance*stone-reading*'surface-reading:name:dressed-limestone:kind*limestone-material*:tone'
0.530.490.39
:finish:dressed:frame*sanctuary-material-frame*:role:architecture
*foundation-stone-reading*
ensure-semantic-instance*foundation-stone-reading*'surface-reading:name:foundation-limestone:kind*limestone-material*:tone'
0.530.490.39
:finish:earth-weathered:frame*sanctuary-material-frame*:role:foundation
flet
seed
placement&restreadings
clrhash
material-placement-readingsplacement
dolist
readingreadings
setf
gethash
surface-reading-rolereading
material-placement-readingsplacement
reading

Seeding retains the first nine assembly identities as a rebuild oracle; any later placement receives the same semantic readings in its own frame.

defunplacement-surface-reading
placementrolenametonefinish

Intern one face interpretation in placement's authored coordinate frame.

or
gethashrole
material-placement-readingsplacement
setf
gethashrole
material-placement-readingsplacement
make-instance'surface-reading:name
list
material-placement-nameplacement
name
:kind
material-placement-kindplacement
:tonetone:finishfinish:frame
material-placement-frameplacement
:rolerole
defunensure-surface-assembly
currentnamerelationprimary&keysecondarytertiarykernel
ensure-semantic-instancecurrent'surface-assembly:namename:relationrelation:primaryprimary:secondarysecondary:tertiarytertiary:kernelkernel

Geometry policy is semantic at this boundary and dense below it. The proof-of-concept profile compiles once to a stock-indexed byte lane; mesh instance partitioning never dispatches on material objects.

defclassmaterial-bevel-profile
terrain-width:initarg:terrain-width:initform4:readermaterial-bevel-profile-terrain-width
architecture-width:initarg:architecture-width:initform1:readermaterial-bevel-profile-architecture-width
contact-width:initarg:contact-width:initform2:readermaterial-bevel-profile-contact-width
:documentation

A semantic assignment of luft integer bevel widths to material relations.

defunmake-material-bevel-profile
&key
terrain-width4
architecture-width1
contact-width2
dolist
width
listterrain-widtharchitecture-widthcontact-width
unless
error"Material bevel width ~S must be an integer between one and four ticks."width
make-instance'material-bevel-profile:terrain-widthterrain-width:architecture-widtharchitecture-width:contact-widthcontact-width
defunarchitecture-surface-reading-p
reading
member
surface-reading-rolereading
'
:architecture:foundation
defunsurface-assembly-readings
assembly
remove-duplicates
removenil
list
surface-assembly-primaryassembly
surface-assembly-secondaryassembly
surface-assembly-tertiaryassembly
:test#'eq
defunsurface-assembly-material-bevel-mask
assembly

Return the terrain/architecture bits represented by assembly.

A face is owned by its primary authored reading. Secondary soil readings on foundation faces describe weathering and therefore do not turn a homogeneous architectural site into a material contact. Bands and junctions retain every incident reading, so their mask records a genuine mixed relation.

if
eq:face
surface-assembly-relationassembly
surface-reading-material-bevel-mask
surface-assembly-primaryassembly
reduce#'logior:key#'surface-reading-material-bevel-mask:initial-value0
defgenericmaterial-bevel-width
profileassembly
:documentation

Return the integer luft bevel width assigned to semantic assembly.

defmethodmaterial-bevel-width
ecase
#.+material-bevel-terrain-mask+
material-bevel-profile-terrain-widthprofile
#.+material-bevel-architecture-mask+
material-bevel-profile-architecture-widthprofile
#.
material-bevel-profile-contact-widthprofile
defuncompile-material-bevel-profile
profile&optional

Compile profile to one unsigned-byte width per packed assembly stock.

check-typeprofilematerial-bevel-profile
let*
members
domains:identity-vocabulary-membersvocabulary
widths
make-array
lengthmembers
:element-type'
unsigned-byte8
loopforassemblyacrossmembersforstockfrom0forwidth=
material-bevel-widthprofileassembly
do
unless
error"Material bevel policy assigned invalid width ~S to ~S."widthassembly
setf
arefwidthsstock
width
widths
defuncompile-material-bevel-site-policy
profile&optional

Compile profile into dense stock masks and site widths.

The first value is one terrain/architecture bit mask per packed assembly stock. The second is a four-entry byte table indexed by the or of every incident stock mask: terrain-only, architecture-only, and mixed sites select the profile's terrain, architecture, and contact widths respectively.

check-typeprofilematerial-bevel-profile

Compile the ordinary stock widths as the validation oracle. In particular, a profile made without make-material-bevel-profile must not smuggle an out-of-range width into the site table.

let*
members
domains:identity-vocabulary-membersvocabulary
stock-masks
make-array
lengthmembers
:element-type'
unsigned-byte8
site-widths
make-array4:element-type'
unsigned-byte8
:initial-contents
list0
material-bevel-profile-terrain-widthprofile
material-bevel-profile-architecture-widthprofile
material-bevel-profile-contact-widthprofile
loopforassemblyacrossmembersforstockfrom0do
setf
arefstock-masksstock
valuesstock-maskssite-widths

The first nine vocabulary members are the stable renderer ABI. The tests rebuild this exact prefix from the semantic objects, so these literals are available while this file itself is being compiled in a clean image.

defconstant+grass-stock+0
defconstant+soil-stock+1
defconstant+subsoil-stock+2
defconstant+stone-stock+3
defconstant+turf-edge-stock+7
defunsurface-kernel-code
kernel

Compile the intentionally closed shader-kernel ABI.

ecasekernel
:grass7
:soil5
:subsoil6
:stone4
:earth-set-stone1
:turf-edge2
:foundation-stone3
defunmaterial-relief-code
relief

Compile the closed procedural-relief ABI shared by all surface kernels.

ecaserelief
:granular1
:weathered-stone2
defunmaterial-relief-amplitude
relief
ecaserelief
:granular0.028
:weathered-stone0.020
defunsurface-contact-variant
assembly
if
eq
surface-assembly-kernelassembly
:earth-set-stone
let
secondary
surface-assembly-secondaryassembly
cond
eq
surface-reading-rolesecondary
:exposed-top
0
eq
surface-reading-rolesecondary
:exposed-side
1
eq
surface-reading-rolesecondary
:underside
2
t
error"Unknown earth contact reading ~S."secondary
0
defunsurface-assembly-descriptor-words

Compile vocabulary into fixed-stride float32 rows for direct GPU indexing.

Each assembly owns seven vec4 rows: primary/kernel, secondary/contact variant, tertiary/roughness, then frame origin/relief profile and its three axes (with relief amplitude beside X). The fixed stride is small enough for direct indexing while leaving material meaning on the CPU.

let*
members
domains:identity-vocabulary-membersvocabulary
words
make-array:element-type'single-float
labels
put-row
rowvalues
loopforvalueinvaluesforlanefrom
*row4
do
setf
arefwordslane
coercevalue'single-float
tone-of
readingfallback
surface-reading-tone
orreadingfallback
loopforassemblyacrossmembersforindexfrom0forprimary=
surface-assembly-primaryassembly
forsecondary=
or
surface-assembly-secondaryassembly
primary
fortertiary=
or
surface-assembly-tertiaryassembly
secondary
forframe=
surface-reading-frameprimary
forrow=do
put-rowrow
append
tone-ofprimaryprimary
list
surface-kernel-code
surface-assembly-kernelassembly
put-row
+row1
append
tone-ofsecondaryprimary
put-row
+row2
append
tone-oftertiarysecondary
list
material-kind-roughness
surface-reading-kindprimary
put-row
+row3
append
material-frame-originframe
list
material-relief-code
material-kind-relief
surface-reading-kindprimary
loopforaxisin
material-frame-axesframe
foraxis-rowfrom
+row4
foramplitude=
material-relief-amplitude
material-kind-relief
surface-reading-kindprimary
do
put-rowaxis-row
appendaxis
list
if
=axis-row
+row4
amplitude0.0
words
defgenericmaterial-face-reading
kindplacementscenecellaxisside
:documentation

Derive one exposed face reading from an authored material placement.

defmethodmaterial-face-reading
declare
ignorekindscenecell
cond
placement-surface-readingplacement:exposed-side:soil'
0.420.320.21
:cut
eqside:backward
placement-surface-readingplacement:exposed-top:grass'
0.180.310.105
:living
t
placement-surface-readingplacement:underside:subsoil'
0.240.180.13
:broken
defmethodmaterial-face-reading
declare
ignorekindaxisside
if
eq:terrain-rock
material-placement-roleplacement
placement-surface-readingplacement:natural-rock:highland-rock'
0.290.300.27
:weathered
if
placement-surface-readingplacement:foundation:foundation-limestone'
0.530.490.39
:earth-weathered
placement-surface-readingplacement:architecture:dressed-limestone'
0.530.490.39
:dressed
defunfind-surface-assembly
relationprimarysecondarytertiarykernel
find-if
lambda
assembly
and
eqrelation
surface-assembly-relationassembly
eqprimary
surface-assembly-primaryassembly
eqsecondary
surface-assembly-secondaryassembly
eqtertiary
surface-assembly-tertiaryassembly
eqkernel
surface-assembly-kernelassembly
domains:identity-vocabulary-members*surface-assembly-vocabulary*
defunintern-surface-assembly
relationprimary&keysecondarytertiarykernelname

Intern a small semantic assembly at mesh-compilation time.

or
find-surface-assemblyrelationprimarysecondarytertiarykernel
let
assembly
make-instance'surface-assembly:name
orname
listrelation
surface-reading-nameprimary
:relationrelation:primaryprimary:secondarysecondary:tertiarytertiary:kernelkernel
assembly
defunface-reading-assembly
reading
cond
t
intern-surface-assembly:facereading:secondary
and
eq
surface-reading-rolereading
:foundation
*soil-reading*
:tertiary
and
eq
surface-reading-rolereading
:foundation
*subsoil-reading*
:kernel
case
surface-reading-rolereading
:exposed-top:grass
:exposed-side:soil
:underside:subsoil
:foundation:foundation-stone
otherwise:stone
defunstone-reading-p
reading
typep
surface-reading-kindreading
'stone-material-kind
defunchamfer-surface-assembly
readings

Resolve incident face readings as one current-width surface assembly.

labels
role-reading
role
findrolereadings:key#'surface-reading-role
stone-reading
find-if#'stone-reading-preadings
earth-set
earth
let
stone
stone-reading
intern-surface-assembly:contactstone:secondaryearth:tertiary*subsoil-reading*:kernel:earth-set-stone
cond
and
stone-reading
role-reading:underside
earth-set
role-reading:underside
and
stone-reading
role-reading:exposed-side
earth-set
role-reading:exposed-side
and
stone-reading
role-reading:exposed-top
earth-set
role-reading:exposed-top
every
lambda
reading
eqreading
firstreadings
restreadings
stone-reading
and
role-reading:exposed-top
or
role-reading:exposed-side
role-reading:underside
*turf-edge-surface*
defunclosure-surface-assembly
assemblies

Resolve an edge or fan closure without erasing incident assembly identity.

Fan construction may present assemblies already derived for surrounding bands; those are not interchangeable with their primary face readings. This resolver therefore preserves the legacy recursive decision exactly while expressing it in semantic identities rather than numeric ranges.

flet
stone-face-p
assembly
if
cond
and
some#'stone-face-passemblies
member*subsoil-surface*assemblies
*deep-set-stone-surface*
and
some#'stone-face-passemblies
member*soil-surface*assemblies
*soil-set-stone-surface*
and
some#'stone-face-passemblies
member*grass-surface*assemblies
*turf-set-stone-surface*
every
lambda
assembly
eqassembly
firstassemblies
restassemblies
firstassemblies
some#'stone-face-passemblies
*stone-surface*
and
member*grass-surface*assemblies
or
member*soil-surface*assemblies
member*subsoil-surface*assemblies
*turf-edge-surface*
chamfer-surface-assembly
mapcar#'surface-assembly-primaryassemblies

--------------------------------------------------------------------------- Scene material compilation

defconstant+assembly-legacy-flag+#x01
defclassmaterial-program
placement-face-stocks:initarg:placement-face-stocks:readermaterial-program-placement-face-stocks
placement-flags:initarg:placement-flags:readermaterial-program-placement-flags
assembly-flags:initarg:assembly-flags:readermaterial-program-assembly-flags
assembly-primary-flags:initarg:assembly-primary-flags:readermaterial-program-assembly-primary-flags
assembly-primary-reading-offsets:initarg:assembly-primary-reading-offsets:readermaterial-program-assembly-primary-reading-offsets
assembly-face-stocks:initarg:assembly-face-stocks:readermaterial-program-assembly-face-stocks
reading-contact-stocks:initarg:reading-contact-stocks:readermaterial-program-reading-contact-stocks
reading-count:initarg:reading-count:readermaterial-program-reading-count
:documentation

Scene-closed dense decisions consumed by face, band, and fan meshing.

defgenericcompile-material-placement
kindplacement
:documentation

Compile placement once into six oriented readings and one foundation row.

defvar*material-placement-compilation-count*0"Dynamically bindable witness for the cold semantic compilation boundary."
defmethodcompile-material-placement
placement
declare
ignorekind
let
side
placement-surface-readingplacement:exposed-side:soil'
0.420.320.21
:cut
top
placement-surface-readingplacement:exposed-top:grass'
0.180.310.105
:living
underside
placement-surface-readingplacement:underside:subsoil'
0.240.180.13
:broken
vectorsidesidesidesidetopundersidenil
defmethodcompile-material-placement
placement
declare
ignorekind
if
eq:terrain-rock
material-placement-roleplacement
let
rock
placement-surface-readingplacement:natural-rock:highland-rock'
0.290.300.27
:weathered
vectorrockrockrockrockrockrocknil
let
architecture
placement-surface-readingplacement:architecture:dressed-limestone'
0.530.490.39
:dressed
foundation
placement-surface-readingplacement:foundation:foundation-limestone'
0.530.490.39
:earth-weathered
vectorarchitecturearchitecturearchitecturearchitecturearchitecturearchitecturefoundation
defunensure-reading-closure-assemblies
reading

Intern the face result that the dense resolver may select for reading.

defunearth-contact-reading-p
reading
and
typep
surface-reading-kindreading
'earth-material-kind
member
surface-reading-rolereading
'
:exposed-top:exposed-side:underside
defunmake-material-program
placement-vocabulary

Bind semantic placement and assembly meaning once into dense stock tables.

let*
placements
domains:identity-vocabulary-membersplacement-vocabulary
placement-count
lengthplacements
placement-readings
make-arrayplacement-count
placement-face-stocks
make-array:element-type'
unsigned-byte16
placement-flags
make-arrayplacement-count:element-type'
unsigned-byte8
:initial-element0

This is the only material-kind generic dispatch in scene compilation.

loopforplacementacrossplacementsforplacement-offsetfrom0forreadings=
compile-material-placement
material-placement-kindplacement
placement
do
setf
arefplacement-readingsplacement-offset
readings
when
eq:architecture
material-placement-roleplacement
setf
arefplacement-flagsplacement-offset
logior
arefplacement-flagsplacement-offset
+material-placement-architecture-flag+
when
typep
material-placement-kindplacement
'earth-material-kind
setf
arefplacement-flagsplacement-offset
logior
arefplacement-flagsplacement-offset
+material-placement-earth-flag+
loopforreadingacrossreadingswhenreadingdo

A previous scene may have extended the renderer-global assembly ABI. Close those primaries too before fixing this program's array bounds.

loopforassemblyacross
copy-seq
domains:identity-vocabulary-members*surface-assembly-vocabulary*
do
ensure-reading-closure-assemblies
surface-assembly-primaryassembly

Intern the cross-product of authored stone and earth readings once. A contact then retains both placements' tone and frame without a hot hash.

let
primary-readings
make-array16:adjustablet:fill-pointer0
primary-reading-offsets
make-hash-table:test#'eq
loopforassemblyacross
domains:identity-vocabulary-members*surface-assembly-vocabulary*
forreading=
surface-assembly-primaryassembly
unless
gethashreadingprimary-reading-offsets
do
setf
gethashreadingprimary-reading-offsets
lengthprimary-readings
vector-push-extendreadingprimary-readings
loopforstoneacrossprimary-readingswhendo
loopforearthacrossprimary-readingswhendo

All assembly interning is complete before the arrays receive their size.

let*
assemblies
domains:identity-vocabulary-members*surface-assembly-vocabulary*
assembly-count
lengthassemblies
reading-count
lengthprimary-readings
assembly-flags
make-arrayassembly-count:element-type'
unsigned-byte8
:initial-element0
primary-flags
make-arrayassembly-count:element-type'
unsigned-byte8
:initial-element0
assembly-reading-offsets
make-arrayassembly-count:element-type'
unsigned-byte16
face-stocks
make-arrayassembly-count:element-type'
unsigned-byte16
reading-contacts
make-array
*reading-countreading-count
:element-type'
unsigned-byte16
:initial-element+soil-stock+
loopforreadingsacrossplacement-readingsforplacement-offsetfrom0do
loopforreadingacrossreadingsforfacefrom0whenreadingdo
setf
arefplacement-face-stocks
loopforassemblyacrossassembliesforstockfrom0forprimary=
surface-assembly-primaryassembly
forrole=
surface-reading-roleprimary
forstone-p=do
setf
arefassembly-reading-offsetsstock
gethashprimaryprimary-reading-offsets
arefface-stocksstock
setf
arefprimary-flagsstock
loopforstoneacrossprimary-readingsforstone-offsetfrom0whendo
loopforearthacrossprimary-readingsforearth-offsetfrom0whendo
setf
arefreading-contacts
+
*stone-offsetreading-count
earth-offset
make-instance'material-program:placement-face-stocksplacement-face-stocks:placement-flagsplacement-flags:assembly-flagsassembly-flags:assembly-primary-flagsprimary-flags:assembly-primary-reading-offsetsassembly-reading-offsets:assembly-face-stocksface-stocks:reading-contact-stocksreading-contacts:reading-countreading-count
defunmake-compiled-material-chamfer-stock-function
program

Capture program's dense lanes as one dispatch-free chamfer resolver.

let
assembly-flags
the
simple-array
unsigned-byte8
material-program-assembly-flagsprogram
primary-flags
the
simple-array
unsigned-byte8
material-program-assembly-primary-flagsprogram
face-stocks
the
simple-array
unsigned-byte16
material-program-assembly-face-stocksprogram
reading-offsets
the
simple-array
unsigned-byte16
material-program-assembly-primary-reading-offsetsprogram
reading-contacts
the
simple-array
unsigned-byte16
material-program-reading-contact-stocksprogram
reading-count
the
integer0#x1000
material-program-reading-countprogram
lambda
stocks
declare
optimize
speed3
safety1
let
all-legacy-pt
same-stock-pt
same-primary-pt
first-stock
the
unsigned-byte16
firststocks
first-primary
arefface-stocks
firststocks
legacy-stonelegacy-grass-plegacy-soil-plegacy-subsoil-pprimary-stoneprimary-grassprimary-soilprimary-subsoil
dolist
stockstocks
declare
type
unsigned-byte16
stock
let
legacy
arefassembly-flagsstock
primary
arefprimary-flagsstock
unless
setfall-legacy-pnil
unless
=stockfirst-stock
setfsame-stock-pnil
unless
=
arefface-stocksstock
first-primary
setfsame-primary-pnil
when
unlesslegacy-stone
setflegacy-stonestock
when
setflegacy-grass-pt
when
setflegacy-soil-pt
when
setflegacy-subsoil-pt
when
unlessprimary-stone
setfprimary-stonestock
when
unlessprimary-grass
setfprimary-grassstock
when
unlessprimary-soil
setfprimary-soilstock
when
unlessprimary-subsoil
setfprimary-subsoilstock
ifall-legacy-p
cond
andlegacy-stonelegacy-subsoil-p
+deep-set-stone-stock+
andlegacy-stonelegacy-soil-p
+soil-set-stone-stock+
andlegacy-stonelegacy-grass-p
+turf-set-stone-stock+
same-stock-pfirst-stock
legacy-stone+stone-stock+
andlegacy-grass-p
orlegacy-soil-plegacy-subsoil-p
+turf-edge-stock+
flet
contact
stoneearth
arefreading-contacts
+
*
arefreading-offsetsstone
reading-count
arefreading-offsetsearth
cond
andprimary-stoneprimary-subsoil
contactprimary-stoneprimary-subsoil
andprimary-stoneprimary-soil
contactprimary-stoneprimary-soil
andprimary-stoneprimary-grass
contactprimary-stoneprimary-grass
same-primary-pfirst-primary
primary-stone
arefface-stocksprimary-stone
andprimary-grass
orprimary-soilprimary-subsoil
+turf-edge-stock+
defuncompiled-material-chamfer-stock
programstocks

Resolve stocks through a freshly captured program, for inspection/tests.