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
0
Question by Matthew A · Feb 14, 2013 at 09:49 AM · shadertransparencyalphablending

Change blend mode from outside shader?

I've been doing something which requires quite a lot of rendering transparent objects to texture.

These objects are used directly in the scene with standard alpha blending ("Blend SrcAlpha OneMinusSrcAlpha"). In order to get the correct alpha when rendering to texture, I need to use pre-multiplied alpha ("Blend One OneMinusSrcAlpha").

Is there any way to change the blend mode from a script, so I don't have to duplicate every single shader just to change one line?

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

3 Replies

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

Answer by Philipp · Feb 14, 2013 at 11:14 AM

I'm 99% certain this isn't possible. However your various shader versions can use #include or UsePass to minimize code duplication.

Comment
Add comment · Show 2 · 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 Matthew A · Feb 14, 2013 at 12:50 PM 0
Share

That's a shame. I hadn't considered #includes / UsePass though. I'll test a few things, then comment with what I think works best.

avatar image Matthew A · Mar 15, 2013 at 11:39 PM 0
Share

I couldn't really get UsePass to work properly, so I ended up using a #include with the main body of the shader in it and one #define. Something like this:

 Shader "Foo/Foo"
 {
     Properties
     {
         // ...
     }
     
     SubShader
     {
         Tags
         {
             // ...
         }
 
         // The one line difference...
         Blend SrcAlpha One$$anonymous$$inusSrcAlpha
         
         AlphaTest Greater .01
         Color$$anonymous$$ask RGBA
         // ...
         
         Pass
         {
             CGPROGRA$$anonymous$$
             
             // pragmas have to be before the include
             #pragma vertex vert
             #pragma fragment frag
 
             // one shader defines this, the other doesn't.
             #define FOO
             #include "Foo.cginc"
             
             ENDCG 
         }
     }
 }

It's still way more code duplication than should be necessary, but it's neater than copying the entire file.

avatar image
7

Answer by Juho_Oravainen · Jun 11, 2014 at 12:46 PM

Setting blend modes by scripting has been possible since 4.3.

On shaderlab add Float properties for the modes:

 Properties { 
     MySrcMode ("SrcMode", Float) = 0
     MyDstMode ("DstMode", Float) = 0
 } 
 
 Pass {
     Blend [MySrcMode] [MyDstMode]
 }


On script side update the values with Material.SetInt() and BlendMode enums:

 material.SetInt ("MySrcMode", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
 material.SetInt ("MyDstMode", (int)UnityEngine.Rendering.BlendMode.Zero);

Edit: Added typecasts as suggested by badweasel

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 badweasel · Feb 01, 2015 at 06:54 AM 0
Share

This works. The only thing is that you have to typecast the blend modes as they are enums...

  material.SetInt ("$$anonymous$$ySrc$$anonymous$$ode", (int)UnityEngine.Rendering.Blend$$anonymous$$ode.SrcAlpha);
  material.SetInt ("$$anonymous$$yDst$$anonymous$$ode", (int)UnityEngine.Rendering.Blend$$anonymous$$ode.Zero);

avatar image raja-bala · Feb 12, 2015 at 04:50 PM 0
Share

Damn, i wish i saw this a few months back. I had been maintaining two shaders which differed only in blend mode.

avatar image Selmar · Jun 24, 2016 at 11:48 AM 0
Share

Any idea about the performance implications of using this on mobile? Assu$$anonymous$$g they don't change at runtime, just so we have less shaders to deal with.

avatar image
2

Answer by PicklesIIDX · Feb 16, 2018 at 05:55 PM

The standard shader has properties called _DstBlend and _SrcBlend which you can modify to get what you want. It's basically exactly like @Juho_Oraveinen answer, but it's built-in.

 material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
 material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
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

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

14 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

Related Questions

(c#) Transparency Problem - Toggle not Gradient 1 Answer

Is it possible to change blend mode in shader at runtime? 1 Answer

Why is color multiplied with 2 in "Particles/Alpha Blended" shader? 1 Answer

Changing custom shader. Add alpha cutout 1 Answer

Alpha Transparency Shader Issue 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