Logo

Procedural Shape

Build scalable UI shapes with fills, outlines, shadows, and blur

Overview

Procedural Shape is the graphic renderer used throughout Evo UI. It draws a shape based on a shader instead of relying on a separate sprite for every radius or outline. A single component can combine a fill, outline, inner shadow, outer shadow, and an optional image.

Procedural Shape

Usage

Add Procedural Shape to a UI object, or start with an Evo UI element that already uses one.

Choose the shape and tweak it to your needs.

Set the fill color mode and color, or assign a sprite.

Add an outline, corner radius, or shadows as needed.


Customization

Shape and Image

  • Choose Rectangle, Ellipse, Polygon, Star, Heart, or Chevron.
  • Shape Angle rotates the graphic, and Shape Skew shears it on either axis without changing the layout rectangle.
  • Stretch fills the rectangle without preserving the image’s aspect ratio, Cover fills and crops, and Fit preserves the image aspect ratio (or 1:1 when there is no image).
  • Assign a portrait sprite and round its corners to make an avatar without a separate mask object.

Corners and Radius Sync

  • Choose pixel or percentage radius units. Percentage values run from 0 to 100, where 100 is half the shorter side of the drawing rectangle.
  • Rectangles can use independent corners and squircle corners; other supported shapes use a uniform radius, and ellipses do not use corner radii.
  • Match Parent or Match Target derives a rectangle’s radius from another Procedural Shape while accounting for the space between them. This is useful for inset panels and borders. Radius synchronization applies to rectangles.
  • Match Ancestor finds the source by itself, so it works for objects created at runtime, such as context menu or list items. Leave Target Name empty to use the nearest parent with a Procedural Shape. Enter a name, or a path like Frame/Background, to use the nearest object with that name under any parent. Found shows the shape it picked.
  • A synced shape uses one radius on every corner, even when its padding differs per side, such as next to a scrollbar. Turn on independent corners (the link button) to fit each corner to its own padding instead.
  • Synced shapes update when their source changes size or radius. The search runs again when the shape or one of its parents moves. At runtime, call UpdateRect() after you create, rename, or move the source in another branch.

Fills, Outlines, and Shadows

  • Each layer can use the Graphic’s base color, its own custom color, a gradient, Styler colors, or a Styler gradient.
  • A layer’s color mode determines which settings are used.
  • Fill Center can be disabled for an outline-only shape.
  • Gradients can be Linear, Radial, or Angular. Local space maps the gradient to the shape; Screen Space maps it across the screen so separate shapes can share a continuous gradient. Angle, zoom, and reverse control its appearance.
  • The outline is drawn inward. Dashed outlines have independent dash length, gap, offset, and rounded ends.
  • Dash offset is measured in repeats: adding 1 moves the pattern by one dash and gap.
  • Inner and outer shadows each have offset, size, softness, color, and gradient settings.
  • Outer Shadow Outside Only keeps the outer shadow out of the original shape’s interior.

Dithering

Large soft shadows and slow gradients can show visible steps (banding) on 8-bit screens. Enable Dither to add faint noise of about one color level, which hides the steps.

  • Use it on big, soft graphics such as glows and background gradients. Most shapes don’t need it.
  • The noise pattern is fixed and doesn’t flicker.
  • Colors can differ from the set color by about one level, so leave it off where exact color values matter.

Clipping and Progress

  • Use Horizontal, Vertical, or Radial360 clipping with a ClipAmount from 0 to 1.
  • Set ClipOrigin for the starting edge and ClipClockwise for radial direction.
  • Rounded Clip Edges preserves corner radii on horizontal/vertical rectangle fills, or rounds the ends of an outline-only radial fill.

Patterns

  • Enable Fill Pattern to overlay repeating shapes or sprites.
  • Tile size and gap use local pixels; offset and angle move the pattern within the fill.
  • Pattern Falloff fades it with distance from an anchor, useful for decoration that gets quieter near text.
  • Sprite tiles preserve their aspect ratio.
  • If the fill also uses a sprite, both sprites must use the same atlas texture.
  • Disable tight packing and atlas rotation for the pattern sprite.

Combining Shapes

Shape Operations combines up to four other shapes in order using Union, Subtract, Intersect, or Exclude. For example, subtract an ellipse from a rectangle to make a cutout.

  • Smoothing rounds the join between shapes.
  • Targets must be active, coplanar, and on the same root Canvas.
  • Enable Operand Only on a target to use its geometry without drawing it or receiving raycasts.
  • Operations sample each target's primitive and clipping, not its colors, shadows, or nested operations.
  • The resulting shape uses the owner's styling and automatic material.

