Search Unity

How to mimic multiple material blending in a shader?

Discussion in 'Shaders' started by mayekol, May 8, 2008.

  1. mayekol

    mayekol

    Joined:
    Oct 23, 2007
    Posts:
    115
    I was wondering how how if a renderer has multiple materials on the same object these materials blended together and how this can be done in a shader?

    I would like to get the effect of blending four (or more) of the same material in a single shader. I am working from the "Vegetation" example found in the Unity manual and found that I got a result I liked if I used four or more copies of the same material on a renderer.

    I have tried adding multiple passes trying to duplicate the second pass with different blend effects, I have tried turning off ZTest on and using previous texture values on the third or fourth passes with different blending but no luck so far :)

    Shader "Vegetation" {
    Properties {
    _Color ("Main Color", Color) = (.5, .5, .5, .5)
    _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
    _Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
    }
    SubShader {
    // Set up basic lighting
    Material {
    Diffuse [_Color]
    Ambient [_Color]
    }
    Lighting On

    // Render both front and back facing polygons.
    Cull Off

    // first pass:
    // render any pixels that are more than [_Cutoff] opaque
    Pass {
    AlphaTest Greater [_Cutoff]
    SetTexture [_MainTex] {
    combine texture * primary, texture
    }
    }

    // Second pass:
    // render in the semitransparent details.
    Pass {
    // Dont write to the depth buffer
    ZWrite off
    // Don't write pixels we have already written.
    ZTest Less
    // Only render pixels less or equal to the value
    AlphaTest LEqual [_Cutoff]

    // Set up alpha blending
    Blend SrcAlpha OneMinusSrcAlpha

    SetTexture [_MainTex] {
    combine texture * primary, texture
    }
    }

    // below is where I try to make another pass
    //trying to duplicate the previous pass
    Pass {
    // Dont write to the depth buffer
    ZWrite off
    // Do write alpha pixels again.

    // Only render pixels less or equal to the value
    AlphaTest LEqual [_Cutoff]

    // It seems like it has to be alpha blending....
    Blend SrcAlpha OneMinusSrcAlpha

    // try to use the previous texture
    SetTexture [_MainTex] {
    combine previous * primary, previous
    }
    }
    }
    }
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Try other blend modes, like "Blend One One". Ztest won't have any effect in what you're doing in this case. You don't want to do "combine previous" by itself in a separate pass, since there is no previous; that only applies when there's more than one texture you're combining in the same pass. Take a look on the wiki and examine some of the shaders there, like some of the multi-layer terrain shaders, to get an idea how to combine stuff.

    --Eric
     
  3. mayekol

    mayekol

    Joined:
    Oct 23, 2007
    Posts:
    115
    Thanks Eric,

    After making the changes you suggested I found that in the third pass I found that I could get the result I was looking for by changing the pass SetTexture to "SetTexture [_MainTex] { Combine texture * primary, texture * primary }"

    And also by adding the tag "Tags {Queue=Transparent}" to the sub shader

    Cheers