Having trouble blending 2 textures together. I following along with Daniel_Brauer and AntonPetrov's explanations here but I've not been able to figure out how to set ShaderLab commands DestBlend and SrcBlend. It does sorta blend, but some colours aren't quite right. Here's what I'm getting: And here's what I'm hoping for: Would someone please tell me where I'm going wrong? (uv_bottomLayer) + (uv_topLayer) = (fragment) Code (CSharp): fixed4 FragmentFunc(v2f IN) : SV_Target { fixed4 texture2 = SampleSpriteTexture(IN.uv_topLayer) * IN.color; fixed4 texture1 = SampleSpriteTexture(IN.uv_bottomLayer) * IN.color; if (texture2.a > 0) { fixed4 fragment; fragment.rgb = (texture1.rgb * (1 - texture2.a) + texture2.rgb); fragment.a = (1 - (1 - texture1.a) * (1 - texture2.a)); return fragment; } return texture1; } ENDCG Cull Off Lighting Off ZWrite Off BlendOp Add Blend One OneMinusSrcAlpha
When you're blending two textures together within a shader, the DestBlend and SrcBlend aren't important. That's just for how the final output color of the shader gets blended with the target. If you want to replicate traditional alpha blending, that'd just be a basic lerp. return lerp(texture1, texture2, texture2.a); However the above will cause issues with the alpha. I'd probably do something like this instead: return float4(lerp(texture1.rgb, texture2.rgb, texture2.a), texture1.a); or return float4(lerp(texture1.rgb, texture2.rgb, texture2.a), max(texture1.a, texture2.a)); However, to be honest, I'm not entirely sure what kind of blend you're looking to do since the png images you posted above don't have any alpha, and I'm not sure how you produced the "wanted" image. Presumably that was done in photoshop with some specific blend mode? Which one?
as I see, you got what you wanted.. you have yellow background and overlay blue over it blending code Code (CSharp): if (texture2.a > 0) { fixed4 fragment; fragment.rgb = (texture1.rgb * (1 - texture2.a) + texture2.rgb); fragment.a = (1 - (1 - texture1.a) * (1 - texture2.a)); return fragment; } makes alpha cutout (which also can be deleted, blending in "then" already exist), then makes Normal blending also you use "+ texture2.rgb" which assumes your texture2.rgb is already in premultiplied-alpha mode (otherwise you need to change formula to "+ texture2.rgb * texture2.a") citated from https://forum.unity.com/threads/wha...-two-transparent-textures-in-a-shader.169313/ Code (CSharp): as a common alpha-blending equation with alpha premultiplied in fragment.rgb: output = background.rgb * (1 - fragment.a) + fragment.rgb; this another blending is related to destination-final-step to allow chain-blend of (tex3 over (tex2 over tex1)) etc, where your original shader contains only tex1, tex2 Code (CSharp): BlendOp Add Blend One OneMinusSrcAlpha ---------- original case from https://forum.unity.com/threads/wha...-two-transparent-textures-in-a-shader.169313/ was "I need to blend three transparent textures in one shader to be drawn in one call," it is important - by one call.. due to this, the solution is in-code-blend formula like fragment.a = (1 - (1 - texture1.a) * (1 - texture2.a)); or tex3, tex2, tex1 formula from it if you don't have case "in one call" (imho you don't need) then you can achieve desired effect only by simple blend delete in-code blending Code (CSharp): fragment.rgb = (texture1.rgb * (1 - texture2.a) etc and simple blend shader is Code (CSharp): Shader "Custom/MyPremultipliedAlpha" { Properties { _MainTex ("Main Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Transparent" "Queue" = "Transparent" } Lighting Off ZWrite Off Cull Off Blend One OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex ComputeVertex #pragma fragment ComputeFragment sampler2D _MainTex; struct VertexInput { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct VertexOutput { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; }; VertexOutput ComputeVertex (VertexInput vertexInput) { VertexOutput vertexOutput; vertexOutput.vertex = UnityObjectToClipPos(vertexInput.vertex); vertexOutput.texcoord = vertexInput.texcoord; return vertexOutput; } fixed4 ComputeFragment (VertexOutput vertexOutput) : SV_Target { return tex2D(_MainTex, vertexOutput.texcoord); } ENDCG } } } (with premult in original texture, which is important to order-independent-blend-to-background, otherwise you should change blend in it to Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha) which can be chained unlimited-times like Code (CSharp): dest = create RT.. Graphics.Blit(tex1, dest, myMat) Graphics.Blit(tex2, dest, myMat) Graphics.Blit(tex3, dest, myMat) it produces formula (tex3 over (tex2 over tex1))