Sprite Export

Open the component's context menu and choose Export Sprite to save a PNG in the project. The result is a static sprite, so it no longer responds to shape properties or Styler transitions.


Integrations

Styler and Interaction

A Shape Style can override selected groups of settings, so one preset can share corners or outlines without replacing every local choice. For state colors or gradients, choose Styler or Styler Gradient on the relevant layer, enable its interaction mapping, and assign the Selectable that supplies the state. Fill, pattern, outline, and both shadows have separate mappings.

Ripple, Spotlight, and Border Glow support Procedural Shape. Configure them through an Interactive component or their standalone components.

Masking and Input

Procedural Shape participates in Unity UI masking and supports Soft Mask. Use its own sprite and shape settings when you only need to crop that graphic; add a mask when child graphics also need clipping.

Standard raycasts use the rectangle; Shape follows the procedural geometry; None disables hits. Shape mode does not test sprite alpha. Decorative graphics usually need no raycast target.

Backdrop Blur

Enable Backdrop Blur for a camera-blurred fill. It shares settings and capture behavior with Backdrop Blur, including its camera, render-pipeline, and overlay-UI restrictions.


Performance

Procedural Shape shares materials and style data between compatible shapes on the same Canvas, so multiple shapes can often render in a single draw call. Different sprite textures, masks, blur settings, effects, custom materials, and rendering order can still split batches. Each shape uses a single quad, but that doesn’t guarantee a single draw call for the entire UI.

Compared with a regular Image, Procedural Shape offers more flexibility, with a generally higher GPU cost. It can combine several visual layers into one component and handle some updates with less CPU work. Neither option is always faster, the result depends on your UI and how you animate it.

Dither has no cost on shapes that leave it off, and it doesn’t split batches. Shapes that use it cost slightly more to draw, so enable it only where banding is visible.


Roadmap

  • Shader variants: Currently, Procedural Shape is an uber shader, which is good for batching but can be more demanding on the GPU. I'm experimenting with shader variants, which may increase the batch count but could improve GPU performance with little to no additional CPU overhead. For example, shapes without gradients or shadows could use a lightweight shader variant, similar to an LOD system.
  • Bezier editing for polygon shape: This feature will allow you to create virtually any shape (with up to 8 corners), such as a lightning bolt. It will include an editor tool and support runtime manipulation.

Public API

Use ProceduralShape in the Evo.UI namespace.

Property setters request their own updates. After changing public fields or editing a Gradient, style mapping, or blur settings object in place, call UpdateRect(). Shape Style overrides can replace local settings in the groups they control.

Properties

Shape and Image

NameTypeDescription
ShapeShapeTypeRectangle, Ellipse, Polygon, Star, Heart, or Chevron.
PolygonSidesintPolygon side count, clamped to 3–8.
ShapeAnglefloatRotation inside the drawing rectangle, in degrees.
ShapeSkewVector2X/Y skew in degrees, each clamped to -60–60.
SpriteSpriteOptional source image.
ImageScaleModeScaleModeStretch, Cover, or Fit.
RaycastDetectionModeRaycastModeNone, Standard, or Shape hit detection.
SoftnessfloatExtra edge softness in pixels.
DitherboolAdds faint noise that hides banding in soft shadows and gradients.

Corners

NameTypeDescription
CornerRadiusModeRadiusModePixels or Percentage.
CornerRadiusVector4Radii in top-left, top-right, bottom-right, bottom-left order.
UniformCornerRadiusfloatSets a common radius.
IndependentCornersboolUses individual radii on a rectangle. With Radius Sync, each corner fits its own padding.
SquircleCornersboolUses smooth squircle corners on a rectangle.
RadiusSynchronizationModeRadiusSyncModeNone, MatchParent, MatchTarget, or MatchAncestor.
RadiusSyncTargetProceduralShapeReference for MatchTarget.
RadiusSyncTargetNamestringName or relative path MatchAncestor looks for under each parent. Empty uses the nearest parent shape.
RadiusSyncSourceProceduralShapeRead-only. The shape the radius currently syncs to, or null.

Fill

NameTypeDescription
FillCenterboolDraws the interior.
FillColorColorSolid fill color used in Custom mode.
FillGradientGradientGradient; call UpdateRect after in-place edits.
FillGradientTypeGradientTypeLinear, Radial, or Angular.
FillGradientSpaceGradientSpaceLocal or ScreenSpace coordinates.
FillGradientAnglefloatGradient angle in degrees.
FillGradientZoomfloatGradient scale.
FillGradientReverseboolReverses gradient direction.

