SpriteSheetInstanced.shader 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.
  2. // Author: Jason Ederle
  3. // Contact: jason@funly.io
  4. // Description: GPU instanced shader for flipping through a sprite sheet.
  5. Shader "Funly/Sky Studio/Sprite Sheets/Sprite Sheet Instanced"
  6. {
  7. Properties
  8. {
  9. [NoScaleOffset] _SpriteSheetTex ("Sprite Texture", 2D) = "black" {}
  10. _SpriteColumnCount ("Sprite Columns", int) = 1
  11. _SpriteRowCount ("Sprite Rows", int) = 1
  12. _SpriteItemCount ("Sprite Total Items", int) = 1
  13. _AnimationSpeed ("Animation Speed", int) = 25
  14. _Intensity ("Intensity", Range(0, 1)) = .7
  15. _TintColor ("Tint Color", Color) = (1, 1, 1, 1)
  16. }
  17. SubShader
  18. {
  19. Tags { "RenderType"="Transparent" "Queue"="Transparent" }
  20. LOD 100
  21. Blend OneMinusDstColor One
  22. Cull Off
  23. Pass
  24. {
  25. CGPROGRAM
  26. #pragma target 2.0
  27. #pragma vertex vert
  28. #pragma fragment frag
  29. #pragma multi_compile_instancing
  30. #include "UnityCG.cginc"
  31. struct appdata
  32. {
  33. float4 vertex : POSITION;
  34. float2 uv : TEXCOORD0;
  35. UNITY_VERTEX_INPUT_INSTANCE_ID
  36. };
  37. struct v2f
  38. {
  39. float2 uv : TEXCOORD0;
  40. float4 vertex : SV_POSITION;
  41. UNITY_VERTEX_INPUT_INSTANCE_ID
  42. };
  43. sampler2D _SpriteSheetTex;
  44. int _SpriteColumnCount;
  45. int _SpriteRowCount;
  46. int _SpriteItemCount;
  47. int _AnimationSpeed;
  48. float _Intensity;
  49. float4 _TintColor;
  50. UNITY_INSTANCING_BUFFER_START(Props)
  51. UNITY_DEFINE_INSTANCED_PROP(float, _StartTime)
  52. #define _StartTime_arr Props
  53. UNITY_DEFINE_INSTANCED_PROP(float, _EndTime)
  54. #define _EndTime_arr Props
  55. UNITY_INSTANCING_BUFFER_END(Props)
  56. int GetSpriteTargetIndex(int itemCount, int animationSpeed, float startTime) {
  57. float delta = _Time.y - startTime;
  58. float timePerFrame = 1.0f / _AnimationSpeed;
  59. int frameIndex = (int)(delta / timePerFrame);
  60. return clamp(frameIndex, 0, _SpriteItemCount - 1);
  61. }
  62. float2 GetSpriteItemSize(float2 dimensions) {
  63. return float2(1.0f / dimensions.x, (1.0f / dimensions.x) * (dimensions.x / dimensions.y));
  64. }
  65. float2 GetSpriteSheetCoords(float2 uv, float2 dimensions, int targetFrameIndex, float2 itemSize, int numItems) {
  66. int rows = dimensions.y;
  67. int columns = dimensions.x;
  68. float2 scaledUV = float2(uv.x * itemSize.x, uv.y * itemSize.y);
  69. float2 offset = float2(
  70. (int)abs(targetFrameIndex) % (int)abs(columns) * itemSize.x,
  71. ((rows - 1) - (targetFrameIndex / (int)abs(columns))) * itemSize.y);
  72. return scaledUV + offset;
  73. }
  74. float2 GetAnimatedSpriteCoords(float2 uv, float startTime) {
  75. float2 dimensions = float2(_SpriteColumnCount, _SpriteRowCount);
  76. float2 itemSize = GetSpriteItemSize(dimensions);
  77. int spriteTileIndex = GetSpriteTargetIndex(_SpriteItemCount, _AnimationSpeed, startTime);
  78. return GetSpriteSheetCoords(uv, dimensions, spriteTileIndex, itemSize, _SpriteItemCount);
  79. }
  80. // Get a normal ranged value in [-1,1] range from a 0-1 percent value.
  81. float GetNormalRangeFromPercent(float percent) {
  82. return -1.0f + (2.0f * percent);
  83. }
  84. float3 GetDirectionFromPercent(float3 percentDir) {
  85. return float3(
  86. GetNormalRangeFromPercent(percentDir.x),
  87. GetNormalRangeFromPercent(percentDir.y),
  88. GetNormalRangeFromPercent(percentDir.z));
  89. }
  90. v2f vert (appdata v)
  91. {
  92. v2f o;
  93. UNITY_SETUP_INSTANCE_ID(v);
  94. UNITY_TRANSFER_INSTANCE_ID(v, o);
  95. float4 worldPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0f));
  96. o.vertex = mul(UNITY_MATRIX_VP, worldPos);
  97. o.uv = v.uv;
  98. return o;
  99. }
  100. fixed4 frag (v2f i) : SV_Target
  101. {
  102. UNITY_SETUP_INSTANCE_ID(i);
  103. float startTime = UNITY_ACCESS_INSTANCED_PROP(_StartTime_arr, _StartTime);
  104. float endTime = UNITY_ACCESS_INSTANCED_PROP(_EndTime_arr, _EndTime);
  105. float2 spriteUV = saturate(GetAnimatedSpriteCoords(i.uv, startTime));
  106. fixed4 spriteColor = tex2D(_SpriteSheetTex, spriteUV) * _Intensity * _TintColor;
  107. // Go transparent if the sprite completed its time loop.
  108. return spriteColor * step(_Time.y, endTime);
  109. }
  110. ENDCG
  111. }
  112. }
  113. FallBack "Unlit/Color"
  114. }