Skip to contents

fill_marble() builds a grid::pattern() fill value resembling veined marble: a set of stripes parallel bands running around the tile's u axis, displaced by a fill_noise()-style torus-periodic turbulence field (via the shared internal torus_grid()/torus_noise() helpers) rather than left straight – the classic "sine of a coordinate plus turbulence" recipe for procedural marble.

Usage

fill_marble(
  color = c("white", "black"),
  spacing = 0.5,
  aspect = NULL,
  resolution = 32L,
  stripes = 3L,
  warp = 4,
  frequency = 1,
  octaves = 3L,
  seed = 1L,
  extend = "repeat"
)

Arguments

color

Two or more colours blended across each band, in order, via grDevices::colorRamp(). Default c("white", "black").

spacing

Baseline tile size, as a fraction of the target's bounding box. Must be a positive number. Default 0.5.

aspect

Width-to-height ratio of the target polygon's bounding box. Must be a positive number, or NULL (the default) to resolve it automatically from the real target's own bounding-box aspect ratio at draw() time – see the fill class. Passing a fixed number instead computes the pattern once, immediately, against that value only.

resolution

Raster resolution (pixels per tile edge). Must be a positive integer of at least 2L. Default 32L.

stripes

Number of bands running around the tile's u axis before turbulence displacement. Must be a positive integer. Default 3L.

warp

Turbulence amplitude, in radians of displacement along the band coordinate. Must be a non-negative number. Default 4.

frequency

Noise frequency, as in shape_blob(). Must be non-negative. Default 1.

octaves

Number of turbulence octaves, as in shape_blob(). Must be a positive integer. Default 3L.

seed

Integer seed for the noise field, as in shape_blob(). Default 1L.

extend

Passed to grid::pattern(). Default "repeat".

Value

A pattern object as returned by grid::pattern(), suitable for use as the fill argument to grid::gpar().

Details

Periodicity needs two things, both already true here: the undisplaced bands (sin(theta_u * stripes)) are periodic in u for any integer stripes, since theta_u itself advances by exactly 2 * pi over one tile width; and the turbulence added on top is periodic in both u and v because it comes from torus_noise(), the same torus-sampling technique fill_noise() uses for its own field. Adding one periodic function to another (here, inside a further sin()) stays periodic, so the combined result still tiles with no seam.

Unlike fill_noise() (opacity of one colour), the banding is rendered as a blend across color via grDevices::colorRamp(), since a marble texture's visual interest is the veining pattern itself rather than a fade to transparency.

fill_noise()'s own faint tile-boundary rasterization seam (see its details) can be more noticeable here: sin() turns a small mismatch in the turbulence field into a visibly sharper edge in a band than the same mismatch would produce in a plain opacity fade.

Examples

draw(shape_circle(fill = fill_marble(stripes = 4L, seed = 1274L)))


# more stripes and stronger warp give busier, more tangled veining
draw(shape_circle(fill = fill_marble(stripes = 8L, warp = 8, seed = 1274L)))


# a different colour pair changes the veining's contrast entirely
draw(shape_circle(
  fill = fill_marble(
    color = c("black", "goldenrod"),
    stripes = 4L,
    seed = 1274L
  )
))


# three or more colours blend across the band in sequence
draw(shape_circle(
  fill = fill_marble(
    color = c("black", "goldenrod", "white"),
    stripes = 4L,
    seed = 1274L
  )
))