Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Multiply shader troubles

Discussion in 'Shaders' started by Nega_Pulluxx, May 2, 2013.

  1. Nega_Pulluxx

    Nega_Pulluxx

    Joined:
    Feb 26, 2013
    Posts:
    3
    Hey guys :)

    Ok so I really need you peoples help. I've been using my googling capabilities to the fullest but I haven't found a good solution to my problem yet (or at least one I can understand). For the game I'm working on we need a shader which can do something similiar to the Multiply function in Photoshop, with the option to change transparency on the 'detail' texture. We want to have a creature which can have it's normal texture, and when it gets sicker we want to raise the transparency on the detail texture to gradually make it appear sicker and sicker. We are using 2d Toolkit and will use this shader on animated sprites if that makes any difference. So what we need in our shader is a _MainTex for the regular texture, a _DetailTex for the texture we want to "Multiply" with the regular and some way to adjust transparency on the _DetailTex (however, this is not our main concern here, just getting Multiply to work would be great). Here's an example picture of what we want:

    http://imageshack.us/photo/my-images/834/multiplyexample.jpg/

    Here's what we got so far. I thought the lerp function would do the 'multiplying' for us by it's use of _DetailMap _DiffuseMap, however with this code it seems we are only taking the mask from the _MainTex and then putting _DetailTex in that mask.

    We are really in a jam about this and any help at all is greatly appreciated :)

    Code (csharp):
    1. Shader "Custom/DiffuseDetailCuttoff"
    2. {
    3. Properties {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    6.     _DetailTex ("Detail Texture", 2D) = "white" {}
    7.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    8.     _DetailTiling ("Detail Tiling", Float) = 1.0
    9.     _DetailFade ("Defail Fade", Range(0, 1)) = 1.0
    10. }
    11.  
    12. SubShader {
    13.     Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    14.     LOD 200
    15.    
    16. CGPROGRAM
    17. #pragma surface surf Lambert alphatest:_Cutoff
    18.  
    19. sampler2D _MainTex;
    20. sampler2D _DetailTex;
    21. float _DetailTiling;
    22. float _DetailFade;
    23. fixed4 _Color;
    24.  
    25. struct Input {
    26.     float2 uv_MainTex;
    27. };
    28.  
    29. void surf (Input IN, inout SurfaceOutput o) {
    30.     fixed4 DiffuseMap = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    31.     fixed4 DetailMap = tex2D(_DetailTex, IN.uv_MainTex * _DetailTiling);
    32.     o.Albedo = lerp(DiffuseMap.rgb, DetailMap.rgb, _DetailFade);
    33.     o.Alpha = DiffuseMap.a;
    34. }
    35. ENDCG
    36. }
    37.  
    38. Fallback "Transparent/Cutout/VertexLit"
    39. }
     

    Attached Files:

  2. Xystress

    Xystress

    Joined:
    Sep 19, 2012
    Posts:
    11
    Hi

    I would do something like :

    o.Albedo = DiffuseMap.rgb * (1 - _DetailFade) + DiffuseMap.rgb * DetailMap.rgb * _DetailFade;

    So if your _DetailFade is at 0 it display the diffusemap, and if it's greater than 0 it will lerp between pure diffusemap + the product of diffusemap and detailmap. Finally, it _DetailFade is to 1, it display only the product
     
  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Might be easier with
    Code (csharp):
    1. o.Albedo = DiffuseMap.rgb * lerp(DetailMap.rgb, fixed3(1,1,1), _DetailFade);
    Giving...
    _DetailFade at 0 = full detail map.
    _DetailFade at 1 = no detail map.

    Basically blends the detail map between itself and white, based on detail fade value. As multiplying a colour with white means that you don't change it (as you're simply multiplying by 1).

    If you want the opposite effect (no detail at 0, full detail at 1), swap the position of DetailMap.rgb and fixed3(1,1,1) in the code I posted.
     
    Last edited: May 2, 2013
  4. Nega_Pulluxx

    Nega_Pulluxx

    Joined:
    Feb 26, 2013
    Posts:
    3
    You guys are the most awesome people in the world :D Thanks! We have our beta in less than a week and I've been stuck with shader problems this entire week.

    I do have some more problems with it though, since we want to use the shader with sprites (taken from the 2D Toolkit) there's no meshes on them and the shader can't function with them. I tried taking the sprites emtpy mesh and running RecalculateNormals() but that gave trouble to the animations. Is there any way to convert the shader to only handle the pixels without taking into account the geometrical shapes? Maybe changing the _DiffuseMap _DetailMap so that it doesn't take in UV maps (would that be enough)?
     
  5. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I'm not sure I understand what you mean...

    Sprites are geometric shapes - they're just flat quads, generally.
     
  6. Nega_Pulluxx

    Nega_Pulluxx

    Joined:
    Feb 26, 2013
    Posts:
    3
    I'm sorry, I'm pretty new at shaders and such, but if I understand correctly, most of Unity's shaders are meant to work with 3D objects right? Whereas what I want is just multiplication between two textures and have no need for any geometrical calculations which may have to do with lightning and such. I just thought maybe you could trim that away from the shader somehow and maybe have it working better with 'easier' objects like sprites. But thats just me thinking out loud. Right now when I use the shader with my sprites they're only black which I thought could have something to do with the texture not being stretched right on the 'geometry'.