Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Sprite Flipping Without using LocalScale

Discussion in 'Assets and Asset Store' started by image28, Nov 4, 2014.

  1. image28

    image28

    Joined:
    Jul 17, 2013
    Posts:
    457
    Didn't like flipping sprites by inverting the localscale, so decided to write a texture flipping editor extension.

    However that didn't work with animations/spritesheets, next I decided to try and flip the sprite on a shader level.

    Which works although currently you have to set the spritesheet width, the individual sprites width for the shader to work ( didn't know how to access those values from within the shader ).

    Anyway The code for the editor extension and shader are bellow, all this to avoid localscale messing with the rotations.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4. using UnityEditor;
    5.  
    6. public class flipImage : ScriptableWizard {
    7.     public Texture2D[] inputTexture = new Texture2D[1];
    8.     public string filenameInsert="-flipped";
    9.     private Texture2D outputTexture;
    10.     private Color[] textureData;
    11.     private Color[] outputData;
    12.  
    13.     // Use this for initialization
    14.     [MenuItem("Window/Flip Texture")]
    15.     public static void ShowWindow()
    16.     {
    17.         ScriptableWizard.DisplayWizard("Flip Texture(s)", typeof(flipImage), "Flip Texture(s)");
    18.     }
    19.  
    20.     void OnWizardCreate()
    21.     {
    22.  
    23.         for(int d=0; d<inputTexture.Length;d++)
    24.         {
    25.             // Get Texture data
    26.             textureData = inputTexture[d].GetPixels();
    27.             outputData = new Color[textureData.Length];
    28.  
    29.             // Flip the Texture
    30.             for(int y=0; y< inputTexture[d].height; y++)
    31.             {
    32.                 for(int x=inputTexture[d].width-1; x > 1; x--)
    33.                 {
    34.                     outputData[((y*inputTexture[d].width)+(inputTexture[d].width-x))]=textureData[((y*inputTexture[d].width)+x)];
    35.                 }
    36.             }
    37.  
    38.             // Write to a new Texture
    39.             outputTexture =  new Texture2D(inputTexture[d].width, inputTexture[d].height, inputTexture[d].format,false);
    40.             outputTexture.SetPixels(outputData);
    41.             outputTexture.Apply();
    42.             byte[] bytes = outputTexture.EncodeToPNG();
    43.             string infile=AssetDatabase.GetAssetPath(inputTexture[d]);
    44.             string outfile=infile.Insert(infile.Length-4,filenameInsert);
    45.             File.WriteAllBytes(outfile, bytes);
    46.         }
    47.  
    48.         AssetDatabase.Refresh();
    49.  
    50.     }
    51. }
    52.  
    And the shader, which works with animationed sprites/spritesheets.

    Code (CSharp):
    1. Shader "Sprites/Flippable"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         _Alpha ("Alpha", float) = 1
    8.         [MaterialToggle] _Flip ("Flip", Float) = 0
    9.         _SheetWidth ("SheetWidth", float) = 0
    10.         _SpriteWidth ("SpriteWidth", float) = 0
    11.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    12.     }
    13.  
    14.     SubShader
    15.     {
    16.         Tags
    17.         {
    18.             "Queue"="Transparent"
    19.             "IgnoreProjector"="True"
    20.             "RenderType"="Transparent"
    21.             "PreviewType"="Plane"
    22.             "CanUseSpriteAtlas"="True"
    23.         }
    24.  
    25.         Cull Off
    26.         Lighting Off
    27.         ZWrite Off
    28.         Fog { Mode Off }
    29.         Blend One OneMinusSrcAlpha
    30.  
    31.         Pass
    32.         {
    33.         CGPROGRAM
    34.             #pragma vertex vert
    35.             #pragma fragment frag
    36.             #pragma multi_compile DUMMY PIXELSNAP_ON
    37.             #include "UnityCG.cginc"
    38.          
    39.             struct appdata_t
    40.             {
    41.                 float4 vertex   : POSITION;
    42.                 float4 color    : COLOR;
    43.                 float2 texcoord : TEXCOORD0;
    44.             };
    45.  
    46.             struct v2f
    47.             {
    48.                 float4 vertex   : SV_POSITION;
    49.                 fixed4 color    : COLOR;
    50.                 half2 texcoord  : TEXCOORD0;
    51.             };
    52.          
    53.             sampler2D _MainTex;
    54.             fixed4 _Color;
    55.             float _Alpha;
    56.             float _SheetWidth;
    57.             float _SpriteWidth;
    58.             float _Flip;
    59.  
    60.             v2f vert(appdata_t IN)
    61.             {
    62.                 v2f OUT;
    63.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    64.                 OUT.texcoord = IN.texcoord;
    65.              
    66.                if ( _Flip != 0.0 )
    67.                {
    68.                     int column=((IN.texcoord.x*_SheetWidth)+_SpriteWidth)/_SpriteWidth;
    69.                     OUT.texcoord.x = ((((1.0/_SheetWidth)*_SpriteWidth)*(column+1))-IN.texcoord.x);
    70.                 }
    71.                  
    72.                 OUT.color = IN.color * _Color;
    73.                 OUT.color.a = OUT.color.a * _Alpha;
    74.                 #ifdef PIXELSNAP_ON
    75.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    76.                 #endif
    77.  
    78.                 return OUT;
    79.             }
    80.  
    81.  
    82.  
    83.             fixed4 frag(v2f IN) : SV_Target
    84.             {
    85.                 fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
    86.                 c.rgb *= c.a;
    87.              
    88.                 return c;
    89.             }
    90.         ENDCG
    91.         }
    92.     }
    93. }
     
    Last edited: Nov 4, 2014
  2. image28

    image28

    Joined:
    Jul 17, 2013
    Posts:
    457
    Getting a little flicker with animations using the shader, working on fixing it

    EDIT: Still no solution, getting weird results when animations are playing it renders a sprite from a completely different row.....
     
    Last edited: Nov 4, 2014