Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Rob-Fireproof · Jan 20, 2014 at 03:16 PM · shaders

Using the stencil-buffer in a post-process?

Hi all,

(Cross-post from the forum - didn't get any response there!)

I'm trying to do a graphical effect where a couple of objects in the scene write to the stencil buffer, and then a post-fx reads the stencil buffer to do a full-screen effect.

The part where the objects write to the stencil buffer is definitely working.

Let's say I just want to write green pixels where the stencil buffer has been written to earlier. Here's my shader:

Shader "Green" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+1"} Pass { Stencil { Ref 1 Comp equal Pass keep ZFail keep }

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         struct appdata {
             float4 vertex : POSITION;
         };
         struct v2f {
             float4 pos : SV_POSITION;
         };
         v2f vert(appdata v) {
             v2f o;
             o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
             return o;
         }
         half4 frag(v2f i) : COLOR {
             return half4(0,1,0,1);
         }
         ENDCG
     }
 } 

}

If I have my OnRenderImage function blitting straight from source to dest using this shader, everything works as expected - I get solid green on screen only where I wrote to the stencil:

 void OnRenderImage (RenderTexture source, RenderTexture dest) 
 {
     Graphics.Blit (source, dest, greenMat);    
      }


But, if I try to use an intermediate buffer, it seems to ignore the Stencil section of the pass, and just write green to every pixel:

 void OnRenderImage (RenderTexture source, RenderTexture dest) 
 {
     RenderTexture buffer = RenderTexture.GetTemporary(source.width, source.height, 0);

     Graphics.Blit (source, buffer, greenMat);
     Graphics.Blit(buffer, dest);

      }

This just results in a completely green screen.

I've noticed that there's a RenderTexture.SupportsStencil method, which returns false for my buffer, but I can't find any documentation on why, or how to change it. Is that even relevant? I only want to use the main screen's stencil buffer.

This is on PC.

Any help would be much appreciated, Rob.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

5 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by markefus · Sep 15, 2016 at 12:44 PM

Even though this question is two and a half years old, there is nowhere on the internet with the correct answer. I spent a long time figuring it out.

This should allow you to use the stencil buffer in a post-process effect.

alt text


09-14-2016-stencilbuffer.jpg (71.2 kB)
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Henry_Sun · Sep 29, 2021 at 06:53 AM 0
Share

Thanks for your example But I find out it doesn't work for the first time. It turns out we don't need the "buffer" parameter for the first Blit. Graphics.Blit(source,material);

It's working for me now.

avatar image
1

Answer by xjqxzyr · May 16, 2017 at 04:18 PM

Recently,I make a post effect of sss by blur the character skin in post effect,but need stencil buffer,I did many way tries,The actual truth is that antialiasing or other post effect before mine cleared the stencil buffer ,if you want to get the correct stencil buffer you could disable AA or other post effects. Though I found that the cam.clearStencilAfterLightingPass is always false,and use the [ImageEffectOpaque] attribute did help nothing. By the way , I have to tell the truth ,The qiankanglai did the right ways.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by qklxtlx · Mar 07, 2015 at 08:15 AM

It seems stencil is cleared before OnRenderImage. I came up with a method to use this for post process:

  • Draw in OnPostRender

  • Blit with the origin depth buffer & new color buffer

I think you should try only drawing the buffer color buffer + dest depth buffer.

ps. I've posted more details and a fastBloom with stencil buffer in my blog

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Sparrowfc · Mar 31, 2015 at 09:13 AM

Thank for qklxtlx's reply, which enlightens me a lot. The key point is to use same stencil buffer when using Graphic.Blit. For your case, just replace line 5 with code below:`

Graphics.SetRenderTarget(buffer.colorBuffer, source.depthBuffer);

Graphics.Blit(source, material);

To be more sepecific, when you use RenderTarget.GetTempory(int width, int height) to get a RenderTarget, that target don't contain the stencil buffer, becouse the depth bit is set to 0 in default. Use RenderTarget.GetTempory(int width, int height, 24) to get a target with depth/stencil buffer. (It's like create depth buffer using D24S8 formate in D3D I guess)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by markefus · Jan 27, 2019 at 06:00 AM

     public Shader shader;
     private Material mat;
   
     void OnEnable()
     {
         mat = new Material(shader);
     }
 
     //'It Just Works' -- Todd Howard
     void OnRenderImage(RenderTexture source, RenderTexture destination)
     {
         RenderTexture buffer = RenderTexture.GetTemporary(source.width, source.height, 24);
         Graphics.Blit(source, buffer, mat);  
         Graphics.Blit(buffer, destination);
         RenderTexture.ReleaseTemporary(buffer);
     }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image slim-brand-interactive · Nov 06, 2019 at 05:01 PM 0
Share

This doesn't work for me.

This is the shader code I use:

 Shader "Hidden/OnionSkinning"
 {
     Properties
     {
         _$$anonymous$$ainTex ("Base (RGB)", 2D) = "white" {}
     }
     SubShader
     {
         Cull Off ZWrite Off ZTest Always
 
         Tags { "RenderType"="Opaque" "Queue"="Geometry" }
 
         CGINCLUDE
         struct Input
         {
             float4 vertex : POSITION;
             float2 uv : TEXCOORD0;
         };
 
         struct Varyings
         {
             float2 uv : TEXCOORD0;
             float4 vertex : SV_POSITION;
         };
 
         Varyings Vertex(Input v)
         {
             Varyings o;
             o.vertex = UnityObjectToClipPos(v.vertex);
             o.uv = v.uv;
             return o;
         }
 
         sampler2D _$$anonymous$$ainTex;
 
         ENDCG
 
         Pass
         {
             Stencil {
                 Ref 1
                 Comp equal
                 Pass keep
                 ZFail keep
             }
 
             CGPROGRA$$anonymous$$
             #pragma vertex vert
             #pragma fragment frag
 
             #include "UnityCG.cginc"
 
             struct appdata
             {
                 float4 vertex : POSITION;
                 float2 uv : TEXCOORD0;
             };
 
             struct v2f
             {
                 float2 uv : TEXCOORD0;
                 float4 vertex : SV_POSITION;
             };
 
             v2f vert (appdata v)
             {
                 v2f o;
                 o.vertex = UnityObjectToClipPos(v.vertex);
                 o.uv = v.uv;
                 return o;
             }
 
             fixed4 frag (v2f i) : SV_Target
             {
                 fixed4 col = fixed4(1,1,1,1);
 
                 return col;
             }
             ENDCG
         }
     }
 }
 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

25 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Is it possible to AlphaTest prior to writing to the Stencil Buffer? 1 Answer

Shadows on terrain splat map shader 0 Answers

How do I use custom tree geometry in Unity? 2 Answers

Missing shaders when import from Maya 0 Answers

About the shader of UIToolkit 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges