Skip to main content
Version: 5.x
Supported on
Snapchat
Camera Kit

Custom Text2D Materials

Custom Text2D materials let you apply custom shader effects to a 2D Text component.

Default Text2D Material

To get started, create a new Text2D material from Asset Browser ➜ + ➜ Materials ➜ Text2D.

Custom Text2D Materials figure 3

The default shader graph will include a Text Data node and a Surface Position (World) node wired into a Mesh3D shader node.

Custom Text2D Materials figure 4

The material has default values set to its parameters to match that of the built-in text material. Importantly, the default blend mode of the material is set to Normal.

Custom Text2D Materials figure 5

Assign this material as-is to the "Material" field on a Text component for it to render the same as the built-in text material.

Custom Text2D Materials figure 6

Text Data Node

Custom Text2D Materials figure 1

PortTypeApplicable ToDescription
Pass IdentifierFloat (integer-valued)Vertex and Fragment

All passes
Which text pass this quad belongs to:
  • Main = 0.0
  • Color (emoji) = 1.0
  • Shadow = 2.0
  • Outline = 3.0
  • Background = 4.0
  • Decoration (underline/strikethrough) Main = 5.0
  • Decoration Outline = 6.0
  • Decoration Shadow = 7.0
Coverage Alpha Masked Colorvec4Fragment only

All passes
The resolved Quad Color with the per-pass Coverage Alpha Mask multiplied into alpha. Equivalent to vec4(quadColor.rgb, quadColor.a * coverageAlphaMask).

Wire this directly into the Color port on the Mesh3D master node to get correctly shaped passes with the proper fill color from the text component.
Quad Colorvec4Fragment only

All passes
Per-pass fill color without the alpha coverage mask. Takes into account fill color, rich-text color and opacity tags, emoji textures, fill textures, and color tint.
Coverage Alpha MaskFloat [0,1]Fragment only

All passes
Per-pass coverage alpha/opacity mask:
  • SDF or bitmap glyph alpha mask for Main/Outline/Shadow passes.
  • Emoji alpha mask for the Color pass.
  • Background rect alpha mask for the Background pass (for example, corner radius).
  • Decoration-bar alpha mask for Decoration passes (to get the proper thickness of decoration segments).
SDF DistancefloatFragment only

SDF passes only: Main, Outline, and Shadow
Spread-normalized signed distance to the glyph edge:
  • Equal to 0 at the glyph edge.
  • Positive inside the glyph until 0.5, which is the max baked SDF distance inside the glyph.
  • Negative outside the glyph until -0.5, which is the max baked SDF distance outside the glyph.
  • Spread-normalized means the physical reach of the SDF distance gradient scales with the SDF Spread setting on the Text Data node. A wider SDF Spread makes the [-0.5, 0.5] range visibly wider.
Note: for the Outline pass (or the Shadow pass with outline enabled), an SDF distance of 0 refers to the outline edge, not the main glyph edge.
UVVec2Fragment only

All passes
If FillMode:Color: per-quad UV normalized with (0,0) at the bottom-left corner and (1,1) at the top-right corner.

If FillMode:Texture: the component's per-pass fill UV, driven by that pass's Tile Count / Tile Zone / Stretch Mode. Sample your own Texture 2D with it for textured fills, or make screen/layout-rect-spanning effects.

Custom Text2D Materials figure 2

SDF Spread determines how far, in em units, the signed distance field extends outward from the glyph edge before it saturates, which increases the mesh size of the glyph quads. This lets larger effects like glow extend past the default quad size allocated for glyphs.

Custom Code Node Accessors

AccessorCorresponding Port
system.getTextPassIdentifier();Pass Identifier
system.getTextCoverageAlphaMaskedColor();Coverage Alpha Masked Color
system.getTextQuadColor();Quad Color
system.getTextCoverageAlphaMask();Coverage Alpha Mask
system.getTextSdfDistance();SDF Distance
system.getTextUv();UV
system.setTextSdfSpreadDefault();Setting SDF Spread to Default
system.setTextSdfSpreadMedium();Setting SDF Spread to Medium
system.setTextSdfSpreadLarge();Setting SDF Spread to Large
system.setTextSdfSpreadMax();Setting SDF Spread to Max

Examples

For all of the following examples the following Text component parameters are used:

Custom Text2D Materials figure 7

Without any custom material it looks like the following:

Custom Text2D Materials figure 8

Pass Identifier

Use Pass Identifier to customize different behavior for each of the text passes.

Custom Text2D Materials figure 9

Add the following code to the Custom Code node:

input_float passId;
output_vec4 result;
void main()
{
vec3 rgb = vec3(1.0, 1.0, 1.0); // fallback (unknown pass) = white
if (passId == 0.0) rgb = vec3(1.0, 0.0, 0.0); // MAIN_PASS - red
else if (passId == 1.0) rgb = vec3(0.0, 1.0, 0.0); // COLOR_PASS - green
else if (passId == 2.0) rgb = vec3(0.0, 0.0, 1.0); // SHADOW_PASS - blue
else if (passId == 3.0) rgb = vec3(1.0, 1.0, 0.0); // OUTLINE_PASS - yellow
else if (passId == 4.0) rgb = vec3(1.0, 0.0, 1.0); // BACKGROUND_PASS - magenta
else if (passId == 5.0) rgb = vec3(0.0, 1.0, 1.0); // DECORATION_PASS - cyan
else if (passId == 6.0) rgb = vec3(1.0, 0.5, 0.0); // DECORATION_OUTLINE_PASS - orange
else if (passId == 7.0) rgb = vec3(0.5, 0.0, 1.0); // DECORATION_SHADOW_PASS - purple
result = vec4(rgb, 1.0);
}

