Shader per vedere la silhouette attraverso gli sprite alfa miscelati


12

Voglio ottenere in Unity un effetto trasparente come quello di questi esempi:

Nel mio scenario specifico ci sono un paio di requisiti:

  • Gli sprite utilizzano la fusione alfa e gli sprite hanno aree trasparenti.
  • Ci sono 2 tipi di elementi che occludono il personaggio. Uno dovrebbe creare l'effetto silhouette e l'altro dovrebbe comportarsi come al solito.

Per nascondere elementi che creano la silhouette, abilito ZWrite e lo disabilito per elementi che non lo fanno.

Per il personaggio ho provato a impostare la coda dello shader su trasparente + 1 e ho aggiunto questo passaggio:

Pass
{
    ZTest Greater
    Lighting Off
    Color [_Color]
}

E l'effetto funziona parzialmente:

  • La silhouette è disegnata su tutto il personaggio, anche le parti che sono trasparenti. Le parti trasparenti non dovrebbero creare una silhouette.

  • La silhouette viene creata quando il personaggio si trova dietro uno sprite, anche se quella parte dello sprite è trasparente. Essere dietro una parte trasparente dello sprite non dovrebbe creare la silhouette.

  • Il personaggio appare davanti al resto degli elementi, anche se è dietro di loro. Immagino che ciò sia dovuto all'impostazione della coda su Trasparente + 1. Ma se lo lascio trasparente, il personaggio viene disegnato nell'ordine corretto, ma la silhouette non viene mai vista.

Ho provato a seguire questi suggerimenti che qualcuno mi ha dato, ma non riesco a farlo funzionare:

1) Lascia il passaggio che rende gli sprite così come sono.

2) Aggiungi un passaggio che scrive nel buffer z, ma ha uno shader che utilizza clip () per scartare i pixel in base all'alfa. Non è possibile utilizzare il buffer z per eseguire test z soft senza utilizzare MSAA e la copertura alpha-to. La qualità non sarà eccezionale, ma è il massimo che puoi fare. Un'alternativa più veloce è un dithering di pattern o noise o una buona soglia vecchio stile se i tuoi sprite hanno bordi abbastanza nitidi.

3) Aggiungi il terzo passaggio agli oggetti occludibili che disegnano il colore dell'occlusione usando il test z e assicurati che sia disegnato come passaggio finale.

Sono un po 'nuovo per gli shader, specialmente in Unity, e non riesco proprio a capire come farlo funzionare correttamente.


Il tuo secondo esempio sembra semplicemente uno sprite verde traslucido posizionato sopra il personaggio. Potresti voler sbarazzartene e lasciare il secondo, se è quello che stai cercando.
Steve Harding,

Risposte:


1

Questo video tratta le basi? È un'illustrazione della creazione di alcuni stili e contorni diversi dagli shader che la gente ha già pubblicato.

https://www.youtube.com/watch?v=00qMZlacZQo

È un esempio dell'uso di uno shader pubblicato su Unity Wiki per fare praticamente quello che stai cercando. Il contenuto dello shader è inferiore, anche se penso che la parte del contorno dello shader potrebbe non funzionare come previsto in U5.

Shader "Outlined/Silhouetted Diffuse" {
Properties {
    _Color ("Main Color", Color) = (.5,.5,.5,1)
    _OutlineColor ("Outline Color", Color) = (0,0,0,1)
    _Outline ("Outline width", Range (0.0, 0.03)) = .005
    _MainTex ("Base (RGB)", 2D) = "white" { }
}

CGINCLUDE
#include "UnityCG.cginc"

struct appdata {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
};

struct v2f {
    float4 pos : POSITION;
    float4 color : COLOR;
};

uniform float _Outline;
uniform float4 _OutlineColor;

v2f vert(appdata v) {
// just make a copy of incoming vertex data but scaled according to normal direction
    v2f o;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

    float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
    float2 offset = TransformViewToProjection(norm.xy);

    o.pos.xy += offset * o.pos.z * _Outline;
    o.color = _OutlineColor;
    return o;
}
ENDCG

SubShader {
    Tags { "Queue" = "Transparent" }

    // note that a vertex shader is specified here but its using the one above
    Pass {
        Name "OUTLINE"
        Tags { "LightMode" = "Always" }
        Cull Off
        ZWrite Off
        ZTest Always
        ColorMask RGB // alpha not used

        // you can choose what kind of blending mode you want for the outline
        Blend SrcAlpha OneMinusSrcAlpha // Normal
        //Blend One One // Additive
        //Blend One OneMinusDstColor // Soft Additive
        //Blend DstColor Zero // Multiplicative
        //Blend DstColor SrcColor // 2x Multiplicative

CGPROGRAM
#pragma vertex vert
#pragma fragment frag

half4 frag(v2f i) :COLOR {
    return i.color;
}
ENDCG
    }

    Pass {
        Name "BASE"
        ZWrite On
        ZTest LEqual
        Blend SrcAlpha OneMinusSrcAlpha
        Material {
            Diffuse [_Color]
            Ambient [_Color]
        }
        Lighting On
        SetTexture [_MainTex] {
            ConstantColor [_Color]
            Combine texture * constant
        }
        SetTexture [_MainTex] {
            Combine previous * primary DOUBLE
        }
    }
}

SubShader {
    Tags { "Queue" = "Transparent" }

    Pass {
        Name "OUTLINE"
        Tags { "LightMode" = "Always" }
        Cull Front
        ZWrite Off
        ZTest Always
        ColorMask RGB

        // you can choose what kind of blending mode you want for the outline
        Blend SrcAlpha OneMinusSrcAlpha // Normal
        //Blend One One // Additive
        //Blend One OneMinusDstColor // Soft Additive
        //Blend DstColor Zero // Multiplicative
        //Blend DstColor SrcColor // 2x Multiplicative

        CGPROGRAM
        #pragma vertex vert
        #pragma exclude_renderers gles xbox360 ps3
        ENDCG
        SetTexture [_MainTex] { combine primary }
    }

    Pass {
        Name "BASE"
        ZWrite On
        ZTest LEqual
        Blend SrcAlpha OneMinusSrcAlpha
        Material {
            Diffuse [_Color]
            Ambient [_Color]
        }
        Lighting On
        SetTexture [_MainTex] {
            ConstantColor [_Color]
            Combine texture * constant
        }
        SetTexture [_MainTex] {
            Combine previous * primary DOUBLE
        }
    }
}

Fallback "Diffuse"
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.