Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Applying image effects to specific objects?

Discussion in 'Editor & General Support' started by Denisowator, May 29, 2017.

  1. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Notice how I said "image effects" and not "Image Effects", as I'm not talking about the Unity Pro scripts, but rather anything that is considered an image effect. Such as the Post Processing Stack, and effects created by people through scripts (much like Image Effects).

    I know that by default, image effects are usually applied to the whole screen. So I want to know if there's a technique to make them apply to either specific objects and/or layers. I have already tried this by simply changing the "Culling Mask" and "Depth" of cameras, but it doesn't work. I have a camera for only using the Post Processing Stack image effects, and I have the Culling Mask set to "Nothing" and the "Clear Flags" set to "Don't Clear". This means the camera is rendering absolutely nothing, yet since there are things on cameras in a lower depth, it still renders over them.

    A problem I can also see with doing it this way (if it did somehow work) is that I would need to create a separate camera object for every single different object/layer/effect, which would obviously get very messy to organize and manage. Not to mention it would be harder to sort through the cameras, if one has a problem and caused things to look weird (which has happened to me 5+ times in the past week).

    So, has anyone figured out a way of setting an image effect to either a specific object or layer? I've looked, and people seem to only ever ask about the Image Effects specifically, not image effects in general.
     
    shottogan and Harinezumi like this.
  2. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    EDIT: new version here

    I wrote a script that can mask post effects with defined Mesh Filters. (Updated May 31, 2017)
    Tested in Unity 5.6.1f1

    Download all attached files to your Assets folder.
    Add the PostEffectMask.cs script to a camera after your post effect scripts. Add objects to the Mask Objects list in the inspector.

    PostEffectMask2.cs is a different version which also works with Debug Views and Ambient Occlusion of the Post Processing Stack (effects that are applied before transparent objects are drawn). It currently does not work with MSAA enabled and has a drawback that it also masks out all transparent objects in the view.
     

    Attached Files:

    Last edited: Jul 23, 2017
    Oxanen, Alvarezmd90 and LightingBox2 like this.
  3. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    It doesn't seem to work. I add the object to the "Mask Objects" after setting the size to 1, but it doesn't work.
    The effects still happen on the whole screen, and I also noticed that the Post Processing Stack effects disappear the second I add either of those scripts to my camera.

    I tried using that shader for the material I have on my object, but that doesn't do anything. That is if I'm using the correct one. The only one I can find is under "Unlit", and I don't know if it was there before I imported your one.

    I'm using 5.6.1f1.
     
  4. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    I tested it on an empty 5.6.0 project with Post Processing Stack from Asset Store and it works.

    Either something has changed in 5.6.1 or you have some other rendering effects.
    Make sure the component is at the bottom of the camera's inspector after the Post Processing Behaviour

    The shader is only used in the script, don't add it to your objects.
     
    LightingBox2 likes this.
  5. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Just tried it in a new scene, and it still doesn't work.

    I have the script in a child camera (child of the main camera). Here are the settings:
    upload_2017-5-31_16-9-0.png
    I tried changing the "Culling Mask", and the three checkboxes right under the "Target Texture". But neither worked.
    Whenever I move the mask script above the PPB script, the effect appears and displays normally, but when I put it under, like you said, the whole effect turns off, no matter what I put in the "Mask Objects". So I'm guessing it is doing something since it's causing the effect to turn off.

    I will create a whole new project, and try it there, and I'll let you know how it goes.

    UPDATE: Yep, same deal. The second I put the mask script under the effect, it doesn't show, and setting the mesh still does nothing.
     
    Last edited: May 31, 2017
  6. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    I fixed some problems in the scripts (the attached files in my previous post have been updated).

    I tested in 5.6.1f1 and indeed the PostEffectMask2.cs doesn't work when antialiasing is enabled (turn it off e.g. by unchecking Allow MSAA on the camera)
    PostEffectMask.cs works with AA enabled but it doesn't mask Debug Views, Motion Blur or Ambient Occlusion of the Post Processing Stack.
     
    Denisowator likes this.
  7. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Works great now, thank you. :D

    I do have a sort of request. There are some effects I'm planning on using, which are basically distortion effects. And currently the effects that are applied to the masked object stop right at the mesh's edges.

    One effect that is clearly being affected is Kino's Analog Glitch effect. Where the lines on the edges should bleed out onto the rest of the scene, they just stop at the mesh, and it doesn't look as realistic.

    So my request, is maybe adding some sort of leeway on the mesh. Maybe somehow inflating it, without it actually affecting the mesh, but creating an invisible margin around it, which allows for effects to bleed out slightly.

    Of course this is 100% your decision. I'm not going to make you do my work for me, and I can definitely research this type of stuff, and implement it myself in the future if I really need it. But seeing as you have way more coding experience and this is your code to begin with, it would be really cool to have this as an official feature type thing, so that maybe even others can have this sort of stuff in their effects.

    Obviously I don't know how hard something like that would be to actually implement, but from the way I see it, the logic behind it is pretty straight forward.
     
    Last edited: May 31, 2017
  8. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    I made a completely new version of this mask, just import the attached unitypackage.
    It now uses alpha blending instead of stencils which enabled me to implement a lot of new features.
    Tested in 5.6.1, MSAA won't break this like the previous one.

    Post Effect Mask

    Mask any camera post effects. Draws an alpha mask and uses alpha blending to blend the processed image on top of the unprocessed image.

    Add a PostEffectMask -component to a camera after the post effect scripts you want to mask.
    Add a PostEffectMaskRenderer -component to the objects you want to include in the mask. (Mesh Filter is required)

    Parameters
    Post Effect Mask:
    - Opacity: Control the opacity of the processed picture in the mask.
    - Invert: Invert the mask.
    - Blur: Level of blur applied on the mask.
    - Full Screen Texture: Add the alpha channel of a texture to the mask.

    Post Effect Mask Renderer: (parameters for individual objects)
    - Mask: Which mask is this object rendered to.
    - Opacity: Opacity used when drawing this object to the mask.
    - Scale: Scale the vertices of this object when drawing to the mask.
    - Texture: Texture applied to the mesh when drawing. Only the alpha channel is used!

    and a couple more explained in the Readme.txt
     

    Attached Files:

    Last edited: Jul 9, 2017
    Alvarezmd90 and Denisowator like this.
  9. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Cheers! Works great. :D
     
  10. sticklezz

    sticklezz

    Joined:
    Oct 27, 2015
    Posts:
    33
    Hey this is really cool- can't tell you how long have been looking for something like this! A couple of things I notice don't seem to work (at least with my content)

    - skinned meshes seem to make it stop working (when "PostEffectMaskRendere" is applied) ; the mask gets disabled and everything gets post effect
    - it only seems to work with the first material of a mesh
     
  11. sticklezz

    sticklezz

    Joined:
    Oct 27, 2015
    Posts:
    33
    Also does not seem to work on mobile (or at least iOS)- if there was some way to address this, it would be a huge help!!!
     
    Last edited: Jul 22, 2017
  12. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    Post Effect Mask

    Mask any camera post effects. Use e.g. to apply a post effect only to defined objects.
    Draws an alpha mask and uses alpha blending to blend the processed image on top of the unprocessed image.
    Effects that leak ouside the normal mesh of the object on the screen (e.g. Bloom) are cut out at the edges but you may get the effect you like by adjusting the Blur or other parameters of the mask.

    How to use:
    Add a Post Effect Mask -component to a Camera after the post effect scripts you want to mask.
    Add a Post Effect Mask Renderer -component to the objects you want to include in the mask.
    Tweak the parameters of these components to your liking.


    Post Effect Mask parameters:
    - Opacity: Control the opacity of the processed picture in the mask.
    - Invert: Invert the mask.
    - Blur: Level of blur applied on the mask.
    - Capture Mode: At which point in rendering is the unprocessed image captured.
    - Before Opaque Effects:
    - Before effects that are applied at CommandBuffer event BeforeImageEffectsOpaque or later (e.g. Ambient Occlusion in the Post Processing Stack)
    - NOTE: this mode will cause all transparent objects to be masked out​
    - Before Effects:
    - Before effects that are applied at CommandBuffer event BeforeImageEffects or later (e.g. majority of post effects, Motion Blur, Bloom in the Post Processing Stack)​

    - Full Screen Texture: Add the alpha channel of a texture to the mask.

    - Renderers enabled: Toggle the renderers attached to this mask.
    - Depth test: Is depth testing done on objects rendered to this mask.
    - Cull mode: Hide front, back, of no face of the rendered triangles. (Off means that a quad will be visible from both sides)


    Post Effect Mask Renderer parameters: (for individual objects)
    - Mask: Which mask is this object rendered to.
    - Mode: Choose what to render to the mask.
    - Use Meshes:
    - Find MeshFilters from the gameobject the script is attached to and draw their meshes to the mask.​
    - Use Renderers:
    - Find Renderers from the gameobject the script is attached to and draw them to the mask.
    - IMPORTANT! "Override Global Options" does not work with this mode!​
    - Use Custom Mesh:
    - Draw only the mesh set as the "Custom Mesh".​
    - Include Children: Find all MeshFilters or Renderers in the transform hierarchy under this gameobject.


    Options: (These can be set globally for the mask or overridden by individual objects)
    - Opacity: Opacity used when drawing this object to the mask.
    - Scale: Scale the vertices of this object when drawing to the mask.
    - Extrude: Move the vertices along their normals by this amount.
    - Texture: Texture applied to the mesh when drawing. Only the alpha channel is used!


    See also additional notes in Readme.txt
    Tested in Unity 5.6.2f1
     

    Attached Files:

    Last edited: Jan 3, 2018
  13. Akeru

    Akeru

    Joined:
    May 2, 2014
    Posts:
    6
    I'm using 5.6.2 and I can't make it work, probably it's for my dumbness. Could you attach an example scene to see how it works, please?
     
  14. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    I made a demo project and also fixed one null reference exception (package in previous post updated)
     

    Attached Files:

    gohst and Denisowator like this.
  15. Mihaszna

    Mihaszna

    Joined:
    Jul 1, 2016
    Posts:
    1
    Hi,

    villevli, you are awesome and your script works very well!
    However, I have a noob question: If I change a canvas rendermode to "Screen Space - Camera" the mask does not include the UI elements. Do you have any ideas why is this happen?

    EDIT:
    Oh, I've found out that "Screen Space - Overlay" did not use camera post effect at all, that's why I thought the mask worked. But now I see CanvasRenderer is not a renderer for CommandBuffer. But I still can use Sprites inside a Canvas, and SpriteRenderer can be masked out with your script.

    As my problem is solved, I have nothing to say, just simply thank You.
     
    Last edited: Dec 21, 2017
    Harinezumi likes this.
  16. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    The UI elements are considered as transparent geometry so they will disappear in masked areas when the Capture Mode of the mask is Before Opaque Effects. Set Capture Mode to Before Effects and the UI elements should be visible again. Note that some (Opaque) Post Effects that are rendered before transparent objects will not be masked in this mode.
     
  17. MU-TH-UR

    MU-TH-UR

    Joined:
    Aug 16, 2016
    Posts:
    17
    This works exactly as I wanted it in VR, but it is really low resolution. Any way to up it? Left is on, right is off. Single Pass Stereo/Forward rendering.

    Thanks!
     

    Attached Files:

  18. MU-TH-UR

    MU-TH-UR

    Joined:
    Aug 16, 2016
    Posts:
    17
    I figured it out by just setting the resolution of the render texture, which works but runs a lot worse since I shouldn't be using them in VR but works for prototyping.

    m_unprocessed = RenderTexture.GetTemporary(3024, 1680, 0);
     
  19. MonkeyPuzzle

    MonkeyPuzzle

    Joined:
    Jan 17, 2016
    Posts:
    70
    Great tool! Is there a way to use this with skeletal meshes?
     
  20. villevli

    villevli

    Joined:
    Jan 19, 2016
    Posts:
    60
    This should work with Skinned Mesh Renderers if you add the Post Effect Mask Renderer component and set the Mode parameter to Use Renderers.
     
    MonkeyPuzzle likes this.
  21. MonkeyPuzzle

    MonkeyPuzzle

    Joined:
    Jan 17, 2016
    Posts:
    70
    Last edited: May 17, 2018
  22. Coding2Handed

    Coding2Handed

    Joined:
    Jan 14, 2018
    Posts:
    4
    Excellent Script. I tried it with an asset called Simple LUT and it worked perfectly. Thanks so much villevli!
     
  23. Nsingh13

    Nsingh13

    Joined:
    Dec 17, 2014
    Posts:
    18
    I tried it but can't seem to get it to work. When I put the Post Processing Mask script on the camera it automatically hides all effects, but then the PP Mask Renderer script on individual objects doesn't seem to do anything.

    I'm using Unity's PP Stack v2 on Unity 2018.2
     
    Last edited: Jul 13, 2018
  24. Nsingh13

    Nsingh13

    Joined:
    Dec 17, 2014
    Posts:
    18
    Never mind, I figured it out. Turned out I had to increase the scale, as the default was too small. Also works for mobile (Android) for me just in case anyone else comes across this thread. Thank you so much for this script, it's a great solution!
     
  25. gohst

    gohst

    Joined:
    Jul 13, 2014
    Posts:
    5
    Been looking for something like this for waaay too long.
    Tried applying post processing to discrete areas (as opposed to the entire scene), myself, and failed miserably so I am very appreciative that "villevli" had the skills and time to nail it for version 2018.2.10f1.
    Solved my problem re. AR on Android altho I have yet to test it out w iOS.
    Anyway, thanx, villevli.
     
  26. vpetyushka

    vpetyushka

    Joined:
    Jun 18, 2018
    Posts:
    1
    Don't you have issues with blurring? I cant turn it off
     
  27. gohst

    gohst

    Joined:
    Jul 13, 2014
    Posts:
    5
    Sorry for the late reply.
    Wasn't notified.
    The only post processing I am doing is to desaturate the color of the AR only w/o affecting the environment it is composited atop of.
    I am not using any blurring effects.
    Hope things work out for you.
     
  28. Hybris_Team

    Hybris_Team

    Joined:
    Oct 17, 2015
    Posts:
    107
    Hey guys I can't get this to work. I have a plane with a texture with an Unlit/Transparent shader that I am using to display GUI. I want this to be ignored by the post effects, is there a certain setup for UI like this?
     
  29. Florian-

    Florian-

    Joined:
    Aug 20, 2017
    Posts:
    5
    @villevli Thank you so much for this. Invaluable for the look of my current project and would never have been able to do it on my own. :)
     
  30. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Couldn't you do it the same way you exclude regular objects?
     
  31. Jeremy-Borton

    Jeremy-Borton

    Joined:
    Oct 21, 2015
    Posts:
    52
    Thanks for the demo scene! I got it to work in unity 2019 with just changing two lines of code that it told me to. It's a pretty cool effect for masking out the post processing effects for if you have like a health bar you always want visible or something...Very cool!
     
  32. leapp

    leapp

    Joined:
    Mar 19, 2015
    Posts:
    1
    It can't be used at moving gameObject
     
    BanzBowinkel likes this.
  33. BanzBowinkel

    BanzBowinkel

    Joined:
    Jun 17, 2015
    Posts:
    6
    Yep! Really unfortunate. Was searching for something to allow me composing for AR.
    So that my camera feed is not affected by the effects. But as beeing said it does not work with moving objects (for example animated figures). Otherwise great stuff. Can't that be fixed somehow!?
     
  34. Tarrag

    Tarrag

    Joined:
    Nov 7, 2016
    Posts:
    122
    doesn't work for lwrp - NullReferenceException: Cannot find Unlit/Alpha shader.
     
  35. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    55

    Thank you, this is exactly what I was trying to do, just need a little advice.

    I'm currently rendering a view to a rendertexture with the colours in unlit black and white (black mesh occludes part of the white to produce the white "alpha" channel. In my shader, I piped this into the alpha of a lerp function. But when using "Full Screen Texture", it looks for true alpha instead of greyscale. Where can I make this change?
     
    Last edited: Oct 4, 2019
  36. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    55
    I'm assuming it has something to do with the BlendMode in CreateResources() and OnRenderImage(). I would have thought changing these to SrcColor instead of SrcAlpha would work but it doesn't
     
  37. tangwilliam

    tangwilliam

    Joined:
    May 4, 2016
    Posts:
    7
    Hi, have you found out some way to make this ?
    I tried two methods:
    1. two camera, the first camera's clear flag set to don't clear, while it has post effects. The second camera only render the GUI without post effects.
    2. write custom blit to replace the Graphics.Blit() to make stencil worked. The UI are marked by stencil, and Post Effect shader only process the other area which are not marked by stencil.
    But, the two methods does not work with MSAA enabled.
    Do you figure out some other way to achieve this ?