Unity阴影忽略了着色器的透明度,但仅在构建时

时间:2018-10-11 02:38:22

标签: unity3d shader shadow

我已经制作了一个自定义着色器,该着色器向表面着色器添加了传递以实现对象周围的轮廓。该对象是一个带有角色精灵的四边形,可以在3D游戏中获得2D角色。该对象应该以与精灵相同的形状投射阴影。

在编辑器的播放模式下,阴影可以完美工作: 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 :(得分:0)

我通过添加阴影投射过程解决了该问题。 (由于某些原因,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
    }