LambdaCube 3D

lambdacube3d.com

A Little History

The LambdaCube adventure started in the beginning of 2009, when Csaba decided to create an Ogre3D compatible engine in Haskell. At this time, Gergely was a postgraduate student at BME (Technical University of Budapest) doing research aimed at applying functional programming in various areas – interactive applications and embedded systems –, and he ended up mentoring Csaba over the years thanks to their overlap in interests.

Originally Csaba intended the engine to act as a drop-in replacement for Ogre3D, including the ability to read and display all the existing assets without the need for conversion. The first incarnation of LambdaCube was therefore a traditional rendering engine based on a hierarchical scene graph, offering an essentially C-style imperative API. Around this time we also submitted it to the Jane Street Summer Project program and it ended up as a finalist.

Afterwards, the project went dormant for nearly two years. We did some work under the hood, but only very sporadically as life would deliver its distractions during this period. In mid-2011 we finally released a new version of the engine whose main contribution was defining an actual public API. This required a major clean-up job, but in hindsight the actual improvements were really minor. We basically wrapped all the operations of the engine in an extra monadic layer called LCM (guess what it stands for!), which took care of resource management under the hood. This was also the moment where we switched to the raw OpenGL bindings.

As the announcement for the above release stated, at this point we realised that the direction we had been pursuing was really a dead-end. Trying to shoehorn an imperative API into a purely functional language felt like a constrant struggle against the elements. We went back to the drawing board and came up with a different plan: let’s take inspiration from GPipe and create a purely functional model of the rendering pipeline. We set the goal of creating an independent DSL, but starting to evolve it as a Haskell EDSL at first.

Unfortunately, progress had to slow down due to the team becoming physically separate, as Gergely moved to Finland and became a game developer shortly after the announcement. It took another year before we would reveal the first public version of the new library in the summer of 2012. We also started the LambdaCube3D blog.

The LambdaCube language was designed to be feature complete and safe by construction from the beginning. We deviated from GPipe’s design in a number of ways to achieve this, e.g. by introducing explicit contexts for various rendering phases or defining shaders as explicit functions instead of mapping over streams. We also leverage the type system to encode the constraints of shader languages. As an important design decision, we clearly separate data (geometry) from logic (pipeline), which goes against the long-standing tradition of coupling meshes with materials, but it allows us to describe complex effects and their compositions with surface materials in a modular manner, and makes it easier to implement hot-swapping both for assets and pipelines.

In 2013 we introduced the LambdaCube Intermediate Representation (IR), which was the next logical step on the path to the independent DSL. The IR allows us to separate the frontend and the backend, and ultimately compile a single pipeline description to several platforms.

Work on the actual DSL started in 2014. This was the time when Péter joined the team, first working on our beloved Stunts example, then moving on to the compiler project itself. The last months preceding the big tour in 2015 were spent building the online editing environment.

LambdaCube 3D Tour 2015

In 2015 we went on a tour around Europe presenting LambdaCube 3D. Our main motivation was to collect feedback from potential LambdaCube 3D users.

Destinations

City Date Organisation + event link
Budapest Monday, May 20, 7:00 PM Budapest Haskell User Group
Munich Wednesday, May 27, 7:00 PM Munich-Lambda
Zurich May 29 - May 31 ZuriHack 2015Projects
Paris Tuesday, June 2, 7:00 PM Functional Programmers Paris
London Friday, June 5, 6:30 PM London Haskell
Cambridge Wednesday, June 10, 7:00 PM Cambridge NonDysFunctional Programmers
Nottingham Friday, June 12, 7:00 PM CompSoc Nottingham
London (2) Wednesday, June 17, 7:00 PM Mobile and Games Dev
Amsterdam Saturday, June 20, 7:00 PM FP AMS
Berlin Tuesday, June 23, 7:30 PM Berlin Haskell Users Group
Copenhagen Tuesday, June 30, 6:00 PM Copenhagen Tech Polyglot Meetup
Gothenburg Thursday, July 2, 7:00 PM Got.λ - Göteborg Functional Programming Group
Helsinki Tuesday, July 7, 6:00 PM Helsinki Haskell Users Group

Development history

date feature
2016.01.18. Improved quake renderer: support for game models and character animations
2016.01.03. LambdaCube 3D Docker image for development and Travis CI
2015.12.30. Roadmap for the next 6 months
2015.12.30. Continuous integration with Travis CI
2015.12.19. Switch to new compiler (lots of improvements; faster & better)
2015.10.22. C++ backend for OpenGL ES 2.0
2015.10.04. Fast reducer prototype
2015.09.19. Data definition language which supports Haskell, PureScript and C++
2015.09.17. Dependent type inference prototype
2015.09.02. Pattern match compilation
2015.06.07. Geometry can be defined in LambdaCube 3D now
2015.06.04. Texture support
2015.05.31. New language features: list comprehension, dot-dot expression
2015.05.29. New language feature: export lists
2015.05.19. Initial editor with error highlight, type popups, auto compilation
2015.05.17. WebGL backend in PureScript
2015.05.16. New language features: operator precedences; swizzling
2015.05.12. New language feature: first version of type classes
2015.04.29. New language feature: type-level literals
2015.04.28. New language features: type arguments; first version of GADTs
2015.04.13. OpenGL 3.3 backend in Haskell
2015.04.10. New language feature: support row polymorphism
2015.04.04. OpenGL constraints modelled with type families work in the DSL
2015.02.25. Use System-F as core language
2015.02.14. First working example in DSL: rotating cube
2015.02.12. First implementation of compositional typing