Result:

Custom Text2D Materials figure 10

Coverage Alpha Masked Color

Use Coverage Alpha Masked Color to use the colors set on the Text component with the proper coverage alpha mask.

Custom Text2D Materials figure 11

The result will look the same as using the built-in Text material:

Custom Text2D Materials figure 12

Quad Color and Coverage Alpha Mask

Use Quad Color to get the per-pass color without a coverage alpha mask.

Custom Text2D Materials figure 13

Result:

Custom Text2D Materials figure 14

Use Coverage Alpha Mask by multiplying it into the opacity of the desired pixel color in order to get the proper coverage alpha mask.

Custom Text2D Materials figure 15

Add the following code to the Custom Code node:

input_float passId;
input_float coverageAlphaMask;
output_vec4 result;
void main()
{
vec3 rgb = vec3(1.0, 1.0, 1.0); // fallback (unknown pass) = white
if (passId == 0.0) rgb = vec3(1.0, 0.0, 0.0); // MAIN_PASS - red
else if (passId == 1.0) rgb = vec3(0.0, 1.0, 0.0); // COLOR_PASS - green
else if (passId == 2.0) rgb = vec3(0.0, 0.0, 1.0); // SHADOW_PASS - blue
else if (passId == 3.0) rgb = vec3(1.0, 1.0, 0.0); // OUTLINE_PASS - yellow
else if (passId == 4.0) rgb = vec3(1.0, 0.0, 1.0); // BACKGROUND_PASS - magenta
else if (passId == 5.0) rgb = vec3(0.0, 1.0, 1.0); // DECORATION_PASS - cyan
else if (passId == 6.0) rgb = vec3(1.0, 0.5, 0.0); // DECORATION_OUTLINE_PASS - orange
else if (passId == 7.0) rgb = vec3(0.5, 0.0, 1.0); // DECORATION_SHADOW_PASS - purple
result = vec4(rgb, coverageAlphaMask);
}

Result:

Custom Text2D Materials figure 16

Multiplying Coverage Alpha Mask into the alpha value of Quad Color will result in Coverage Alpha Masked Color.

Custom Text2D Materials figure 17

Add the following code to the Custom Code node:

input_vec4 quadColor;
input_float coverageAlphaMask;
output_vec4 result;
void main()
{
result = vec4(quadColor.rgb, quadColor.a * coverageAlphaMask);
}

Result:

Custom Text2D Materials figure 18

SDF Distance

Use SDF Distance to do effects that rely on the distance away from the glyphs. This is only applicable to the main, outline, and drop shadow passes on world space text or large screen space text.

Custom Text2D Materials figure 19

Add the following code to the Custom Code node:

input_float passId;
input_vec4 color;
input_float sdfDistance;
output_vec4 result;
void main()
{
// Outer glow only on the glyph passes: MAIN (0), SHADOW/dropshadow (2), OUTLINE (3).
// Every other pass (color-glyph 1, background 4, decoration 5-7) passes through untouched.
if (passId != 0.0 && passId != 2.0 && passId != 3.0)
{
result = color;
return;
}
const vec3 glowColor = vec3(0.6, 0.1, 0.9); // glow tint (change to taste)
const float glowWidth = 0.35; // outward reach in SDF units (0.0 .. 0.5)

// Screen-space antialiasing width from the SDF gradient, so the glyph edge stays crisp at any scale.
float aa = fwidth(sdfDistance);
// Glyph coverage: 1 inside, 0 outside, smoothly AA'd across the edge at sdfDistance == 0.
float glyph = smoothstep(-aa, aa, sdfDistance);
// Outer glow halo: brightest at the edge, fading to 0 by glowWidth outside; restricted to
// outside the glyph (1 - glyph) so it never overwrites the fill.
float glow = smoothstep(-glowWidth, 0.0, sdfDistance) * (1.0 - glyph);

// Glyph fill composited over the glow halo.
result.rgb = mix(glowColor, color.rgb, color.a);
result.a = max(color.a, glow);
}

Result:

Custom Text2D Materials figure 20

SDF Spread

Use SDF Spread to expand the size of your SDF distance effects past the default quad size.

For example, setting SDF Spread to Large (0.5 em) for the example above results in:

Custom Text2D Materials figure 21

UV

Use UV to do UV effects. When a pass is not set to the Texture fill mode, UV will output per-quad UV.

Custom Text2D Materials figure 22

Add the following code to the Custom Code node:

input_vec4  color;
input_vec2 uv;
output_vec4 result;
void main()
{
// --- UV effect: diagonal two-color gradient across the glyph's UV ---
vec3 colorA = vec3(1.0, 0.2, 0.6); // color at uv (0,0)
vec3 colorB = vec3(0.2, 0.6, 1.0); // color at uv (1,1)
float t = clamp((uv.x + uv.y) * 0.5, 0.0, 1.0);
vec3 grad = mix(colorA, colorB, t);
// Keep the glyph shape from the coverage-masked alpha; drive the RGB from the UV gradient.
result = vec4(grad, color.a);
}

Result:

Custom Text2D Materials figure 23

Was this page helpful?
Yes
No