Releases: jonathanhogg/flitter
Release 1.0.0b24
User visible changes in this release:
- A new mechanism for creating 3D models programmatically using
!model vertices=... faces=...
!sdf
node now accepts the samesmooth=
,fillet=
andchamfer=
attributes as!union
(since it is an implicit union operator)- A fix to
nearest=true
shader input sampling, which was accidentally disabling the border settings - New grammar for sub-vector searching:
x in y
(note that this has subtly changed the rules around using "reserved" names) - New grammar for binding a sequence expression to a name:
let x = expr1 expr2 ...
- The precedence rules have changed for anonymous functions so that they now bind a bit less tightly and thus can contain inline for loops, where clauses and other anonymous functions without parentheses
- New
product()
function - New optional second parameter for
colortemp()
function that specifies whether to normalise the luminance of the returned colour or not - New
uv_remap=:plane
UV remapping scheme for topographical mapping
Less visible changes:
- The 3D model caching framework has been changed to cache based on a (probably-)unique 64-bit identifier instead of the user-readable name; this increases the speed of model collection and will be particularly noticeable if rendering thousands of identical structured models
- A more robust mechanism for figuring out which outer-scope names a function is capturing
- The simplifier will now attempt to inline calls to recursive functions if any of the arguments are literal; it will abandon the attempt if the expression tree becomes too deep
- The simplifier is now able to throw away unused
let
bindings - The simplifier has gained rules for collapsing mathematical expressions involving a
null
on one side - Grammar rules around comparison operations have changed in a way that shouldn't matter unless you were doing weird/bad things with them before
- A bunch more tests
- A bunch of documentation improvements and fixes
Full Changelog: v1.0.0b23...v1.0.0b24
Release 1.0.0b23
Visible changes:
sum()
now returns0
for an empty vector instead ofnull
- A new collating
mean()
function with similar behaviour tosum()
- Resolve inconsistencies between use of
minimum
/min
andmaximum
/max
attributes in different places by making both versions acceptable everywhere - Switch to using the model matrix cofactor for normal matrices instead of using the transposed inverse. This is faster and more correct – in particular, it means that scaling by a negative value will result in the model normals being reversed to correctly match the reversed face winding
- New syntactic sugar for nested
for
loops:for x in a, y in b
- The grammar rules have also been changed slightly to allow
;
sequences to be used as for loop sources without needing to be wrapped in brackets - New
nearest=false
attribute on window nodes can be used to turn off linear interpolation on sampling - A load of documentation fixes and improvements
Full Changelog: v1.0.0b22...v1.0.0b23
Release 1.0.0b22
This release contains the following visible changes:
- Signed distance functions - these are available with the new
!sdf
node, which contains an otherwise fairly normal-looking models hierarchy but which allows for smoothed CSG operations and custom functions! !slice
has been renamed!trim
- but you can still use!slice
for compatibility- A new
inverse()
function for calculating the inverse of a 3x3 or 4x4 matrix - Flitter functions that call context-dependent built-ins (like
read()
) no longer use the path context of the module in which they were defined. The semantics of this broke under inlining and were too hard to retain in that form. Arguably it was confusing anyway. - The
!edges
window node supports a newmixer
attribute for mixing in some of the original input to the output.
and under the hood:
- Python 3.13 support
- a new mechanism for clearing the models cache of unused 3D models
- a massive heap of fixes to tiny bugs in the models architecture found during the addition of regression tests
Full Changelog: v1.0.0b20...v1.0.0b22
Release 1.0.0b20
Features:
- Can change the title of a window live now (w00t!)
- New
sort()
function - A few changes to
!noise
to make it more useful (see docs) - Texture mapping attributes have all been renamed (old ones still supported)
- Texture sampler properties can now be controlled on a
!material
node - A completely new, saner UV mapping for
!box
- New
cross()
anddot()
product functions - Support for keystone transformations in
!transform
window nodes - Can now provide arbitrary ffmpeg codec options on a
!record
node !adjust
nodes now support hue and saturation adjustments
Under the hood:
- A bunch of changes to the physics engine to simplify it a bit and improve performance
- Faster nested CSG operations
Bug fixes:
- Fix spherical UV remapping direction
- Fix bug in how transparent objects with textures are dispatched
- Fix bug in processing additional physics frames when running non-realtime
- Fixed how physics groups work to match my original intention
- Fix for offscreen windows on macOS
- Fix a bug in 3D lighting code with AMD GPUs on macOS
- Fix for reloading when nested code dependencies change
- Exporting videos with transparency now works again (only for the
:prores_ks
codec at the moment)
Plus the usual bevy of tweaks to the documentation.
Full Changelog: v1.0.0b18...v1.0.0b20
v1.0.0b18
Fairly big release this time.
This release contains the following user-visible changes:
!electrostatic
and!gravity
forces now become constant when particles overlap to avoid unstable massive forces- The
!material
occlusion=
attribute has been renamed toao=
to make it clear that this is ambient occlusion !adjust
now supports acolor_matrix=
attribute for supplying a 3x3 matrix to apply to the RGB channels- Unused
!noise
channels are now filled with1
!physics
simulations can now use a new!group
node to control more precisely which forces apply to which particles. This is useful for reducing the computational complexity of large simulations.!drag
supports a newflow=
attribute for giving a flow velocity of the pretend medium- A new
!field
force was added to simulate uniform electric fields. - A
qbetween()
function was added for calculating the Quaternion to rotate one vector to another - The Oklab colourspace is now supported via new
oklab()
andoklch()
functions (both of which produce linear-sRGB colours) - We can now ask macOS to use the sRGB colourspace for windows iff the
pyobjc
andpyobjc-framework-Cocoa
packages are installed (these are now optional dependencies that can be installed withpip install flitter[macos]
- New
inf
andnan
constants were added to the language - The
gamma
attribute has been removed from all window nodes except!adjust
and the--gamma
command-line option has been ditched (this special pleading is no longer needed now that sRGB is more consistent across platforms) - Tone-mapping support has been added with the new
tonemap=
attribute to!adjust
, with the:reinhard
and:aces
functions implemented !adjust
also has newshadows=
andhighlights=
attributes for applying exposure adjustments to only the darkest/lightest parts of the image- Emissive lighting has a new algorithm that is partially dependent on the surface normal – this is an attempt to make emissive lighting less flat
- A new lens
!flare
filter has been added and, with it, new support for downsampled shader passes and a completely new texture/framebuffer pool-based architecture - New
shadows=
andhighlights=
attributes for!adjust
for doing exposure adjustments on the dark or light parts of images - Window
!transform
filter nodes now apply attributes in order like in!canvas3d
It also contains the following, less visible, improvements:
- The physics simulation of
!barrier
reflections has been improved significantly !random
forces are now seeded with a stable, reproducible seed (this caused problems previously when running tests)- Translucent objects are now rendered at the same time as transparent objects to ensure that the transparency ordering is maintained
- The structure of the internal PBR lighting shader was reworked so that the big stuff is now done in reusable functions in an include file – this is useful if you want to write a custom lighting shader that would like to use these standard functions (like my example SDF sphere shader)
- The plug-in API has been extended to 3D models; the
flitter.render.window.models
module was made usable from Python to support this - VM instruction optimisations were moved into the compiler instead of being done in a post-compilation pass. This works better as the compiler has access to more semantic information and can make better optimisation decisions.
- The lighting calculations for translucency were tweaked a bit
- The 3x3 matrix inverse calculation was broken and has now been fixed
!difference
with multiple non-overlapping subtraction models now actually works
Also a bunch of documentation improvements, though still no documentation for !canvas
.
Full Changelog: v1.0.0b17...v1.0.0b18
Release 1.0.0b17
This release contains a bunch of bug fixes, speed improvements, OpenGL ES compatibility fixes, additional tests, documentation fixes and improvements and the following user-visible changes:
- New
!transform
filter node for translating, scaling and rotating window nodes - New
!vignette
filter node for applying a simple, rectangular vignette (probably more advanced options coming later) uniform()
random variate now has 53 bits of pseudo-randomness instead of 32 – thebeta()
andnormal()
variates based on this are also extended- The
sample()
function now returns an RGBA 4-vector - Addition of
run_time
andframe
global names !video
nodes have newtrim=
andback_and_forth=
attributes for controlling trimming and looping backwards- New algorithm for computing
!sphere
meshes that generates half as many faces, with more even sizes - New
quaternion()
,qmul()
andslerp()
built-in functions for making and manipulating quaternions - The
rotate=
attribute of 3D!transform
nodes now accepts a 4-vector unit quaternion for specifying arbitrary rotations
Full Changelog: v1.0.0b16...v1.0.0b17
Release 1.0.0b16
This is a pretty big release that includes:
- A bunch of changes to support running coverage analysis against the tests. This is now done automatically in a GitHub workflow so you can continuously judge me on that last stubborn quarter of the codebase that is untested
- I did actually add more tests too though.
- I also fixed a few bugs that that testing revealed.
- An implementation of 4D noise was finally added to the built-in
noise()
andoctnoise()
functions. I have also finally properly attributed the source of the noise implementation. - The
sample()
function can now take a 2n-vector of coordinates to sample and will return a 4n-vector of RGBA color values. - A new
length()
function was added as a matching function toangle()
. This allows a 2n-vector of cartesian coordinates to be turned into a n-vector of polar distances. - The simplifier was completely reworked to return the original
Expression()
nodes when no simplification is possible. This means that the simplifier is faster (as it is doing less object creation) and the engine is able to skip recompilation if simplifying on state results in no change to the tree. This generally means that state simplifying is less noticeable. - Some simplifier rules were tidied up.
- A few VM optimisations were added (including a new ability to swap instructions where that usefully allows further optimisation to occur)
- A bunch of improvements were made to multi-pass
!shader
s that allowed all of my standard shaders to be moved in-engine as nodes. So you can now use (more flexible)!blur
,!bloom
, (color-)!adjust
,!feedback
and!noise
nodes. - Matrix maths was optimised by speeding up the creation of result matrices.
!slice
-ing of models is now done using manifold3d, which means it actually works instead of sometimes spitting out hopelessly broken meshes.- Making meshes watertight for CSG operations has been made saner and is now cached.
- The
!physics
extra-frame logic was completely redone as it had a habit of producing horrid visually-obvious speeding up of simulations. - 3D models are now cached forever and without limit. The LRU logic was a waste of time: if you're generating too many models to fit in memory then you have other problems that the cache can't solve.
- Instance depth-sorting can now be turned off with
depth_sort=false
on render groups. This is useful if you're creating thousands of small models and the sorting wastes more time than early fragment discarding can save. --autoreset
idle state resetting was dumped – it no longer achieves what it was intended to.
Breaking changes:
- The
clock
global name has been renamed totime
. None of my code was usingclock
anyway and it wasn't consistent with the way I use the idea of frame time everywhere else. - The (very weak) compatibility with the pre-PBR material model has been dumped. This means that the
shininess=
andspecular=
attributes on!material
have gone away. This was always a hack once I adopted PBR. You should be usingroughness=
andmetal=
instead.
Exciting new thing:
- Flitter now has plugins. In fact, all of the internal logic is implemented as built-in plugins. However, you can now add your own top-level renderers, window (OpenGL) nodes, controller drivers and DMX interface drivers through Python package entry points and an entirely undocumented API.
Full Changelog: v1.0.0b14...v1.0.0b15
Release 1.0.0b14
This release has the following changes from b13:
- Reworked the AST to be a pure expression tree, removing the ugly special pleading done for
Top
and also:- removing
Let
and makingInlineLet
the onlylet
(where
is just syntactic sugar) - making
Import
introduce names into a sub-expression the same aslet
- ditching the
StoreGlobal
stuff in favour of a newExport
mechanism that is injected into the last leaf of the AST via a parser rule matching EOF - extracting pragmas at parse time and storing them directly on the
Program
in the compiler
- removing
- Tighter restrictions on module imports – no more access to state – which allows module exports to be cached so that they are only run once (unless the source file changes)
- Addition of anonymous functions with new
func(x) x*x
syntax - Simpler for loops in the VM with the addition of tracking the number of bindings being done on each iteration in the
LoopSource
list; this allows ditching a few instructions from loops and dropping unnecessary operands from the loop instructions - A fix for a bug in simplifying on static state (it would collect old keys)
Plus it adds a heap more tests for the language in the form of unit/regression tests of the simplifier and compiler, and a bunch of integration tests of the language that test the interaction of the parser, simplifier, compiler and VM. Excitingly, these new tests unearthed a few significant bugs in the semantics and also shone a light on corners of the simplifier that could benefit from more work.
This release touches a lot of dangerous code in the language, but thanks to that mass of new tests I'm feeling pretty confident about it.
Release 1.0.0b13
This is just a packaging change over b12.
Release 1.0.0b12
This release includes:
- New rough n' ready translucency support
- OpenGL ES improvements
- A mass of fixes around using symbols with controllers
- Support for multi-pass shader nodes
Plus the usual background noise of fixes and small improvements.