Unity3D Sprite … but single sided?

2019-05-15 11:10发布

Unity's excellent new Sprites (to wit, Unity's excellent new sprites), among other worthy advantages, are in fact double-sided. In a 2D or 3D use case, you can flip the little bastards around and still see them from behind - they are rendered from both sides.

I also love the unlit shader used on them (ie, Sprite-Default, not Sprite-Diffuse).

However I have need for an old-fashioned single-sided Sprite.

Fortunately, you can freely download the source of the excellent shader used by Unity ... confusingly, you can't just open it in the Editor, but see here and thence here.

After considerable sustained effort involving inexpensive whisky, I made two (2) modifications to the shader.

1) I changed the name in the first line of the file to "DefaultSingle" rather than "Default"

2) I commented away the line Cull Off

(I then made a new Material, called it "Sprite Single Sided", set the shader to this new one, and on Sprites I replace the material slot with that new material.)

in fact, have I screwed-up anything in the shader by making this modification? Can one gaily comment out "Cull off" without causing further problems? Is there some gotchya in changing that usual material used by Sprite (you can't "see" it so I don't know). More broadly, is there a more correct way to achieve single-sided Sprite?

// file "Sprites-DefaultSingle.shader"
Shader "Sprites/DefaultSingle"
{
  Properties
  {
    [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    _Color ("Tint", Color) = (1,1,1,1)
    [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
  }

  SubShader
  {
    Tags
    { 
      "Queue"="Transparent" 
      "IgnoreProjector"="True" 
      "RenderType"="Transparent" 
      "PreviewType"="Plane"
      "CanUseSpriteAtlas"="True"
    }

  ///  Cull Off
    Lighting Off
    ZWrite Off
    Blend One OneMinusSrcAlpha

    Pass
    {
    CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma multi_compile _ PIXELSNAP_ON
      #pragma shader_feature ETC1_EXTERNAL_ALPHA
      #include "UnityCG.cginc"

      struct appdata_t
      {
        float4 vertex   : POSITION;
        float4 color    : COLOR;
        float2 texcoord : TEXCOORD0;
      };

      struct v2f
      {
        float4 vertex   : SV_POSITION;
        fixed4 color    : COLOR;
        float2 texcoord  : TEXCOORD0;
      };

      fixed4 _Color;

      v2f vert(appdata_t IN)
      {
        v2f OUT;
        OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
        OUT.texcoord = IN.texcoord;
        OUT.color = IN.color * _Color;
        #ifdef PIXELSNAP_ON
        OUT.vertex = UnityPixelSnap (OUT.vertex);
        #endif

        return OUT;
      }

      sampler2D _MainTex;
      sampler2D _AlphaTex;

      fixed4 SampleSpriteTexture (float2 uv)
      {
        fixed4 color = tex2D (_MainTex, uv);

#if ETC1_EXTERNAL_ALPHA
        // get the color from an external texture ..
        color.a = tex2D (_AlphaTex, uv).r;
#endif //ETC1_EXTERNAL_ALPHA

        return color;
      }

      fixed4 frag(v2f IN) : SV_Target
      {
        fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
        c.rgb *= c.a;
        return c;
      }
    ENDCG
    }
  }
}

2条回答
劫难
2楼-- · 2019-05-15 11:43

That won't cause any problems and is the correct way of doing things. If you want to be really explicit about it you could change the line to Cull Back instead of commenting it out, but back-face culling is defined as the default behaviour so just removing it is fine.

查看更多
相关推荐>>
3楼-- · 2019-05-15 11:46

As far as I'm aware, neither of these changes have any effects other than the that which you intended. Also, this is the most correct way to achieve this- it's the only thing Cull is for.

查看更多
登录 后发表回答