Arvtesh / UnityFx.Outline

Screen-space outlines for Unity3d.
MIT License
1.28k stars 90 forks source link
image-effects outline post-effect unity unity3d unityfx

UnityFx.Outline

Channel UnityFx.Outline
Github GitHub release
Npm (core + built-in RP) Npm release npm
Npm (Post-processing v2) Npm release npm
Npm (URP) Npm release npm
Npm (HDRP) TODO

Requires Unity 2018.4 or higher.
Compatible with Unity Post-processing Stack v2.
Compatible with Universal Render Pipeline.
Compatible with XR (Multi Pass, Single Pass Instanced).

Please ask any questions and leave feedback at the Unity forums.

Synopsis

Outline demo Outline demo

UnityFx.Outline implements configurable per-object and per-camera outlines. Both solid and blurred outline modes are supported (Gauss blur). The outlines can be easily customized either through scripts or with Unity editor (both in edit-time or runtime).

Implementation is based on Unity command buffers, compatible with Unity Post-processing Stack v2 and Universal Render Pipeline, extendable and has no external dependencies.

Supported outline parameters are:

Supported platforms:

Please see CHANGELOG for information on recent changes.

Getting Started

Prerequisites

You may need the following software installed in order to build/use the library:

Getting the code

You can get the code by cloning the github repository using your preffered git client UI or you can do it from command line as follows:

git clone https://github.com/Arvtesh/UnityFx.Outline.git

Npm packages

NPM
NPM
NPM

Npm core package is available at npmjs.com. There are dedicated packages for Post-processing Stack v2 and Universal Render Pipeline. To use the packages, add the following line to dependencies section of your manifest.json. Unity should download and link the package automatically:

{
  "scopedRegistries": [
    {
      "name": "Arvtesh",
      "url": "https://registry.npmjs.org/",
      "scopes": [
        "com.unityfx"
      ]
    }
  ],
  "dependencies": {
    "com.unityfx.outline": "0.8.5",
    "com.unityfx.outline.urp": "0.5.0",
  }
}

Usage

Install the package and import the namespace:

using UnityFx.Outline;

Per-camera outlines (built-in RP)

Outline demo

Add OutlineEffect script to a camera that should render outlines. Then add and configure as many layers as you need. An outline layer is a group of game objects that share the same outline settings:

var outlineEffect = Camera.main.GetComponent<OutlineEffect>();
var layer = new OutlineLayer("MyOutlines");

layer.OutlineColor = Color.red;
layer.OutlineWidth = 7;
layer.OutlineRenderMode = OutlineRenderFlags.Blurred;
layer.Add(myGo);

outlineEffect.OutlineLayers.Add(layer);

or

var outlineEffect = Camera.main.GetComponent<OutlineEffect>();

// This adds layer 0 (if it is not there) and then adds myGo.
outlineEffect.AddGameObject(myGo);

// Now setup the layer.
var layer = outlineEffect[0];

layer.OutlineColor = Color.red;
layer.OutlineWidth = 7;
layer.OutlineRenderMode = OutlineRenderFlags.Blurred;
layer.Add(myGo);

This can be done at runtime or while editing a scene. If you choose to assign the script in runtime make sure OutlineEffect.OutlineResources is initialized. Disabling OutlineEffect script disables outlining for the camera (and frees all resources used).

Multiple OutlineEffect scripts can share outline layers rendered. To achieve that assign the same layer set to all OutlineEffect instances:

var effect1 = camera1.GetComponent<OutlineEffect>();
var effect2 = camera2.GetComponent<OutlineEffect>();

// Make effect1 share its layers with effect2.
effect1.ShareLayersWith(effect2);

Per-object outlines (built-in RP)

Outline demo

Add OutlineBehaviour script to objects that should be outlined (in edit mode or in runtime). Make sure OutlineBehaviour.OutlineResources is initialized. You can customize outline settings either via Unity inspector or via script. Objects with OutlineBehaviour assigned render outlines in all cameras.

var outlineBehaviour = GetComponent<OutlineBehaviour>();

// Make sure to set this is OutlineBehaviour was added at runtime.
outlineBehaviour.OutlineResources = myResources;

outlineBehaviour.OutlineColor = Color.green;
outlineBehaviour.OutlineWidth = 2;
outlineBehaviour.OutlineIntensity = 10;

Depth testing

By default depth testing is disabled when rendering outlines. This behaviour can be overriden by setting EnableDepthTesting flag of Rander Flags (either via scripting API or with editor).

var outlineSettings = GetComponent<OutlineBehaviour>();

outlineSettings.OutlineColor = Color.green;
outlineSettings.OutlineWidth = 2;
outlineSettings.OutlineRenderMode = OutlineRenderFlags.Blurred | OutlineRenderFlags.EnableDepthTesting;

Alpha testing

By default alpha testing is disabled when rendering outlines. This behaviour can be overriden by setting EnableAlphaTesting flag of Rander Flags (either via scripting API or with editor).

outlineSettings.OutlineRenderMode = OutlineRenderFlags.EnableAlphaTesting;

Ignore layers

When adding a GameObject to outline collection it is often desirable to ignore child renderers in specific layers (for instance, TransparentFX). This can be achieved by settings the IgnoreLayers mask in outline settings (or through corresponding API).

var outlineSettings = GetComponent<OutlineBehaviour>();
outlineSettings.IgnoreLayerMask = LayerMask.GetMask("TransparentFX", "UI");

Extensibility

There are a number of helper classes that can be used for writing highly customized outline implementations (if neither OutlineBehaviour nor OutlineEffect does not suit your needs). All outline implementations use following helpers:

Using these helpers is quite easy to create new outline tools. For instance, the following code renders a blue outline around object the script is attached to in myCamera:

var commandBuffer = new CommandBuffer();
var renderers = GetComponentsInChildren<Renderer>();

// Any implementation of `IOutlineSettings` interface can be used here instead of `OutlineSettings`.
var settings = ScriptableObject.CreateInstance<OutlineSettings>();

settings.OutlineColor = Color.blue;
settings.OutlineWidth = 12;

// Get outline assets instance. In real app this usually comes from MonoBehaviour's serialized fields.
var resources = GetMyResources();

using (var renderer = new OutlineRenderer(commandBuffer, resources))
{
  renderer.Render(renderers, settings, myCamera.actualRenderingPath);
}

myCamera.AddCommandBuffer(OutlineRenderer.RenderEvent, commandBuffer);

Integration with Unity post-processing v2.

NPM

Install the package, add Outline effect to PostProcessProfile's overrides list. Configure the effect parameters, make sure outline resources and layer collection are set:

Post processing outlinesettings

Assign the configured PostProcessProfile to PostProcessVolume and that's it!

More info on writing custom post processing effects can be found here.

Integration with Universal Render Pipeline (URP).

NPM

Install the package, add OutlineFeature to ScriptableRendererData's list of features. Configure the feature parameters (make sure outline resources reference is set). Outline objects can be selected by layer or explixitly using OutlineLayerCollection:

URP outline settings

Enable depth texture rendering in UniversalRenderPipelineAsset and that's it!

Integration with High Definition Render Pipeline (HDRP).

NPM

TODO

Motivation

The project was initially created to help author with his Unity3d projects. There are not many reusable open-source examples of it, so here it is. Hope it will be useful for someone.

Documentation

Please see the links below for extended information on the product:

Useful links

Contributing

Please see contributing guide for details.

Versioning

The project uses SemVer versioning pattern. For the versions available, see tags in this repository.

License

Please see the license for details.