Layers several color-sources into one spatial base color — stacking them back-to-front, each blended over the ones below with its own blend mode — the way to build a rich, multi-part surface color no single source could express.
JavaScript API:
CompositeColorSource
This is the layering member of the ColorSource family: like every
color-source it gives a material a base color that varies across the surface,
but instead of computing one color it composites a stack of child
color-sources. Children stack back-to-front over the flat base-color, each
blended onto the accumulated result beneath it and weighted by its own
applicability field, so where no child applies the stack simply IS the flat
base. It is the spatial sibling of sk-composite-color-map.
Key attributes. color-sources is the ordered, space-separated id-reference
list of the child sources (back-to-front). blend-modes is the matching
space-separated list of per-layer blend modes (normal, screen, multiply,
…), one per child; the mode lives on the composite entry, not on the child.
A child's own per-fragment alpha gates its layer coverage together with its
applicability field. For the source-over blend modes (normal, multiply,
screen, …), a fully transparent child sample is a no-op that leaves the
accumulated stack below unchanged, and a partially transparent sample
contributes proportionally to its alpha — so the transparent gaps of a
halftone-dot child reveal the layers beneath rather than darkening them under
multiply. (The additive plus-lighter mode sums coverage instead, so a
transparent child there still lowers the accumulated alpha.) Composites may
nest, and at most ONE raster child is supported per material (single texture
binding). The composite's own applicability field is applied by its consumer
exactly once.
Related. Its children are any color-sources — sk-color-map-source,
sk-raster-color-source, sk-paper-texture-color-source, or nested
composites. A material selects it with base-color-source="#id" (see
sk-plain-material). Its light-driven analogue for layering is
sk-composite-color-map.
Serve these docs to run the live example.
WebGPU needs a secure context — open this page via grunt serve
rather than double-clicking the file. The Markup tab works from disk.
<!-- Two color-sources composited into one base color on an imported mesh —
here BLENDING two full-surface layers, not masking them to regions. BASE:
a purple -> pink -> orange gradient swept up the model. TOP: a
black-and-white PAPER texture in the object's own space (triplanar, pinned
to the mesh) so the grain stays stuck to the surface as it turns, `overlay`
blended so the grain modulates the gradient's light and dark. Read
`blend-modes` (normal + overlay): overlay is what fuses texture into
colour. -->
<sk-scene>
<sk-directional-light p="42deg" h="130deg" intensity="1.0"></sk-directional-light>
<sk-ambient-light intensity="0.4"></sk-ambient-light>
<!-- BASE layer: a colour gradient swept up the model (its +Z ramp rotated
to +Y with p="-90deg"), driven by a vertical field. -->
<sk-linear-gradient-field id="up" y="-3" extent="6" p="-90deg"></sk-linear-gradient-field>
<sk-ramp-color-map id="ramp">
<sk-color-stop stop-offset="0" stop-color="#833AB4"></sk-color-stop>
<sk-color-stop stop-offset="0.5" stop-color="#FD1D89"></sk-color-stop>
<sk-color-stop stop-offset="1" stop-color="#FCB045"></sk-color-stop>
</sk-ramp-color-map>
<sk-color-map-source id="grad" color-map="#ramp" intensity-field="#up"></sk-color-map-source>
<!-- TOP layer: neutral-grey paper grain, projected in the mesh's OWN space
(projection-node="#scooter") so it rides the rotation. -->
<sk-paper-texture-color-source id="paper" projection="triplanar" projection-node="#scooter"
mottle="6" mottle-scale="10" tooth="10" tooth-scale="1" fine="4.2" speck="5.4"
contrast="1"></sk-paper-texture-color-source>
<!-- Stack them: gradient with `normal`, paper `overlay` on top. -->
<sk-composite-color-source id="comp" color-sources="#grad #paper"
blend-modes="normal overlay"></sk-composite-color-source>
<sk-plain-material id="mat" base-color="white" base-color-source="#comp"></sk-plain-material>
<sk-mesh id="scooter" src="/js-assets/skenra/demos/html/scenes/scooter.obj"
normalize-scale="3" anchor="center">
<sk-surface-paint material="#mat"></sk-surface-paint>
<sk-animation duration="9000ms" iterations="Infinity">
<sk-keyframe offset="0" h="0deg"></sk-keyframe>
<sk-keyframe offset="1" h="360deg"></sk-keyframe>
</sk-animation>
</sk-mesh>
</sk-scene>
| Attribute | Type | Default | Description |
|---|---|---|---|
id |
<id> |
— | The element's unique identifier — the standard HTML global id attribute. |
color-sources |
<id-ref-list> (<id-ref>[,<id-ref>]*) |
"" |
The color-sources <id-ref-list> as a property. Reads / writes |
blend-modes |
<blend-mode-list> (<blend-mode>[,<blend-mode>]*) |
"" |
The companion blend-modes list as a property. Reads / writes the |
color-interpolation |
<blend-color-interpolation> ("auto" | "srgb" | "srgb-linear") |
"auto" |
The color space this composite runs its per-layer BLEND + weight-mix |
fieldanimatable |
<id-ref> |
— | Gets the optional applicability field that masks where this source reference by id |
xanimatable |
<number> |
0 |
Gets the X position component. |
yanimatable |
<number> |
0 |
Gets the Y position component. |
zanimatable |
<number> |
0 |
Gets the Z position component. |
hanimatable |
<angle> |
0 |
Gets the heading (Y-axis) rotation in radians. |
panimatable |
<angle> |
0 |
Gets the pitch (X-axis) rotation in radians. |
banimatable |
<angle> |
0 |
Gets the bank (Z-axis) rotation in radians. |
visualize |
<boolean> |
false |
Whether the visualization is visible (wireframe splines + center marker). |
interactive-controls |
<boolean> |
false |
Whether interactive controls are shown (draggable markers for adjusting parameters). |