The question is answered, right answer was accepted
Additive Blending Shader for Mobile - parse error
Hello!
I'm working on custom surface shader, which blending two textures into one additive image with transparency (alpha channel).
I have very low knowledge about shaders and I mostly improvise.
Generally I've done it by mixing some parts of Unity built-in shaders. And here comes the problem:
When I'm using only CGPROGAM instructions without Pass, shader works in editor and it effects are visible in Game viewport, even in runtime. BUT, if I hit Play button on other scene, then switch it (in-game) to that with shader - shader aren't working anymore. Object is invisible.
When I'm using CGPROGRAM instructions with Pass and SetTexture functions (CG instructions are outside Pass brackets) then it works. Unfortunately, in that case I lost blending, so this isn't what I want.
When I'm put CGPROGRAM instructions into Pass brackets I receive error:
Parse error: syntax error, unexpected TOK_PASS, expecting TOK_SETTEXTURE or '}' at line 38
I don't know what I'm doing wrong.
Below is my code.
Unity version: 2017.1.0f3
Target platform: Android
Shader "Custom/AdditiveTransparentBlending"
{
Properties
{
_MainTex("Texture 1", 2D) = "white" {}
_Texture2("Texture 2", 2D) = "white" {}
_Blend("Blend", Range(0, 1)) = 0.5
}
SubShader
{
Pass
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
Blend SrcAlpha One
Cull Off
Lighting Off
ZWrite Off
Fog{ Color(0,0,0,0) }
BindChannels
{
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
CGPROGRAM
#pragma target 2.0
#include "UnityCG.cginc"
//#pragma exclude_renderers flash
#pragma surface surf Lambert vertex:vert noforwardadd keepalpha
struct Input
{
float2 uv_MainTex;
float2 uv_Texture2;
float4 color : Color;
};
float _Blend;
sampler2D _MainTex;
sampler2D _Texture2;
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input,o);
o.color = v.color;
}
void surf(Input IN, inout SurfaceOutput o)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
fixed4 c2 = tex2D(_Texture2, IN.uv_Texture2);
o.Albedo = (c.rgb * IN.color.rgb) * _Blend + (c2.rgb * IN.color.rgb) * (1 - _Blend);
o.Alpha = (c.a * IN.color.a) * _Blend + (c2.a * IN.color.a) * (1 - _Blend);
o.Albedo *= 2;
}
ENDCG
/*
Pass
{
SetTexture[_MainTex]
SetTexture[_Texture2]
{
//combine texture * primary
ConstantColor(0,0,0,[_Blend])
Combine texture Lerp(constant) previous
}
}*/
}
}
//Fallback "Diffuse"
}
Answer by Gregor2211 · Oct 12, 2017 at 10:12 AM
Okay, I figured it out by changing approach. I've looked better into Unity documentation and code of built-in shaders, to reveal that I don't even need that whole CG part of code, because Legacy Texture Combiners are doing all the work. Earlier I didn't know that combiners can compute color and alpha separately (see documentation >> link).
Below is current code (now is short and clear).
Shader "Custom/AdditiveBlending"
{
Properties
{
_MainTex("Texture 1", 2D) = "white" {}
_Texture2("Texture 2", 2D) = "white" {}
_Blend("Blend", Range(0, 1)) = 0.5
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
Blend SrcAlpha One
Cull Off
Lighting Off
ZWrite Off
Fog{ Color(0,0,0,0) }
BindChannels
{
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass
{
SetTexture[_MainTex]
SetTexture[_Texture2]
{
ConstantColor(0,0,0,[_Blend])
combine texture Lerp(constant) previous, texture Lerp(constant) previous
}
}
}
}