Pattern Layout

NameTypeDescription
FillPatternboolEnables the repeating fill overlay.
PatternTypePatternSourceShape or Sprite tiles.
PatternSpriteSpriteSprite tile; must be compatible with the fill texture.
PatternSpriteCompatibleboolRead-only; whether the sprite meets the pattern texture and packing requirements.
PatternShapeShapeTypeProcedural tile shape.
PatternPolygonSidesintPolygon tile side count, clamped to 3–8.
PatternRadiusfloatTile corner radius in local pixels.
PatternSizeVector2Tile bounds in local pixels.
PatternGapVector2Space between tiles in local pixels.
PatternOffsetVector2Translation before pattern rotation, in local pixels.
PatternAnglefloatPattern rotation in degrees.
PatternFalloffboolFades tiles with distance from an anchor.
PatternFalloffOriginVector2Anchor from (0, 0) at bottom-left to (1, 1) at top-right.
PatternFalloffStartfloatDistance where fading begins, in local pixels.
PatternFalloffEndfloatDistance where tiles become invisible, in local pixels.

Pattern Colors

NameTypeDescription
PatternColorColorCustom pattern color.
PatternGradientGradientPattern gradient.
PatternGradientTypeGradientTypeLinear, Radial, or Angular.
PatternGradientSpaceGradientSpaceLocal or ScreenSpace coordinates.
PatternGradientAnglefloatPattern gradient angle in degrees.
PatternGradientZoomfloatPattern gradient scale.
PatternGradientReverseboolReverses the pattern gradient.

Outline

NameTypeDescription
OutlineWidthfloatInward outline thickness in pixels.
OutlineColorColorCustom outline color.
OutlineGradientGradientOutline gradient.
OutlineGradientTypeGradientTypeLinear, Radial, or Angular.
OutlineGradientSpaceGradientSpaceLocal or ScreenSpace coordinates.
OutlineGradientAnglefloatOutline gradient angle.
OutlineGradientZoomfloatOutline gradient scale.
OutlineGradientReverseboolReverses the outline gradient.
OutlineDashedboolEnables a dashed outline.
OutlineDashLengthfloatDash length in local pixels.
OutlineDashGapfloatGap between dashes in local pixels.
OutlineDashOffsetfloatPattern offset in repeats.
OutlineDashRoundedboolRounds dash ends.

Clipping

NameTypeDescription
ClippingMethodClipMethodNone, Horizontal, Vertical, or Radial360.
ClipOriginintStarting edge/direction for clipping.
ClipAmountfloatVisible amount from 0 to 1.
ClipClockwiseboolRadial clipping direction.
RoundedClipEdgesboolRounded supported clip ends.

Inner Shadow

NameTypeDescription
InnerShadowOffsetVector2Inner-shadow offset.
InnerShadowSizefloatInner-shadow expansion.
InnerShadowSoftnessfloatInner-shadow blur radius.
InnerShadowColorColorCustom inner-shadow color.
InnerShadowGradientGradientInner-shadow gradient.
InnerShadowGradientTypeGradientTypeLinear, Radial, or Angular.
InnerShadowGradientSpaceGradientSpaceLocal or ScreenSpace coordinates.
InnerShadowGradientAnglefloatInner-shadow gradient angle in degrees.
InnerShadowGradientZoomfloatInner-shadow gradient scale.
InnerShadowGradientReverseboolReverses the inner-shadow gradient.

Outer Shadow

NameTypeDescription
OuterShadowOffsetVector2Outer-shadow offset.
OuterShadowSizefloatOuter-shadow expansion.
OuterShadowSoftnessfloatOuter-shadow blur radius.
OuterShadowOutsideOnlyboolExcludes shadow from the original interior.
OuterShadowColorColorCustom outer-shadow color.
OuterShadowGradientGradientOuter-shadow gradient.
OuterShadowGradientTypeGradientTypeLinear, Radial, or Angular.
OuterShadowGradientSpaceGradientSpaceLocal or ScreenSpace coordinates.
OuterShadowGradientAnglefloatOuter-shadow gradient angle in degrees.
OuterShadowGradientZoomfloatOuter-shadow gradient scale.
OuterShadowGradientReverseboolReverses the outer-shadow gradient.

Backdrop Blur

NameTypeDescription
BackdropBlurEnabledboolEnables the blurred fill.
BackdropBlurSettingsBackdropBlur.SettingsShared BackdropBlur.Settings configuration.

