Help
underconstruction.gif
When you first visited Bauble, you were greeted by an interactive tutorial. You can restore it by deleting your script (just clear out the text field) and then refreshing the page. Make sure to save a backup of your script if you’ve done something interesting!
Some general notes:
- Argument order is usually not significant; only the types of values
are significant. Argument order is significant when a function
takes multiple arguments of the same type, such as
torus
– the major radius must come before the minor radius. - Probably the most useful functions in order are
move
,union
,rotate
, the shape primitives,color
, andshade
.
All of the examples on this page are interactive. To prevent annoying scroll hijacking, you have to click on a canvas to focus it before you can zoom.
Function reference
- Shapes
- Spatial operations
- Hybrid spatial/surface operations
- Repetition
- Operations on color
- Meta-operations
- General helpers
- GLSL functions ported to Janet
- Janet functions ported to GLSL
- Functions that are the same
- Color constants
Shapes
A quick list of all shape primitives:
sphere
sphere
is the simplest of all primitives. It has only
one parameter: the radius.
box
box
can take a single float
dimension or a
vec3
.
The dimensions you supply to box
are twice the size that
the box appears. Think of them like a radius: a box of “width 50” will
range from p.x = -50
to p.x = 50
.
:r
to round the edges.
cylinder
The second argument is twice the height of the cylinder, which is centered at the origin.
:r
to round the edges.
ellipsoid
Not an exact distance field! This is an approximation that produces better results than scaling a sphere, but that is still only an approximation.
line
The two vec3
arguments are the start and end points. An
optional float
argument is the radius of the line (default
0
).
torus
half-space
This one is very hard to show with images, because it just looks like a flat-colored plane of infinite extent. Instead, it’s easier to understand when used as an input to a boolean operation:
The first argument is a signed axis, and the second optional argument is the position along that axis.
cone
Unlike most other shapes, which are centered at the origin, the cone rests at the origin, and the height you pass it is the cone’s actual height, not one half of its height. It’s still the extent of the cone in a single axis, like other shapes, but unlike most shapes the cone does not extend in both directions.
:r
to round the edges.
ground
ground
should not be used in actual art, but it’s useful
for debugging. It’s kind of a “(half-space :-y)
that you
can see through,” so that you can add a ground to see shadows, and still
move the camera around to view the underside of your shape.
It is not an actual distance field (the distance depends on the position of the camera), so it will not work well with morphs, boolean operations, or ambient occlusion. It’s really just for quickly looking at shadows.
Spatial operations
move
Can take a vec3
elements or named :x
,
:y
, and :z
float arguments. You can mix and
match these forms, and the computed sum will be used.
move
is also a great way to distort shapes.
rotate
Takes named :x
, :y
, and :z
arguments; the final rotation is the combination of each rotation in
order. There is no vector form because the order of the rotations is
significant: (rotate :x 1 :y 1)
is not the same as
(rotate :y 1 :y x)
.
You can also pass :pivot
, with a vec3
that
will form the point around which rotation happens.
You can also optionally supply scale arguments, which will multiply
the rotations following that scale argument by a fixed amount.
Valid scales are :pi
, :tau
, or
:deg
. You can change scale mid-rotation, for example by
saying (rotate :deg :x 45 :tau :y 0.125)
. This is
equivalent to (rotate :x tau/8 :y tau/8)
.
scale
Can take a single float
, a vec3
, or named
:x
:y
:z
parameters. Like move
, you can mix and match these forms
and the final product will be used as the scale factor for each
axis.
If you scale by different amounts across different axes, the distance
field produced will be an underestimate. This means that Bauble can
still raymarch it accurately without the use of slow
, but soft shadows and boolean
operations will be inaccurate.
offset
Name will probably change.
Good way to apply texture to a shape, although if your expression is
expensive you should use bounded-offset
instead.
onion
float
argument is half of the thickness. The shape will
be both inset and outset by this amount.
distort
This allows you to supply an arbitrary expression that will replace
p
. You can use this to deform space in ways that are not
possible with any of the built-in operators.
This is by its nature a bizarre operation that can be used to do anything, including implement any of the other spatial distortion operations, so examples are not very informative.
mirror
Interior distances will have discontinuities when a shape crosses the axis.
You can specify multiple axes to mirror along. The optional
:r
argument makes this a smooth mirror.
reflect
Like mirror, but doesn’t create a copy. Can take multiple axes.
mirror-plane
TODO
mirror-space
TODO
symmetry
It’s hard to describe this one. It mirrors space across every axis and also flips it across every axis of rotation. You end up with only a tiny sliver of useful space that you can put a shape in, so it’s only really suitable for abstract things.
flip
Rotates the shape 90° around a signed axis (so :x
rotates counter-clockwise, :-x
rotates clockwise). More
efficient than rotate
.
twist
float
argument is the rate of rotation, in radians per
unit distance.
This is equivalent to a rotation around an axis that varies with
p.(axis)
, but it might be slightly more efficent.
Does not produce a correct distance field.
swirl
float
argument is the rate of rotation, in radians per
unit distance.
This is equivalent to a rotation around an axis that varies with
(length p.(other axes))
, but it might be slightly more
efficent.
Does not produce a correct distance field.
bend
This operation is weird and hard to explain and I will probably get rid of it.
Does not produce a correct distance field.
map-distance
Apply a function to a shape’s distance field. Can be used to do weird
things. Many operations, like offset
or slow
,
are simple transformations on the underlying distance field. For
example, offset
:
Hybrid spatial/surface operations
The boolean operations union
, intersect
,
and subtract
can all take an optional :r
value, but note that this will make color calculations slower:
all surfaces will be evaluated, even those that do not
contribute at all to the final result. When used without
:r
, or with an :r
value of 0
(as
evaluated on the CPU – any symbolic expression will cause Bauble to take
the slow branch), only the one relevant surface will be evaluated.
Because of this, you should prefer to apply surfaces after smooth boolean operations, unless of course you are relying on the surface blending. Even if it’s the same surface, Bauble will still evaluate it multiple times! (This is a fixable deficiency in Bauble but it is the way that it is right now.)
union
Union produces a correct distance field unless shapes overlap, in which case the interior distance field will be discontinuous.
intersect
Does not produce a correct distance field.
subtract
Does not produce a correct distance field.
morph
Produces incorrect distance fields when the amount is outside of the
range [0, 1]
.
Repetition
tile
Tile divides space into rectangular regions.
The vec3
argument determines the size of each tile, with
0
meaning that no repetition takes place in that direction.
By default the shape will be repeatedly infinitely in every direction,
but the optional argument :limit
will clamp the
repetition.
:limit
must be a tuple of three positive integers; you
cannot write a dynamic expression for :limit
.
If you provide a function argument instead of a shape, your function
will be called with an expression for the current index of the tiling.
This allows you to produce different objects at each instance of the
tiling. The index will always be a vec3
, even if you are
not repeating in all three directions.
Indexes are integers, so the index of the element at the origin is
[0 0 0]
, the index to the right of that is
[1 0 0]
, etc.
You can also provide a shape and a function, in which case
the shape will be passed as the first argument to your function. By
appropriating a little bit of Janet convention, we call this argument
$
, for $hape
. This is useful for fitting
tile
into a pipeline:
Asymmetry
The way tile
works is that, for each step of the
raymarch, it computes the current “slice” of space. Then it evaluates
only that one slice, and returns the nearest distance.
This means that, if the actual nearest shape is in a different tile than the current one, this will produce an invalid distance field.
Here you can see lots of artifacts around the edges of the boxes,
where rays overshoot their targets. The solution to this problem, if you
want to tile an asymmetric shape, is to first duplicate the shape a
small number of times (with union
) and then to tile that
array of shapes with overlap.
A future version of Bauble will have a helper to make this more convenient.
radial
Similar to tile
, but repeats radially. Requires an axis
and a count. Can optionally take a number that will determine how far to
outset the shape before repeating it (default 0
).
Like tile
you can supply a mapping function (with a
shape) or a producing function (without a shape). The index will be an
integer in the range [0, count)
. As with tile
,
only a fraction of space is considered at once, so asymmetric shapes
will produce invalid distance fields.
Operations on color
shade
fresnel
cel?
resurface
map-color
color
Meta-operations
bound
bounded
bounded-offset
slow
pivot
General helpers
fork
spoon
remap+
(andsin+
,cos+
,perlin+
)hsv
hsl
rgb
hex-rgb
pi
,pi/2
,pi/3
, etctau
,tau/2
,tau/3
, etcdeg
tau*
,pi*
,tau/
,pi/
ss
hash
functionsperlin
GLSL functions ported to Janet
sign
clamp
step
(note: argument order reversed)smoothstep
distance
dot
mix
min
(note: overloaded better)max
(note: overloaded better)fract
normalize
sqrt
length
/vec-length
pow
(note: overloaded better)
Janet functions ported to GLSL
sum
product
atan2
(note: safer thanatan
)
Functions that are the same
sin
cos
abs
round
floor
ceil
atan
mod
Color constants
(def red (hsv (/ 0 6) 0.98 1))
(def orange (hsv (/ 0.25 6) 0.98 1))
(def yellow (hsv (/ 1 6) 0.98 1))
(def green (hsv (/ 2 6) 0.98 1))
(def cyan (hsv (/ 3 6) 0.98 1))
(def sky (hsv (/ 3.5 6) 0.98 1))
(def blue (hsv (/ 4 6) 0.98 1))
(def purple (hsv (/ 4.5 6) 0.98 1))
(def magenta (hsv (/ 5 6) 0.98 1))
(def hot-pink (hsv (/ 5.5 6) 0.98 1))
(def white [1 1 1])
(def light-gray [0.75 0.75 0.75])
(def gray [0.5 0.5 0.5])
(def dark-gray [0.25 0.25 0.25])
(def black [0.03 0.03 0.03])