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?

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

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

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);