Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Serlite · Aug 07, 2016 at 01:23 PM · shadershaderlabocclusiongl

Writing a fixed function shader to render occluded GL lines with a different alpha

I'm trying to write a multi-pass shader that I'll be using for colouring lines and shapes drawn by the various GL methods. The intention of the shader is to render visible parts of the shapes using the supplied colour in GL.Color(), and rendering occluded parts using a transparent variant of that colour. However, for some reason my shader can only achieve one of those two goals, and not both at the same time.

Here's my current shader:

 Shader "Custom/GLShader" {
     SubShader {
         BindChannels {
             Bind "vertex", vertex
             Bind "color", color
         }
         Pass
         {
             Blend SrcAlpha OneMinusSrcAlpha
             ZWrite Off
             Cull Off
             Fog { Mode Off }
         }
         Pass
         {
             Blend SrcAlpha One 
             ZTest Greater
             ZWrite Off
             Cull Off
             Fog { Mode Off }
         }
     }
     Fallback "Diffuse"
 }

And here's the relevant parts of the C# script attached to my main camera:

 public Shader glShader;
 private Material glMat;

 void Awake()
 {
     glMat = new Material(glShader);
 }

 void OnPostRender()
 {
     glMat.SetPass(0);
     GL.PushMatrix();
     GL.Begin(GL.QUADS);
     GL.Color(Color.red);
     GL.Vertex3(0, 0, 0);
     GL.Vertex3(5F, 0, 0);
     GL.Vertex3(5f, 5F, 0);
     GL.Vertex3(0, 5f, 0);
     GL.End();
     GL.PopMatrix();
 }

This results in the visible parts of the shape being rendered properly, but not the occluded parts:

alt text

Swapping the two Passes in the shader, I can get the occluded part to render now, but the visible parts are now missing:

alt text

I feel like I've misunderstood how a Pass works, and need some clarification on how I can tweak the shader to make this work - or if that isn't possible, what the best approach for this would be that I could still use in conjunction with my C# code.

I did find some similar questions like the shader provided at Render Occluded pixels to gray color, but I'm not sure how to adapt that to how I'm currently drawing shapes (since they won't have a texture, only a colour given by GL.Color().

order2.png (7.8 kB)
order1.png (10.5 kB)
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

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Bunny83 · Aug 07, 2016 at 01:49 PM

Well, you only render one pass of your shader. You have to do this:

 void OnPostRender()
 {
     GL.PushMatrix();
     for (int i = 0; i < glMat.passCount; i++)
     {
         glMat.SetPass(i);
         GL.Begin(GL.QUADS);
         GL.Color(Color.red);
         GL.Vertex3(0, 0, 0);
         GL.Vertex3(5F, 0, 0);
         GL.Vertex3(5f, 5F, 0);
         GL.Vertex3(0, 5f, 0);
         GL.End();
     }
     GL.PopMatrix();
 }

A lot people seem to not fully understand what a second pass actually means. It means the whole object has to be drawn again, just with a different pass. That's why a second pass usually causes another "drawcall". That's also why Unity now seperates those in the stats window and lists "SetPass calls" seperately.

Comment
Add comment · Show 3 · 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 Glurth · Aug 07, 2016 at 04:51 PM 0
Share

Hmm, anyway to tell unity to use the same verticies as "the last pass"? Or should we cache that stuff ourselves? (obviously no diff in your example, I'm talking about more procedural based stuff.)

avatar image Bunny83 Glurth · Aug 07, 2016 at 11:24 PM 1
Share

No you can't. That's the point of the GL immediate mode. What you pass in as data is processed immediately as soon as GL.End is invoked. At this point the vertex data is passed to the GPU and causes a "drawcall". So if you have multiple passes you have to "cache" the content yourself. That's why in most cases where the shader gets a bit more complex it's way easier to use a $$anonymous$$esh / $$anonymous$$eshFilder / $$anonymous$$eshRenderer setup.

Of course you can't change the pass / shader in-between GL.Begin and GL.End. SetPass is part of the shader setup for one or multiple drawcalls. When SetPass is called the GPU pipeline will be flushed and will setup the new shader (shader as it's seen from the GPU where a shader is a vertex & fragment shader function). GL.Begin initiates a drawcall and GL.End will finish it.

avatar image Serlite · Aug 07, 2016 at 07:44 PM 0
Share

That makes a lot of sense! I definitely failed to make the connection between shader passes and SetPass(), even though it seems so clear to me now.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Why Unity compiled shader doesn't use the GLSLPROGRAM/GLSL syntax? 0 Answers

GL - Shader not working in Android 1 Answer

How do you hide a shader property? 2 Answers

Logical BlendOp not working 0 Answers

Shader - What is float3.xy? 1 Answer


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