Code Monkey home page Code Monkey logo

outline-effect's Introduction

Outline Effect

Outline Image Effect for Unity

FEATURES:

Sprite/Line/Mesh renderer support

HDR support (useful for bloom, etc...)

Alpha cutout option

Additive outline rendering option

Merged outline between renderers (or you can add outlines between different colors)

Erase option to keep outlines behind specific renderers

Per renderer color support (up to three different colors)

INSTALLATION:

Option #1 (Recommended): Use OpenUPM or add the package using the Package Manager: https://github.com/cakeslice/Outline-Effect.git (Add from git URL)

Option #2: Download from the Asset Store: https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/outline-effect-78608

Option #3: Download the files and place them anywhere in the Assets folder of your Unity project

USAGE:

Add "Outline Effect" component to camera

Add "Outline" component to renderers

SUPPORT:

Twitter @cakeslice_dev

Unity Forum Thread

outline-effect's People

Contributors

cakeslice avatar claytonious avatar digimatic avatar hobnob avatar jimmycushnie avatar lholsti avatar nikkiwitch avatar openlevel avatar ptwohig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

outline-effect's Issues

Effect always treats alpha channel in _Maintex as opacity

Hello, this outline effect looks wonderful, and thank you for supplying it.
My project has texture channels in a specific way, and while ti doesn't utilize any opacity effects for the models, we do use the alpha channel for translucency effects (for fast SSS).
However the outline effect always wants to utilize this channel as opacity regardless, so i'm unable to get it to correctly outline the model. Verified this by removing the texture that's set in _Maintex, and the outline worked as expected.
Couldn't find any over-rides and toggled about everything I could find on Outline and Outline Effect scripts. Figured I would post here before I begin diving into the code.

Separate Outlines

Is there a feature to outline individual meshes, not aggregate the entire shape?

For instance, this image has 7 meshes but the outline is drawn according to the entire silhouette. Can they each have their own outline drawn?

[Bug] lost Material references

After cleaning up my camera prefab containing stuff of the outline effect, the Material references got lost and, although not in play mode, OnRenderImage has been called and spammed my console with null reference exception logs.

I solved the problem by adding the following lines to the class:

#if UNITY_EDITOR
        private void OnValidate()
        {
            CreateMaterialsIfNeeded();
        }
#endif

This way the materials where created as soon as I selected the GameObject containing the OutlineEffect.

SRP Compatibility

We used this to great effect before we upgraded to the LWRP. I think that the shaders are not SRP friendly and thus are not being rendered by the render pipeline.

Put all of your code in a namespace

Put all of your code in a namespace, many scripts have the same name - conflict. Toggle.cs script exactly need or rename, or placed in a namespace :)

Memory leak with NatCorder

I use your plugin with the asset NatRecorder (a plugin that records the screen). It seems that in certain condition, OutlineEffect causes a memory leak when recording the screen with NatCorder. I found a quick fix to this issue, maybe you can tell me more about it. It seems than erasing rendertexture with the new renderTexture doesn't destroys the old one in the memory

if (renderTexture == null || renderTexture.width != sourceCamera.pixelWidth || renderTexture.height != sourceCamera.pixelHeight) {
 Destroy(renderTexture); // Added line
 renderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 16, RenderTextureFormat.Default);
 extraRenderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 16, RenderTextureFormat.Default);
 outlineCamera.targetTexture = renderTexture;
}

Does not work correctly with multiple cameras (VR)

When using a Virtual Reality headset (Vive) the outlines are shown slightly to the left of the object on the left screen and slightly to the right of the object on the right scene. This leads to two half transparent outlines on both sides of the object.

[Bug] All Objects with Outline component are drawn

All objects which have an outline component are drawn all the time. Regardless if eraseRenderer is set to true or not.
Maybe I misunderstood the concept of the component. But if the outline should not be displayed when eraseRenderer is off, you would need to apply the following patch in OutlineEffect.OnPreRender:

// ...
            if(outlines != null)
            {
                foreach(Outline outline in outlines)
                {
                    LayerMask l = sourceCamera.cullingMask;

                    if(outline != null && l == (l | (1 << outline.originalLayer)))
                    {
                        //PATCH START
                        if (outline.eraseRenderer)
                            continue;
                        //PATCH END

                        for (int v = 0; v < outline.Renderer.sharedMaterials.Length; v++)
// ...

Even with all outlines disabled, effect consumed 0.3ms

Looking at the Profiler, even with all Outline components disabled (which required the integration of the Pull request currently open), OutlineEffect.OnPreRender() consumes 0.3ms of render time.

(With a few outlines enabled, we're up to 1ms which is quite expensive, but also a separate issue.)

Change the lineThickness and fillAmount

Could it be possible to change the variables (lineThickness and fillAmount) in OutlineEffect.cs for different objects, because I want to chang the thickness of line for different objects.

Outline doesn't work on AddComponent

If you add outline after start, it doesn't work.

Steps

  1. Setup the camera with Outline Effect
  2. Add a cube to the scene
  3. Press play
  4. Add Outline component to the cube
  5. Verify that the outline is not visible

Cause

IsVisible = false although actually is visible. OnBecameVisible event is the event used to change the value of that flag. Because this event was already triggered, when you add the Outline component, the value visible doesn't change because the event was fired before

Fix

Possibly, do some checks at OnEnable and decide if this object is visible or not

Workarround

Forcing the mesh to disable/enable triggers again OnBecameVisible event

            public void AddOutline(GameObject go)
            {
                var outline = go.AddComponent<Outline>();
                bool isRendererEnabled = outline.Renderer.enabled;
                if (isRendererEnabled)
                {
                    outline.Renderer.enabled = false;
                    outline.Renderer.enabled = true;
                }
            }

outline not working with surface shaders

I want to add outline to some object in my scene to separate them from the background. The outline wont show with my materials but works fine with the default unity materials see image:

outline bug

shader file:
SHD_ToonShader.zip

EDIT:

i found out that it doesn't show an outline when a object has a texture. I changed line 190 in OutlineEffect.cs to:
outline.Renderer.sharedMaterials[m].mainTexture = null;

Low Performance on Mobile Devices

I used this effect on an android project, the result was perfect Functionality but very low performance, is there any option to make this effect works well on mobile devices?

Performance issues in Editor mode

For some reason the outline spikes over and over in edit mode. I've found this out using the profiler. My scene has many, many sprites, but only a few of them have outlines.
Playmode runs OK, but edit mode is slow.
Profiler is reporting issues around/in SceneView drawing. (If I close the Scene tab, performance goes up significantly. Same with Game tab too though.)

Upsidedown outline

Just downloaded this and tried it out but the outline is flipped vertically and offset a bunch as if it were an outline of a reflection.
outlineglitch

HDRP Support?

Any chance of this coming to HDRP? Would be great since Unity is going that direction more and more.

Show outline between meshes of same color?

Hello.
Is it possible to show borders of same color between meshes?
I have a map created from meshes (created from PolygonCollider2D) - all with same fill color.
If i set different outline colors between parts of the map - it's ok. If I move one element on distance from others - is ok (blue on example). But I have no idea how to outline all parts with same color e.g color1. Looks like all meshes with same outline color are merged into one, big one.
Light green colider on the middle is example without outline.
image

It's possible that is just how it works and it's just not the tool for my scenario :<

blurred outilne

How we can add blur effect to outline?
I tried adding to OnRenderImage()

blur.OnRenderImage(renderTexture, extraRenderTexture);
outlineShaderMaterial.SetTexture("_OutlineSource", extraRenderTexture);

(where blur is added in Start() like
BlurOptimized blur = cameraGameObject.AddComponent();)

but looks like shader can't work with blurred texture

Not working on prefabs

Just downloaded this and have run into a (hopefully) noob issue. I put the Outline script on a simple cube (with OutlineEffect on Main Camera) and it works. Can toggle the effect easily. Then I put the Outline script on the same cube as a prefab that is instantiated at runtime and in its construction process (when Instantiate() is called) I get this unhandled exception:
NullReferenceException: Object reference not set to an instance of an object
cakeslice.OutlineEffect.OnPreRender () (at Assets/OutlineEffect/OutlineEffect/OutlineEffect.cs:228)

I assume this is a timing or order of construction issue because that line of code accesses objects created by the component.
Any suggestions?

Vive

Hi,
this relates to issue#13. For the Vive (atleast for me) it still shows a slightly offset outline for each eye separately. I tried a few things, but i don't know how to fix this, so just letting this be known here.

It causes memory usage getting higher.

thanks for your share and sorry for my bad English.

I applied this to my project and worked greatly.(It uses Mesh Renderer.)
However, the memory usage was getting higher up to 2GB.

OutlineEffect creates garbage per frame.

Per frame allocations OnPreCull:
if (outlineRenderers.Distinct().Count() < outlineRenderers.Count)

originalMaterials = new Material[outlineRenderers.Count];
originalLayers = new int[outlineRenderers.Count];

outlineRenderers[i].material.mainTexture = originalMaterials[i].mainTexture;

originalEraseMaterials = new Material[eraseRenderers.Count];
originalEraseLayers = new int[eraseRenderers.Count];

eraseRenderers[i].material.mainTexture = originalEraseMaterials[i].mainTexture;

renderTexture = RenderTexture.GetTemporary(width, height, 16, RenderTextureFormat.Default);
Temporary texture is optimized. but you can prepare a texture.
#8

I've fixed above memory leaks.

cakeslice.LinkedSet.AddOrMoveToEnd() does not work absolutely correctly

Without knowing I was working on a third party software I've started writing unit tests for this.
Here's a the test:

    [Test]
    public void LinkedSetTestWithComparer()
    {
        LinkedSet<string> ls = new LinkedSet<string>((IEqualityComparer<string>)(new MeaninglessSrtingComparer()));
        ls.Add("12");
        Assert.That(ls.Contains("34"));
        Assert.False(ls.Add("56"));
        ls.Add("1");
        var at = ls.AddOrMoveToEnd("34");
        Assert.That(ls.Contains("1"));
        var temp="";
        foreach (var s in ls) {
            temp = s;
        }
        Assert.That(temp.Equals("12"));

    }


class MeaninglessSrtingComparer : IEqualityComparer<string> {
    public bool Equals(string s1, string s2) {
        //return s1.ToString().Length == s2.ToString().Length;
        return s1.Length == s2.Length;
    }

    public int GetHashCode(string s) {
        //return s.ToString().Length;
        return s.Length;
    }

The last assertion should not fail but it is.Instead of the element "12" be moved at the end it is replaced with the new one.Which not exactly the returned result and the name of the method implie.

To me the fix looks easy:

			else if (dictionary.TryGetValue(t, out node))
			{
				list.Remove(node);
				node = list.AddLast(node.Value);
				dictionary[node.Value] = node;
				return AddType.MOVED;
			}

Update dynamically the outline Renderers array

Hi, Thanks for share this work !!
I have found a problem but i didn't see how to correct it.
When i update dynamically the outline Renderers array and if this array become empty some error arrive.
I Think it comes of the OutlineEffect.cs script on the OnPreCull() function :

You have the processing for this case
if (outlineRenderers != null && outlineRenderers.Count != 0)
but not for the
else

Thanks for your time

Outlines on scene objects aren't registered if AutoEnableOutlines is false

If there's an active object in the scene with an enabled Outline, it may not be registered with the OutlineEffect if AutoEnableOutlines is false. The outcome depends on script execution order.

If OnEnable() gets called on Outline first, it will not find an OutlineEffect instance and will not register itself. When OnEnable() is later called on OutlineEffect it also won't register the object because AutoEnableOutlines is false so it completely ignores it.

The fix would be rewriting the OnEnable() in OutlineEffect like this:

private void OnEnable()
{
    Outline[] o = FindObjectsOfType<Outline>();
    if (autoEnableOutlines)
    {
        foreach (Outline oL in o)
        {
            oL.enabled = false;
            oL.enabled = true;
        }
    }
    else 
    {
        foreach (Outline oL in o) 
        {
            if (!outlines.Contains(oL))
                outlines.Add(oL);
        }
    }
}

Create GitHub release (git tag)

Hi @cakeslice,

Thanks for creating this awesome packages. I'm the creator of OpenUPM, an open source registry collects upm packages with automatic build pipelines. Our build pipelines monitor git tags (that are semver) and publish new release automatically. You can checkout the announcement on Medium for details.

Your package is available at https://openupm.com/packages/com.cakeslice.outline-effect/

To make it work, please consider creating a git tag (GitHub releases) that match the version of package.json.

To learn best practices of maintaining an upm repository, please checkout https://openupm.com/docs/managing-upm-project.html

Material doesn't have a texture property '_MainTex'

Hey,
i'm using the outline effect for an ARKit Project on an IPad 2017.
It's nice, but i get always this error, when running it on the IPad:
`Material doesn't have a texture property '_MainTex'
cakeslice.OutlineEffect:OnPreRender()

[/Users/builduser/buildslave/unity/build/Runtime/Shaders/Material.cpp line 1170]
(Filename: /Users/builduser/buildslave/unity/build/Runtime/Shaders/Material.cpp Line: 1170)`

Do you know how to fix it? (Googled it, but didnt help me. Sorry!)
Thanks :)

Rendering LODs

There's a problem when rendering LODs using this Outline-Effect plugin. If you have a LOD swap in the middle of an animation, the outline will encompass both LOD renderers.

I tried creating a pull request but it's denied, so the way I fixed it on my end was by adding this code to Outline.cs

private bool visible;

private void OnBecameVisible()
{
    visible = true;
}

private void OnBecameInvisible()
{
    visible = false;
}

public bool IsVisible => visible;

And then this code to OutlineEffect.cs

foreach (Outline outline in outlines)
{
    if (!outline.IsVisible)
        continue;

Highlight

Hello:
The compiler is highlighted, but the compiled exe is not highlighted

Separate tint color from outline color

It would be a nice enhancement to separate the outline color from the tint color (and then perhaps the tint strength).

For example, I would like to have a white outline on an object, but tint everything slightly black inside of the outline.

unnecessary draw call and mistakes when submeshes use different texture

I found it has many unnecessary draw calls when outline camera render. And if submeshes use different material with different texture, it causes some mistakes, especially when you use mesh to render atlas, like spine object.

It's wierd to render SharedMaterials.Length * (sharedMesh.subMeshCount - 1) times in OutlineEffect's OnPreRender(). I can't get why. So I change the render times to correspond to outline.SharedMaterials.Length
ๆ•่Žท
Everything works fine. Is this a bug or there's some consideration in it ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.