FX Machina Sprites
User Manual
Table of Contents
Overview
FX Machina Sprites provides a set of three shaders intended for use with Unity’s internal SpriteRenderer, SpriteShapeRenderer, and ParticleSystemRenderer components. These sprite shaders together solve certain commonly encountered problems and limitations with the default sprite shaders, as well as providing a large number of controls for creating special effects by warping and recoloring the sprite texture’s pixels. This package also provides the SpriteSettings script for changing the shader parameters per-sprite both in-editor and at runtime, alongside a few demo effects to help you quickly get started using these tools in your own project.
Shaders
There are three shaders provided in this package, each intended to be used for specific situations:
- Depth Sprite
This is a shader intended for rendering solid objects. Sprites with this shader can cast shadows and draw to the depth texture – which is used for post-processing effects such as depth of field – and can receive shadows and additive lights. They are in general more efficient than Blended Sprites because they occlude other objects, but do not support true transparency. - Blended Sprite
This is a shader intended for opaque or transparent objects, and can render in different ways based on the Blend Mode parameter. Sprites with this shader can cast shadows and draw to the depth texture, but can only be lit by a single directional light source and cannot receive shadows. Because this draws in the transparent queue it can cause overdraw (the same screen pixel being rendered multiple times), and is thus generally less efficient than Depth Sprite. - Modifier Sprite
This is a shader intended for special effects: Sprites with this shader sprites don’t cast or receive shadows or draw to the depth texture, and don’t even directly draw the sprite – instead they displace and recolor background pixels based on the sprite and the parameters you set.
Scripts
- SpriteSettings
There’s one primary script provided, SpriteSettings, which allows you to control parameters on a per-GameObject basis and which handles some per-renderer information such as sprite atlases. In general, you will want to attach this to any GameObject that uses any of the provided shaders for any renderers. Most material settings can be modified from here, but because some affect how the shader is compiled they are not available. The following settings are not available:- Light Mode
- Normal Map Enabled/Disabled
- Normal Space
- Blend Mode
- Depth/Shadows Mode
- Pixel Snap Enabled/Disabled
- Mix-In Enabled/Disabled
- Outline Enabled/Disabled
- Outline Texture Enabled/Disabled
- Blur Enabled/Disabled
- Color Transform Enabled/Disabled
- Color Transform Mask Enabled/Disabled
- Displacement Enabled/Disabled
- Displacement Map Enabled/Disabled
- Vertex Transform Enabled/Disabled
- Vertex Transform Map Enabled/Disabled
- Effects UV Space
If you need to set a texture parameter such as the normal map on a sprite, you must first enable the texture parameter on the material itself – even if the material leaves the texture itself unassigned, it will allow it to be set by SpriteSettings.
There are also a couple of settings available which do not map to any material settings, being instead methods to access otherwise hidden renderer settings. These are:
-
- Receive Shadows
- Cast Shadows
- Demo Scripts
A few scripts are also included to create the demo effects. Though these have specific applications in those effects, you may also find them useful in creating your own:- ScrollScript
Requires SpriteSettings. Moves the offsets for different textures in the shader over time. Simply scrolling these values can generate a surprising range of effects, and this is a good entry point into generating more sophisticated effects. Used for Fire, Portal, Water, Grass, and Glitch effects. - RotateScript
A very simple script to rotate the object over time. Used for the portal effect. - DissolveScript
Requires SpriteSettings. A script to take a value between 0 and 1 and use it to tween the scale and offset of the dissolve effect. - GlitchScript
Requires SpriteSettings. A script to set a randomized scale and offset for the displacement map every second or two for the glitch effect.
- ScrollScript
Getting Started:
Standard Sprites
First, add a sprite to your scene. You can use one of the provided prefab sprites in Prefab/Basics to automatically handle the next few steps, but if you create a standard sprite either through Unity’s context menu or by dragging a sprite into the scene.
The new Sprite will be created using Unity’s Sprites-Default material, which uses Unity’s built-in sprite shader.
You can quickly switch to a standard FX Machina Sprite Shader material by setting one of the materials in Basic Materials to the new Sprite’s SpriteRenderer material value.
Alternately, if you want to customize the material more, you can create a new material through the context menu and set it to use one of the FX Machina Sprites shaders.
Finally, you should also add the SpriteSettings script to the Sprite to automatically handle edge cases and provide per-Sprite controls.
Particle Systems
In order for the vertex transformation effect and complex lighting mode to work properly with particle systems, the system has to be configured to send additional information to the shader. In the Renderer component of the particle system, check the “Custom Vertex Streams” box, then:
-
- Click the plus button and select ‘Tangent’ if you’re using normal maps in tangent space
- If you want to add a randomized offset to the transform map so that the particles aren’t obviously synced up, click the plus button and select ‘Random > Stable.xy’. If you don’t want this effect, instead select Custom.xy
- Click the plus button and select ‘Center’ if you’re using the vertex transform effect
- Note: The order these are in is important. Many effects will not function properly if TEXCOORD0.zw are not set and TEXCOORD1.xyz aren’t set to center. Default Particle System prefabs with these settings have been provided
Normally particle systems use materials with main textures assigned, but because these are sprite shaders the main texture is reserved to be assigned by the renderer. You can either set the desired texture as the mix-in texture at full opacity in the material to emulate this behavior, or you can use the Sprite Sheet Module in the Particle System to assign the main texture from there
Working With Sprite Shapes
Some of the vertex modifications that happen with the Displacement effect are currently incompatible with Unity’s SpriteShapeRenderer. To enable compatibility, simply attach the SpriteSettings script to any object using a SpriteShapeRenderer and these modifications will be disabled.
Unbounded Colors
Many of the color settings in FX Machina Sprites use ‘Unbounded Color’ settings. These are an extended form of color which allow arbitrary values for each channel, including negative values, to enable the most flexibility possible for color effects. You can set them like a normal HDR color using the standard color picker on the right, or change each channel individually to access this extended capability.
Many of the settings you can reach this way won’t look good or make sense: When in doubt, just use the color picker.
HDR
Many of the effects, most notably the blend modes, will not work correctly if the project is not set to use HDR colors. This is usually turned on by default, but if you’re not sure you can check in Project Settings > Quality. Also, be sure this setting isn’t being overridden by whichever camera you’re currently rendering to!
The SpriteSettings Script
The SpriteSettings script provides a method to change the way sprites display on a case-by-case basis without generating a new material for each individual sprite, much the same as Unity’s SpriteRenderer can recolor or flip a sprite all while using the same default sprite material. You can see at a glance which settings differ from the original material settings since they use white text, while default values have gray text. Press the red button to reset any setting back to the material default, or the ‘revert all’ button to revert all settings to material defaults. Only settings available on the material will be visible – so, for instance, if color transform isn’t enabled on the material, color transform settings will not be visible. Any of the SpriteSettings script values can be controlled from other scripts, and will automatically update the sprite’s rendering.
Important Note: Any changes made to the properties controlled by SpriteSettings to the original material will no longer affect the sprite. If you’re changing values and not seeing a difference, this may be why.
Controlling SpriteSettings From Other Scripts
SpriteSettings exposes properties that can be controlled by other scripts for every material property it can change. The names of the exposed properties follow:
depthCutoff (float) alphaCutoff (float) pixelScale (Vector2) normalMap (Texture) bumpScale (float) metallic (float) smoothness (float) mixInTexture (Texture) mixInTextureScale (Vector2) mixInTextureOffset (Vector2) mixInAmount (float) modifyColorRotation (float) outlineTexture (Texture) outlineTextureScale (Vector2) outlineTextureOffset (Vector2) outlineColor (UnboundedColor) outlineThickness (float) outlineSamples (int) blurDistance (Vector2) blurSamples (Vector2Int) blurSpread (float) colorTransformMask (Texture) colorTransformMaskScale (Vector2) colorTransformMaskOffset (Vector2) colorTransformColorTint (UnboundedColor) colorTransformColorOffset (UnboundedColor) colorTransformHueRotation (float) colorTransformSaturation (float) colorTransformThreshold (float) displacementMap (Texture) displacementMapScale (Vector2) displacementMapOffset (Vector2) displacementValueOffset (float) displacementScale (Vector2) displacementTranslate (Vector2) displacementRotate (float) transformMap (Texture) transformMapScale (Vector2) transformMapOffset (Vector2) transformValueOffset (float) transformScale (Vector2) transformTranslate (Vector2) transformRotate (float) receiveShadows (bool) shadowCastingMode (ShadowCastingMode)
SpriteSettings also provides a set of methods for reading and changing values using the FXMachinaSpriteControl enum as a control ID:
void SetVectorOverride(FXMachinaSpriteControl, Vector4) void SetTextureOverride(FXMachinaSpriteControl, Texture) void SetFloatOverride(FXMachinaSpriteControl, float) void SetColorOverride(FXMachinaSpriteControl, Color) void SetColorOverride(FXMachinaSpriteControl, Vector4) void SetColorOverride(FXMachinaSpriteControl, UnboundedColor) bool IsOverridden(params FXMachinaSpriteControl[]) void ClearOverride(FXMachinaSpriteControl) Vector4 GetVectorValue(FXMachinaSpriteControl) Texture GetTextureValue(FXMachinaSpriteControl) float GetFloatValue(FXMachinaSpriteControl) Color GetColorValue(FXMachinaSpriteControl)
Demo Museum
The Demo Museum scene is provided both to convey straightforward applications of the shaders and more advanced ‘special effects’ applications. All of the demo effects in this scene are also available as prefabs, so you can easily drop them into your own project.
Click the left or right buttons to scroll through the different displays in the Demo Museum. The available displays are:
-
- Basic Sprite Types
Shows how the same sprite renders differently with each shader and common settings for those shaders. The sprites are shown at 90% opacity so you can get some idea of how each shader/setting handles transparency. - Fire
An animated fire effect created from 5 sprites and a point light. - Dissolve
A sprite with radial dissolve effect controlled with a slider - Grass
A particle effect of grass swaying in the wind - Water
A simple reflective water effect created from 2 sprites - Glitch
A sprite with a glitch effect applied that changes over time - Portal
A warping portal effect created from 4 sprites
- Basic Sprite Types
Shader Parameters
Basic Parameters
- Color
Available in: All
Tints the sprite by multiplying color values. With the modifier shader, this is used to determine the masking value. - Light Mode
Available in: Depth, Blended
Determines how the sprite is lit.
There are three options: None, which disables lighting and shadows; Simple, which lights the sprite based on ambient light and whichever light it’s closest to but disregards orientation; and Full, which is similar to Unity’s standard shader for 3d objects.- Normal Map
Modifies facing of pixels for lighting calculations. Only available with Full Lighting.
Normal maps have a few spatial modes: Tangent, which modifies the pixels relative to the facing of the sprite; Camera, which modifies the pixels relative to the facing of the camera; World, which modifies the pixels relative to the world’s X/Y plane; and Custom, which is similar to World but allows you to rotate the plane.
Normal maps also have the Scale setting, which allows you to change the magnitude of the effect. - Metallic and Smoothness
Affects how the material responds to light. Only available with Full Lighting.
- Normal Map
- Blend Mode
Available in: Blended
Determines how the sprite draws over background pixels, similar to the blend modes available in graphics software like Photoshop. Due to how shader blending is implemented in Unity, this property can only be changed on the material itself, not using the SpriteSettings script – so if you need to change the blend mode at run-time, you’ll either need to change the material itself or create another material and switch to it. Important Note: In order for all blend modes to function properly, HDR must be enabled for the camera being rendered.
There are 15 blend modes available: Normal, Dissolve, Add, Screen, Color Dodge, Lighten, Subtract, Multiply, Color Burn, Darken, Overlay, Hard Light, Soft Light, Vivid Light, and Linear Light. - Depth/Shadows Mode
Available in: Depth, Blended
The depth texture is used for shadow casting and certain post-processing effects, such as depth of field. This setting determines how the sprite interacts with the depth texture.
There are four options: Disabled, which doesn’t draw to the depth texture or cast shadows; No Shadows, which draws to the depth texture but doesn’t cast shadows; Dithered, which casts shadows which dissolve pixel-by-pixel if the object casting them becomes transparent; and Solid, which casts shadows without any dithering as long as the sprite isn’t fully transparent. - Pixel Alpha Cutoff
Available in: All
Pixels with alpha value under this threshold will be discarded. This calculation happens after color transformation effects. - Depth Cutoff
Available in: All
Pixels with alpha value under this threshold will not be drawn to z buffer or depth texture. This calculation happens after color transformation effects. - Pixel Snap and Pixel Scale
Available in: All
How sprite pixel samples are aligned: None, which renders the sprite normally; Screen, which aligns samples to the screen; Texture, which aligns samples to the texture’s pixel boundaries.
Pixel Scale is only available when Pixel Snap is not set to None, and snaps the pixels to an x by y grid, creating a pixelation effect - Receive Shadows
Available in: Depth
Whether the sprite can receive shadows. Important Note: Due to how Unity’s SpriteRenderers are set up, even with this setting on shadow receiving must be manually enabled on each SpriteRenderer for it to receive shadows. You can write your own script to do this or use the SpriteSettings script to easily toggle shadow receiving on and off.
Effect Parameters
- Mix-In Texture
A secondary texture that can be blended into the main texture with a blend value slider. Also contains tiling/offset information.
Performance Impact: Low. One additional sample per fragment operation. - Outline
The outline effect draws around the boundaries of the sprite using whatever texture and color you set.- Outline Texture
An optional texture to draw the outline with, along with its tile and offset information. - Outline Thickness
The distance the outline is drawn in texels - Outline Color
Draw using this color or use it to multiply the texture’s color values - Outline Samples
The number of times to sample in different directions to find the bounds of the outline.
- Outline Texture
Performance Impact: High. Each iteration of Outline Samples requires 4 more samples, and combined with other effects this can accumulate quickly.
- Blur
The blur effect applies a Gaussian blur to all pixels- Blur Distance
The distance the blur reaches in texels - Blur Spread
The sigma value for the Gaussian blur function - Blur Samples
The number of times to sample in x/y directions to create the blur effect
- Blur Distance
Performance Impact: VERY HIGH. Each sample requires an additional (2x + 1) * (2y + 1) samples, so this can increase incredibly quickly especially in combination with other effects. Use with caution.
- Color Transform
The color transform effect provides settings for modifying the color of the sprite’s pixels in almost any imaginable way – or, in the case of the modifier sprite, to modify the color of underlying pixels.- Color Transform Mask
Set an optional texture to control the color transform effect, along with its tile and offset information.
Three mask modes are available: Average, which uses the average of the rgb channels to control the effect; Luma, which uses the rgb luminance to control the effect; and Per Channel, which uses the mask’s red channel to affect the red channel, blue to blue, etc. - Color Transform Mask Factor
Determine how the mask is applied. 1 is standard, 0 inverts the mask, and other values extrapolate from these - Tint
Multiply the channels of the color by scalar values - Offset
Offset the channels of the color by scalar values - Hue
Rotate the hue of the color by degrees - Saturation
Modify saturation of color: 0 is grayscale, 1 is normal, -1 is inverted color channels - Threshold
Converts pixels to grayscale and sets them to black if they fall under threshold value
- Color Transform Mask
Performance Impact: Low. Only adds one extra sample operation independent of other effects.
- Pixel Displacement
The pixel displacement effect provides settings for warping the positions of pixels on the sprite – or, in the case of the modifier sprite, warping the positions of background pixels.- Displacement Map
Set an optional texture to control the displacement effect, along with its tile and offset information.
Two mask modes are available: RGB to Average, which uses the average of the RGB channels to control the effect; and RGB to XYR, which uses the texture’s red channel to affect the x displacement, green channel to affect the y displacement, and blue channel to affect the rotational displacement. - Value Offset
Normally the values of the displacement map range from 0 to 1, but for some effects we may want it to be both positive and negative. Using this slider you can offset it – so, for instance, if you set it to -0.5 the effective values of the displacement map are between -0.5 and 0.5. - Center Offset
Offset the UV center coordinates of the sprite for the purposes of scaling and rotation - Scale
Scale the pixels of the sprite around the center - Translate
Translate the pixels of the sprite along the X/Y axes - Rotation
Rotate the pixels of the sprite by degrees around the center
- Displacement Map
Performance Impact: Moderate. Doubles sampling operations, and also can expand the vertices so more pixels are drawn. Changes to rotation are particularly expensive, and more so the further from the pivot point the sprite is
- Vertex Transformation
Conceptually similar to the pixel displacement effect, this provides settings for changing the positions of sprite vertices. This has limited utility for traditional sprites, but can be very powerful when used with particle effects.- Transform Map
Set a texture to control the transform effect, along with its tile and offset information.
Two mask modes are available: RGB to Average, which uses the average of the RGB channels to control the effect; and RGB to XYR, which uses the texture’s red channel to affect the x displacement, green channel to affect the y displacement, and blue channel to affect the rotational displacement. - Value Offset
Normally the values of the displacement map range from 0 to 1, but for some effects we may want it to be both positive and negative. Using this slider you can offset it – so, for instance, if you set it to -0.5 the effective values of the transform map are between -0.5 and 0.5. - Scale
Scale the vertices of the sprite around the center - Translate
Translate the vertices of the sprite along the local X/Y axes - Rotation
Rotate the vertices of the sprite along the X/Y plane by degrees around the center
- Transform Map
Performance Impact: The impact of the process itself is negligible, but it can cause more pixels to be drawn. The performance impact is directly proportional to the scale values provided.
- Effects UV Space
Determines how the UV of the Color Transform Mask, Displacement Map, and Transform Map are generated. There are three modes: Vertex, which uses the same UV coordinates as are used for the sprite’s main texture; Camera, which aligns the UV coordinates to the camera view’s frustum, with 0,0 being the bottom left and 1,1 being the top right; and World, which generates consistent UV coordinates based on the vertex’s world position.
Tips
- Per-Fragment Performance
Certain settings can drastically effect the overall performance quality of the shaders. You can see a report at the bottom of both the standard material inspector for the shaders or the SpriteSettings script detailing how many samples need to be taken to render each pixel, and expand it to see the formula. - Vertex Scaling, Displacement, and Performance
Both the Vertex Transformation and Displacement effects can change the dimensions of the sprite, making it larger. Sometimes, as in the case of a displacement effect with a map full of low values applied, most of that territory isn’t even being rendered! Try to be aware of how many invisible pixels are being rendered. If you’re not sure, you can use the color transform’s offset alpha value to make the entire sprite rectangle visible. - The Dangers of Blur and Outline
The most dangerous effect is Blur: Be very cautious in its use, particularly in combination with other effects, and try to keep the sample count as low as possible. When the blur effect is applied to a material with no other special effects, it multiplies the number of necessary samples by a factor of (2x+1)*(2y+1) – as you might imagine, this gets expensive quickly! The next-most dangerous effect is Outline: Though this effect may seem straightforward, it requires several extra texture samples for each pixel, and scales the requisite number of samples by (4d+1). Using the two effects together is not recommended.
Troubleshooting
- Particle transforms don’t work or behave strangely: See the section “Using the Shaders with Particles” and ensure the settings are correct.
- The shaders are just rendering as magenta squares: This is probably because you’re using an unsupported rendering pipeline. Currently, FX Machina Sprites only supports Unity’s built-in rendering pipeline.
- Changes made to my material aren’t affecting sprite using the material: The changes are probably being overridden by an SpriteSettings script. Rarely, these settings might persist after the script being removed or disabled: In these cases you may need to restart Unity or delete and recreate the sprite renderer.
- Modifier sprite isn’t working/isn’t visible: Because the modifier sprite shader works by changing background pixels, if no color changes or special effects are set it renders the background pixels exactly as they are, making it effectively invisible. Try changing the color setting on the material or renderer.
- These Blend Modes Don’t Look Right: For Blended Sprite blend modes to work well, they require HDR to be enabled in the project’s Graphics Settings or the camera being rendered.
- The Sprite is Black: Ensure that, if lighting mode is not set to None, there is a light source within range and oriented towards the surface of the sprite. If the sprite uses the BlendedSprite shader, ensure that the light source is a directional light, and try changing the blend mode or alpha value – certain blend modes, such as color dodge, are just very dark and can appear black when at full strength.
- My SpriteShape Looks Fragmented: Attach the SpriteSettings script to the same object as the SpriteShapeRenderer to put it in Sprite Shape compatibility mode.
- My Sprite Turns Black or Has Strange Lighting When I Flip It: Because the SpriteRenderer flips the normals along with the sprite, it creates lighting errors. Attach the SpriteSettings script to the same object as the SpriteRenderer to have it orient the normals correctly.
External Asset Credits
Skull
https://opengameart.org/content/resouces-pack-1
Bricks
https://opengameart.org/content/brick-texture