Тени Unity игнорируют прозрачность шейдера, но только в билде - PullRequest
0 голосов
/ 11 октября 2018

Я сделал пользовательский шейдер, который добавляет проход к поверхностному шейдеру для получения контура вокруг объекта.Объект представляет собой четырехугольник со спрайтами персонажей для достижения двумерного персонажа в трехмерной игре.Объект должен отбрасывать тень в той же форме, что и его спрайт.

В режиме воспроизведения редактора тени работают идеально: 2D character casting a shadow that matches its 2d shape

Однако, когда я строюВ игре под Windows или на платформе Android тени полностью игнорируют прозрачность объекта и показывают только тень четырехугольника.2D character casting a rectangular shadow

Я не уверен, вызвана ли проблема моим шейдером или чем-то в настройках.Я сбросил настройки качества до значений по умолчанию и все еще имею проблему, даже если она настроена на ультра качество.Единственный источник света в сцене - это направленный источник света с включенными мягкими тенями.

Это код в моем шейдере.

Shader "Custom/MultiPassOutlineShader" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _OutlineColor ("Outline Color",Color) = (1,1,1,1)
        _OutlineThickness ("Outline Thickness",float) = 0.05
    }
    SubShader {

        Tags {"RenderType"="Transparent" "Queue"="Transparent" "IgnoreProjector"="True"}
        LOD 100

        Pass
        {
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag alpha
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;

            float4 _MainTex_ST;
            float _OutlineThickness;
            fixed4 _OutlineColor;

            v2f vert (appdata v)
            {
                v2f o;
                v.vertex = normalize(v.vertex) * _OutlineThickness + v.vertex;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {

                UNITY_APPLY_FOG(i.fogCoord, col);
                fixed4 c = tex2D (_MainTex, i.uv);
                fixed4 col = _OutlineColor;
                col.a *= c.a;
                clip(c.a-0.1);
                return col;
            }
            ENDCG
        }

        ZWrite On
        Blend Off
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows alpha
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
         #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_CBUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_CBUFFER_END

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            clip(c.a - 0.9);
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Standard"
}

1 Ответ

0 голосов
/ 13 октября 2018

Я исправил проблему, добавив проход для отбрасывания теней.(по какой-то причине у Unity нет документации по ним.) Я также изменил запасной вариант на «VertexLit», но я не знаю, имел ли это какой-либо эффект.Я до сих пор не знаю, почему формы тени в редакторе отличались от формы в сборке.

    //From https://answers.unity.com/questions/1003169/shadow-caster-shader.html
    Pass{ 
        Name "ShadowCaster"
        Tags { "LightMode" = "ShadowCaster" }

        Fog {Mode Off}
        ZWrite On ZTest Less Cull Off
        Offset 1, 1

        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag
        #pragma fragmentoption ARB_precision_hint_fastest
        #pragma multi_compile_shadowcaster
        #include "UnityCG.cginc"

        sampler2D _MainTex;

        struct v2f
        {
            V2F_SHADOW_CASTER; 
            float2 uv : TEXCOORD1;
        };


        v2f vert(appdata_full v )
        {
            v2f o;
            o.uv = v.texcoord;
            TRANSFER_SHADOW_CASTER(o)

        return o;
        }

        float4 frag( v2f i ) : COLOR
        {
            fixed4 c = tex2D (_MainTex, i.uv);
            clip(c.a - 0.9);
            SHADOW_CASTER_FRAGMENT(i)
        }
        ENDCG
    } 
...