Table of Contents

🔳 CosterGraphics.Systems.OutlineSystem


❔ Frequently Asked Questions

❔ Why Does Using Multiple Outline Renderer Features Sometimes Cause Weird Artifacts?

The OutlineSystem is designed with the feature of being able to stack multiple 🧑‍🎨Outline3DRenderFeatures in mind, but there are a few things to consider when stacking/layering multiple 🧑‍🎨Outline3DRenderFeatures on top of each other...

  1. When using multiple Outline3DRenderFeatures that use the same Composite outline material file at runtime the Outline3DRenderFeatures might try to apply masks to the same material during the same frame and things can break. When using multiple Outline3DRenderFeatures that use the same outline shader then it is best to create multiple composite materials for each feature so that render textures don't get mixed up. Currently this is a limitation of the system that may be adressed later by implementing the option to instance the materials but at the moment this feature isn't fully implemented yet.

  2. The order of the 🧑‍🎨Outline3DRenderFeatures in the Renderer Features list of the URP Renderer asset matters! The Renderer Features at the bottom of the list get executed last so if you want for instance a thick white silhouette outline with a thin black contour outline drawn on top of it, then the thin black contour outline should be added below the thick white silhouette outline in the list, otherwise the thick outline gets rendered on top of the thin outline, making the thin outline invisible.

  3. The order of the Render Pass Events of the Scriptable Renderer Feature's Render Passes also matters and for each Render Pass the pass injection point can be set in the Inspector but it is not recommended to do so since the default setting of 'Before Rendering Post Processing' usually works best for all of the Render Passes and none of the shaders in the collection requires the order to be changed.

    If for some reason the Outline Render Passes injection point has to be changed then keep in mind that mask passes should always be injected before the final composite pass and that some of the masking passes rely on other masking passes to have been executed beforehand. The OutlineSystem is designed to keep each Outline3DRenderFeature's render passes seperate from each other and from Unity's built-in render passes (each 🧑‍🎨Outline3DRenderFeatures is basically a small mini-render-pipeline injected in-between Unity's render passes in the Render Graph) but with many stacked 🧑‍🎨Outline3DRenderFeatures mixed with maybe other types of Renderer Features (Decal, SSAO, DoF etcetera.) things can become unpredictable, so keep that in mind when mixing different outlines and using other Renderer Features.
    (The 🧑‍🎨Outline3DRenderFeatures were tested against the Decal, SSO and DoF Render Features that come with Unity and shouldn't conflict with those particular features but of course can't be tested against other unknown Renderer Features)

ℹ️ Generally speaking it is more efficient to combine for instance a silhouette outline with a contour outline all in the final 🖼️Composite shader (for instance with a 🐦‍🔥Hybrid Silhouette & Contour outline shader) instead of running two seperate 🧑‍🎨Outline3DRenderFeatures because when the outlines are combined in the 🖼️Composite shader only one feature has to run the shared 🎭Masking Render Passes!

❔ Why have all these different variations of inside/outside contour/silhouette outline shaders. Can't it be combined into one single shader with all of the properties added together?

The main consideration to not create what gets called an 'Uber shader' that can do everything via enums or Booleans is that it will force the shader compiler to create an extreme amount of different shader variations for all of the different combinations of settings that the shader could have. This would lead to extreme shader compilation times and bloat for all of the variations that aren't used at runtime. The system is built however with the flexibility of combining and stacking of multiple outline shaders to create layered effects in mind. Each enabled 🧑‍🎨Outline3DRenderFeature added to the Renderer Features list creates and adds it's own Render Passes to the main URP pipe-line and is basically a small self-contained mini-render-pipeline.

Another reason to not create one big Uber shader is for runtime performance reasons. Each non-standard outline feature, like depth tested outlines, outlines with view space thickness, intersection outlines or per-object color outlines adds more calculations to the outline shader and/or requires the 🧑‍🎨Outline3DRenderFeature to run more mask passes. So the collection of outline shaders is built-up in 'steps' of incrementally added complexity and shader modes and features kept to a minimum as much as possible.

❔ Whats With All The Emoji Symbols??..🫠

Colored symbols can really help with quickly navigating trough code in scripts and to quickly find things at a glance. Humans in general can recognize things very fast by color and by shape. (Often the first thing we 'read' with our eyes when observing objects like cars and people approaching in the distance when walking outside is the object's overall color and rough silhouette shape, then when we go for the 'second read'/look for the second time, we mentally fill in the general color and overall shape with other finer details that we notice!) Having a custom symbol font would be even better but at this time Emojis are about the only colored set of generic symbols that just work basically everywhere and on every computer. They work in scripts, Shader Graphs, the Hierarchy and on website documentation pages, so at the moment it is the best option available!

See the OutlineSystem Glossary for an overview of what the Emojis mean in the context of this Outline System:

📙 Glossary - Glossary of Terms like "ULP," "Render Graph" and the meaning of the Outline System's Emoji Symbols



🔫 TroubleShooting