Compiler Reference
Overview
The renderlet compiler (rlc) takes a YAML-based file, called a renderspec, that provides a declarative definition of graphics pipelines.
rlc generates backing C++ code from the renderspec, and uses LLVM to link together all code, library modules, and graphics data into a renderlet - a self-contained WebAssembly binary.
Format
A renderspec is a YAML container for multiple formal grammars - each grammar providing a series of attributes (data) and rules (code), each made up of a list of operators:
grammars:
version: "0.1"
grammar:
-
attr:
-
name: "height"
value: "28.0"
rule:
-
name: "Start"
op:
-
extrude:
height: "height"
Objects:
version: The currentrenderspecversion:0.1grammar: A list of grammars, link-time bound to modules. Each grammar is translated to an exported Wasm function / graphics object to be called.attr:attributewith a default values, and optionally ranges, that can be overriden at runtime based on the input data (see the documentation in thewanderSDK)name: Attribute namevalue: Attribute initial valuerange(optional): Attribute value range ("<min>, "<max>")
ruleA named list of operators that may be referenced from other rules in the treename: Rule nameop: Operator list (run sequentially)
shapes: Allows procedural shapes to be specified directly in therenderspecrectangleandpolygoncurrently supported - see example
exports: Functions and parameters passed into the procedural program from the host- Currently custom exports are not used
Modules
renderlet includes 5 modules by default:
- Pipeline
- 2D
- 3D
- Vector
- Procedural
Only Procedural is currently exposed to the renderspec in the renderlet playground. Assumptions are made about the pipeline state, and 2D and 3D geometry are implicitiy
We are working on an SDK to add your own modules with C++ or Rust.
Please check back frequently as we expand the features of the renderspec and the wander runtime library.
Procedural Operators
Procedural: Version 0.1
This module provides a library for procedural modeling of geometry using a shape grammar, heavily inspired both by CityEngine's CGA.
The Procedural package exports the following operators:
center
Centers the scope of the object about an axis or axes.
Parameters:
axesSelector(EAxesSelector): The axis or axes to center about, one of:XYZXYZXYXZ
Example:
center:
axesSelector: "X"
color
Sets the color of the object to a static value using rgb components or hex codes.
Components are in the range of 0.0f - 255.0f, hex string is #RRGGBB.
Parameters:
-
r(float (expression)): The red color component -
g(float (expression)): The green color component -
b(float (expression)): The blue color component -
s(string (expression)): Must evaluate to a string of (#RRGGBB) format, sets all rgb components
Example:
color:
r: "32"
g: "128"
b: "64"
color:
s: "#a3875e"
comp
Splits a piece of 3D geometry into its 2D components.
Each face that is selected is then pushed into the render tree and passed to another rule
Currently only face splits are supported, and the face selector is implied.
More details are available in the CGA documentation.
Parameters:
-
-(list): list of component splitsname(ESelector): Component to split by, one of:frontbackleftrighttopbottomsideunselected
value(string): Rule name to evaluate the split geometry, ORvalues(list): Proportionally weighted list of Rule names to evaluate the split geometry (forsideorunselected)weight(float (expression)): Proportion of totalweights (normalized) to route randomly to this rulevalue(string): Rule name to evaluate a portion of the split geometry
Notes:
sideroutes all side faces (including anyfront,back,left, andright) to the same rule(s)unselectedroutes all remaining faces not covered by another selector to the same rule(s)- To add shapes to the output without further processing, select them and route them to the
nullrule - Any remaining shapes not covered by a selector are discarded
frontface selector on aprimsreturns the first side - no other sides use semantics
Example:
comp:
-
name: "front"
value: "Facade"
-
name: "top"
value: "Top"
-
name: "bottom"
value: null
-
name: "unselected"
values:
-
weight: 3
value: "FacadeA"
-
weight: 1
value: "FacadeB"
# Distribute sides across FacadeA and FacadeB randomly at a 3:1 ratio
...
name: "Top"
op:
-
# additional operators for the "top" face here
copy
Copies another rule in the render tree into this location.
Parameters:
name(string): The rule name to copy
Example:
copy:
name: "Rule2"
...
rule:
-
name: "Rule2"
op:
-
cornerCut
!! Not currently supported through YAML interface !!
Symmetrically cuts the corner off of a rectangular surface, generating a chamfer or fillet.
Parameters:
name(ECornerCut): Component to split by, one of:straight- generate a chamfercurve- generate an external filletnegativeCurve- generate an inner fillet
length(float (expression)): Distance from corner (horizontal and vertical) to generate the cut
Example:
cornerCut:
type: "straight"
length: "12.0"
extrude
Performs a geometric extrustion, transforming a 2D shape into a 3D shape.
Parameters:
height(float (expression)): Amount to extrude by (in the scope's Z axis)
Example:
extrude:
height: "10.0"
gable
Extrudes a 3D hip roof gable from a 2D shape.
!! This does not yet support polygons, only rectangles !!
For a polygon, this requires a stright skeleton.
Parameters:
angle(float (expression)): Angle of the roof from all points to the straight skeletop, degrees
Example:
gable:
angle: "20"
hemisphere
!! Not currently supported through YAML interface !!
Extrudes a circular shape into a hemisphere / cap.
When applied to non-circular shapes, generates a pyramid with a height bounded by the shape's scope.
Parameters:
- None
Example:
hemisphere:
hip
Extrudes a 3D hip roof shape from a 2D shape.
For a polygon, this requires a stright skeleton. For a rectangle, this is analogous to pyramid.
Parameters:
angle(float (expression)): Angle of the roof from all points to the straight skeletop, degreesoffset: (float (expression), optional): Horizontal offset applied to all points to make roof "overhang", meters (>0)
Example:
hip:
angle: "20"
offset: "0.8"
innerCircle
!! Not currently supported through YAML interface !!
Replaces a rectangle/square with the circumscribed ellipse/circle.
Parameters:
- None
Example:
innerCircle:
innerSemiCircle
!! Not currently supported through YAML interface !!
Replaces a rectangle/square with the circumscribed semi-ellipse/semi-circle.
Parameters:
- None
Example:
innerSemiCircle:
insert
!! Not currently supported through YAML interface !!
Inserts static 3D geometry from a supported parser (gltf, obj) into the render tree
Parameters:
path(string): Path to geometry file(s)
Example:
insert:
path: "/files/teapot.obj"
offset
Grows (or shrinks) a shape by a positive (or negative) value.
The resulting shape is passed to two (optional) rules for further processing: border and inside. Inside is the new shape, and border is the delta (positive or negative faces) from the starting shape.
More details are available in the CGA documentation.
Parameters:
distance(float (expression)): Amount to scale every edge's normal byborder: (string, optional): Rule name to evaluate the delta geometryinside: (string, optional): Rule name to evaluate the scaled geometry
Example:
offset:
distance: "-2.0"
border: "Wall"
inside: "AwningInside"
pyramid
Performs a geometric extrustion to a pyramid, forming a volume with a line drawn from every point of the shape to its centroid at a given height.
Parameters:
height(float (expression)): Amount to extrude by
Example:
pyramid:
height: "10.0"
rotate
Rotate the shape around an axis or axes.
Parameters:
x(float (expression), optional): Amount to rotate around x axis, degreesy(float (expression), optional): Amount to rotate around y axis, degreesz(float (expression), optional): Amount to rotate around z axis, degrees
Example:
rotate:
x: "-45.0"
y: "yAmount"
setupProjection
Setup texture projection to UV coordinates across the object's scope.
The coordinates are maintained/recalculated across the shape's lifecycle in the shape tree unless another setupProjection applies later in the tree.
More details are available in the CGA documentation.
Parameters:
axes(EAxesSelector): The axis or axes to center about, one of:scope.xy- In the horizontal plane of the shape's scopescope.xz- In the vertical plane of the shape's scope
face.xy- In the horizontal plane of the scope of each face of the 3D shape (currently only supported onHip)width(Object): Projection in the width (U) directionvalue(float (expression)): Width of texture in world unitstype(Size::Type): Type ofvalue, one of:absolute- absolute world unitsrelative- relative to the scope of the object
height(Object): Projection in the height (V) directionvalue(float (expression))type(Size::Type)
Example:
setupProjection:
axes: "scope.xy"
width:
value: "1"
type: "relative"
height:
value: "1"
type: "relative"
shapeL
!! Temporarily disabled in the YAML interface !!
Replaces a rectangle/square with the circumscribed "L" shaped polygon.
Parameters:
frontWidth(float (expression)): Width of the vertical part of the "L"rightWidth(float (expression)): Height of the bottom part of the "L"
Example:
shapeL:
frontWidth: "3.0"
rightWidth: "2.0"
shapeU
!! Temporarily disabled in the YAML interface !!
Replaces a rectangle/square with the circumscribed "U" shaped polygon.
Parameters:
frontWidth(float (expression)): Width of the vertical parts of the "U"backDepth(float (expression)): Height of the bottom part of the "U"
Example:
shapeU:
frontWidth: "4.0"
backDepth: "2.0"
size
Resize a shape's scope vector.
Parameters:
centered(bool, optional): Center the output along all axesx(float (expression), optional): Size of X axisvalue(float (expression)): New sizetype(Size::Type): Type ofvalue, one of:absolute- absolute world unitsrelative- relative to the scope of the object
y(float (expression), optional): Size of Y axisvalue(float (expression))type(Size::Type)
z(float (expression), optional): Size of Z axisvalue(float (expression))type(Size::Type)
Example:
size:
centered: "true"
x:
value: "width"
type: "absolute"
y:
value: "depth"
type: "absolute"
z:
value: "0"
type: "absolute"
split
Splits a piece of geometry into mutliple geometric objects.
For example, a rectangle can be split into a series of component rectangles of specified horizontal or vertical sizes.
Each new shape is inserted into the tree and further processed by the specified rule.
Note, when mixing repeat and floating, all repeatable floats are calculate first, and any non-repeatable floats will not float.
If there are no repeatable floats, non-repeatable floats will then float to fill the remaining scope.
More details are available in the CGA documentation.
Parameters:
axis(EAxis): Axis to split by, one of:XYZ
sizes(list): List of sizes for each componentvalue(float (expression)): Size of the splitname(string): Rule name to evaluate the split geometryrepeat(bool, optional): Whether this split continues until scope is filledtype(Size::Type): Type ofvalue, one of:absolute- absolute sizerelative- relative size to the scope of the objectfloating- size is adjusted to fill remaining space
Example:
split:
axis: "y"
sizes:
-
value: "FloorHeight"
name: "Floor"
repeat: "true"
type: "floating"
-
value: "DividerHeight"
name: "Wall"
type: "floating"
taper
Performs a geometric extrustion to a taper.
Logically, a taper is like a pyramid with the top sliced off, forming a shape similar to a mesa, with a chamfer on every edge.
A volume is formed from a line drawn from every point of the shape to its centroid at a given angle, up to a given height. A top surface is added of the starting shape scaled to the remaining area to close the volume.
Parameters:
height(float (expression)): Height of the extruded volumeangle(float (expression)): Angle of the volume from all points, extruded up toheight, degrees Example:
taper:
height: "10"
angle: "45.0"
texture
Sets a texture on a face with a path to a file linked into the renderlet.
You can use any path/filename you want. For it to show in the web editor, uploaded it in the "View Textures" dialog.
The filename will be copied to the material properties (.mtl file for server-side rendering, metadata in the .rlt wire format), and one can load and attach on the host side. Bundling textures into the renderlet will be supported soon
Parameters:
path(string): Path to texture file
Example:
texture:
path: "window_glass.png"
translate
Translate an object in 3D space.
Translations can be performed on any axis, relative to absolute world space, relative world space, or relative object space.
Additionally, translation of each axis can be performed in absolute units, or relative to an object's scope.
Parameters:
mode(EMode): Sets how translation is appliedabs- Sets absolute position tovaluerel- Moves position byvalue
coordSystem(ECoordSystem): Sets coordinate system for translationsobject- Object space (origin of scope vector)world- World space (origina of world vector)
x(float (expression), optional): Position on X axisvalue(float (expression)): Amounttype(Size::Type): Type ofvalue, one of:absolute- absolute world unitsrelative- relative to the scope of the object
y(float (expression), optional): Position on Y axisvalue(float (expression))type(Size::Type)
z(float (expression), optional): Position on Z axisvalue(float (expression))type(Size::Type)
Example:
translate:
mode: "rel"
coordSystem: "object"
x:
value: "12.0"
type: "absolute"
z:
value: "0.5"
type: "relative"