2
\$\begingroup\$

I want my shader to work in both Forward and VertexLit rendering modes. I'd written a texture scrolling shader, but I also want to consider lighting which is produced by Vertex lit shader. I can't add my effect directly in the vertex lit shader, so I'd created 2 passes: the lighting one and the effect one. Here's my code now:

SubShader 
{
    Tags 
    {
        "RenderType" = "Opaque"
        "LightingMode" = "Vertex"
    }
    Pass 
    {
        Name "Hardware lighting pass"
        Tags { "LightingMode" = "Vertex" }

        Zwrite On
        Cull Back

        Material 
        {
            Diffuse [_Color]
        }

        Lighting On
    }

    // At the second pass we'we turned the multiplicative blending on to combine our texture
    // effect with the ightin that has been couputed at the previous pass.
    Pass 
    {
        Name "Effect-applying pass"
        Tags { "LightingMode" = "Vertex" }

        // If you're change this, you must then change the light calculation algorithm
        Blend One DstColor
        Lighting Off
        Cull Back

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        // texture samplers
        uniform sampler2D _MainTex;
        uniform sampler2D _AlphaMask;
        uniform sampler2D _ManaTexture;
        uniform sampler2D _Noise;

        // float values
        uniform float _ManaFloatSpeed;
        uniform float _ShinessSpeed;

        struct VertexInput 
        {
            float4 pos : POSITION0;
            float4 col : COLOR0;
            float4 uv : TEXCOORD0;
        };

        struct FragmentInput 
        {
            float4 pos : POSITION0;
            float4 col : COLOR0;
            half2 uv : TEXCOORD0;
        };

        // In the vertex shader we're just applied MVP-transform to our object
        FragmentInput vert (VertexInput i) 
        {
            FragmentInput o;
            o.pos = mul(UNITY_MATRIX_MVP, i.pos);
            o.uv = i.uv.xy;
            o.col = i.col;
            return o;
        }

        // 1) Sample our fancy texture to get the pixel color
        // 2) Get the color value of scrolled pixel of the noise texture
        // 3) Set the alpha channel of an output color value to prevent glow at the textured areas
        half4 frag(FragmentInput i) : COLOR0
        {
            float4 col = i.col * tex2D(_MainTex, i.uv);

            // Now reading from the separate mask, later it will be col.a by default (this instruction will desappear)
            col.a = tex2D(_AlphaMask, i.uv).r;

            // Epsilon to prevent dx9-11, and GLES tolerance pass (not 0.0f)
            if(col.a > .0001f)
            {
                // Sample two textures and get the value from the alpla layer
                float4 tl1 = tex2D(_ManaTexture, float2(i.uv.x, i.uv.y + (_Time.y * _ManaFloatSpeed)));
                float4 tl2 = tex2D(_ManaTexture, float2(i.uv.x, i.uv.y + (_Time.y * (_ManaFloatSpeed * 2))));
                float alphaValue = tex2D(_Noise, float2((i.uv.x + _Time.y * _ShinessSpeed), (i.uv.y + _Time.x))).r;

                return half4((tl1 * tl2).rgb, alphaValue);
            }
            else
            {
                return col;
            }
        }
        ENDCG
    }
}

The problem is... Yep, 2 passes, which is extremely undesirable. How can I calculate vertex-lit lighting and apply my effect in the single pass?

\$\endgroup\$

0

You must log in to answer this question.

Browse other questions tagged .