Styling

NameTypeDescription
PresetStylerPresetStyler preset used by the shape.

Shape Operations

NameTypeDescription
OperandOnlyboolSupplies operation geometry without drawing or receiving raycasts.
ShapeOperationCountintRead-only count of configured operations, up to four.

Fields

Styling and Interaction

NameTypeDescription
shapeStyleIDstringShape Style ID within that preset.
useDefaultStylerPresetboolLocks the preset to the current default Styler Preset.
interactableObjectSelectableSelectable that supplies interaction states.

Fill

NameTypeDescription
fillColorModeColorModeBase, Custom, Gradient, Styler, or StylerGradient fill.
fillStylerStyler.ColorStyleFill color and state mappings.
fillGradientStylerStyler.GradientStyleFill gradient and state mappings.

Pattern

NameTypeDescription
patternColorModeColorModeSource of pattern color.
patternStylerStyler.ColorStylePattern color and state mappings.
patternGradientStylerStyler.GradientStylePattern gradient and state mappings.

Outline

NameTypeDescription
outlineColorModeColorModeSource of outline color.
outlineStylerStyler.ColorStyleOutline color and state mappings.
outlineGradientStylerStyler.GradientStyleOutline gradient and state mappings.

Shadows

NameTypeDescription
innerShadowColorModeColorModeSource of inner-shadow color.
outerShadowColorModeColorModeSource of outer-shadow color.
innerShadowStylerStyler.ColorStyleInner-shadow color and state mappings.
outerShadowStylerStyler.ColorStyleOuter-shadow color and state mappings.
innerShadowGradientStylerStyler.GradientStyleInner-shadow gradient and state mappings.
outerShadowGradientStylerStyler.GradientStyleOuter-shadow gradient and state mappings.

Methods

NameParametersDescription
UpdateRect()NoneRefreshes geometry/materials after direct field or in-place edits.
UpdateStyler()NoneResolves preset settings and interaction mappings.
GetDrawingRect()NoneReturns the resolved drawing rectangle. Returns Rect.
GetRadiiPixels()Rect rectResolves radii in pixels for a rectangle. Returns Vector4.
SetShapeOperations()ShapeOperation[] operationsRetains the supplied array; accepts up to four operations. Pass null or an empty array to clear it.
GetShapeOperation()int indexReturns a copy of a configured ShapeOperation.
SetShapeOperation()int index, ShapeOperation valueReplaces an existing operation and clamps its smoothing to 0–1.

ShapeOperation contains target (ProceduralShape), operation (OperationType), and smoothing (float, 0–1). OperationType is Union, Subtract, Intersect, or Exclude. Use a valid index below ShapeOperationCount when reading or replacing an entry.

Example

ProceduralShapeExample.cs
using UnityEngine;
using Evo.UI;

public class ProceduralShapeExample : MonoBehaviour
{
    [SerializeField] private ProceduralShape target;

    private void Start()
    {
        // Shape and corners
        target.Shape = ProceduralShape.ShapeType.Rectangle;
        target.CornerRadiusMode = ProceduralShape.RadiusMode.Pixels;
        target.UniformCornerRadius = 20f;
        
        // Select the color sources before assigning their values
        target.fillColorMode = ProceduralShape.ColorMode.Custom;
        target.FillColor = new Color(0.12f, 0.15f, 0.22f);
       
        // Outline parameters
        target.outlineColorMode = ProceduralShape.ColorMode.Custom;
        target.OutlineWidth = 2f;
        target.OutlineColor = Color.cyan;
        target.OutlineDashed = true;
        target.OutlineDashLength = 12f;
        target.OutlineDashGap = 6f;

        // Pattern parameters
        target.FillPattern = true;
        target.PatternType = ProceduralShape.PatternSource.Shape;
        target.PatternShape = ProceduralShape.ShapeType.Ellipse;
        target.PatternSize = new Vector2(3f, 3f);
        target.PatternGap = new Vector2(12f, 12f);
        target.patternColorMode = ProceduralShape.ColorMode.Custom;
        target.PatternColor = new Color(1f, 1f, 1f, 0.12f);
        
        target.UpdateRect(); // Force apply the color-mode fields changed above
    }

    public void SetProgress(float progress)
    {
        target.ClippingMethod = ProceduralShape.ClipMethod.Horizontal;
        target.RoundedClipEdges = true;
        target.ClipAmount = Mathf.Clamp01(progress);
    }
}

On this page