Search Unity

Blend Multiply with Slider

Discussion in 'Shaders' started by macdude2, Jun 23, 2014.

  1. macdude2

    macdude2

    Joined:
    Sep 22, 2010
    Posts:
    686
    Hello, I'm trying to make a particle multiply shader that can simply blend between two textures. I have looked into unity's docs on shaders, but I was unable to find much regarding how I might incorporate a slider into controlling the opacity of a texture in a multiply shader. Does anyone know how I might go around creating such a shader? I really don't have much experience in shaders and would be appreciative of any help I can get. I have included the code of the shader I would like to modify below. Thanks for any help!

    Edit: I am sorry, I did not make myself clear enough. The trouble I'm running into comes from the fact that to my knowledge particle shaders (which I think are vertex shaders) – like multiply – cannot be coded as surface shaders.

    Using a surface shader, its very possible to make a shader such that a slider can control the opacity of two textures. The idea is that a slider when at its min shows one texture, at its max shows a second texture and in-between shows both textures simultaneously at varying opacities.

    I'm trying to mimic this effect in a vertex multiply shader such that I can use the shader to ultimately which can blend between two different texture maps in realtime. How can I create such a shader? Any pointers would be wonderful!

    Code (CSharp):
    1. // Simplified Multiply Particle shader
    2.  
    3. Shader "Custom/MultiplyBlendTextures" {
    4.     Properties {
    5.         _Blending ("Blend Amount", Range(0,1)) = 0.5
    6.         _MainTex ("Particle Texture", 2D) = "white" {}
    7.         _BlendTex ("Blend Texture", 2D) = "white" {}
    8.     }
    9.  
    10.     Category {
    11.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    12.         Blend Zero SrcColor
    13.         Cull Off Lighting Off ZWrite Off Fog { Color (1,1,1,1) }
    14.  
    15.         BindChannels {
    16.             Bind "Color", color
    17.             Bind "Vertex", vertex
    18.             Bind "TexCoord", texcoord
    19.         }
    20.  
    21.         SubShader {
    22.             Pass {
    23.                 SetTexture [_MainTex] {
    24.                     combine texture * primary
    25.                 }
    26.                 SetTexture [_MainTex] {
    27.                     constantColor (1,1,1,1)
    28.                     combine previous lerp (previous) constant
    29.                 }
    30.             }
    31.         }
    32.     }
    33. }
     
    Last edited: Jun 23, 2014
  2. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    And how are you going to control the blend between the two images using particles?
     
  3. macdude2

    macdude2

    Joined:
    Sep 22, 2010
    Posts:
    686
    See the edit, I hope I have clarified my intentions!
     
  4. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    See if this works for you, i simply copied the internal multiply particle shader and added a second texture that lerps from the alpha of the color (color of lifetime) the problem with this is that now you lose the ability to change the alpha of the particle (because it now controls the lerp), so my question still stands, how do you want to blend between the two?

    Code (csharp):
    1. Shader "Particles/Multiply Texture Blend" {
    2. Properties {
    3.     _MainTex ("Particle Texture", 2D) = "white" {}
    4.     _FinalTex ("Final Texture", 2D) = "white" {}
    5.     _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
    6. }
    7.  
    8. Category {
    9.     Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    10.     Blend Zero SrcColor
    11.     Cull Off Lighting Off ZWrite Off Fog { Color (1,1,1,1) }
    12.    
    13.     SubShader {
    14.         Pass {
    15.        
    16.             CGPROGRAM
    17.             #pragma vertex vert
    18.             #pragma fragment frag
    19.             #pragma multi_compile_particles
    20.  
    21.             #include "UnityCG.cginc"
    22.  
    23.             sampler2D _MainTex;
    24.             sampler2D _FinalTex;
    25.             fixed4 _TintColor;
    26.            
    27.             struct appdata_t {
    28.                 float4 vertex : POSITION;
    29.                 fixed4 color : COLOR;
    30.                 float2 texcoord : TEXCOORD0;
    31.             };
    32.  
    33.             struct v2f {
    34.                 float4 vertex : SV_POSITION;
    35.                 fixed4 color : COLOR;
    36.                 float2 texcoord : TEXCOORD0;
    37.                 #ifdef SOFTPARTICLES_ON
    38.                 float4 projPos : TEXCOORD1;
    39.                 #endif
    40.             };
    41.            
    42.             float4 _MainTex_ST;
    43.             float4 _FinalTex_ST;
    44.  
    45.             v2f vert (appdata_t v)
    46.             {
    47.                 v2f o;
    48.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    49.                 #ifdef SOFTPARTICLES_ON
    50.                 o.projPos = ComputeScreenPos (o.vertex);
    51.                 COMPUTE_EYEDEPTH(o.projPos.z);
    52.                 #endif
    53.                 o.color = v.color;
    54.                 o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
    55.                 return o;
    56.             }
    57.  
    58.             sampler2D_float _CameraDepthTexture;
    59.             float _InvFade;
    60.            
    61.             fixed4 frag (v2f i) : SV_Target
    62.             {
    63.                 #ifdef SOFTPARTICLES_ON
    64.                 float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
    65.                 float partZ = i.projPos.z;
    66.                 float fade = saturate (_InvFade * (sceneZ-partZ));
    67.                 i.color.a *= fade;
    68.                 #endif
    69.                
    70.                 half4 prev = half4(i.color.rgb,1) * lerp(tex2D(_MainTex, i.texcoord), tex2D(_FinalTex, i.texcoord), i.color.a);
    71.                 return lerp(half4(1,1,1,1), prev, prev.a);
    72.             }
    73.             ENDCG
    74.         }
    75.     }
    76. }
    77. }
     
    Last edited: Jun 24, 2014
  5. macdude2

    macdude2

    Joined:
    Sep 22, 2010
    Posts:
    686
    Thanks so much for taking the time to write that. However, it's still not working quite the way I want. It looks like the lerp function is taking in the alpha of the main texture, would there be any way for it to instead take in the value on the slider? I suppose I'm not fully understanding your question. I'm looking for a shader to do a linear blend between the two textures so that you could slide the sider from 0 to 1 and see the material's view texture change from the first texture to the second. What ways are there to blend between two textures? Thanks so much for your help.

    Edit: Awesome! Literally just did what I said – changed the input on the lerp function to take in the slider's value instead of the texture alpha and was able to achieve what I was aiming for! Thanks so much!
     
  6. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    If its working for you i'm cool but what i gave you was already lerping using the slider alpha value of color over lifetime, it wasn't lerping using the texture alpha at all

    i.color.a is the vertex color and the lerp is doing a lerp between _MainTex and _FinalTex using i.color.a to do so, i then multiply it by the vertex color without alpha to tint the textures normally
    Code (csharp):
    1. half4 prev = half4(i.color.rgb,1) * lerp(tex2D(_MainTex, i.texcoord), tex2D(_FinalTex, i.texcoord), i.color.a);