No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TextureTasks.cs 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. using System;
  2. using Unity.Burst;
  3. using Unity.Collections;
  4. using UnityEngine;
  5. namespace UnityEditor.U2D.Aseprite
  6. {
  7. #if UNITY_2022_2_OR_NEWER
  8. [BurstCompile]
  9. #endif
  10. internal static class TextureTasks
  11. {
  12. [BurstCompile]
  13. public static void AddOpacity(ref NativeArray<Color32> texture, float opacity)
  14. {
  15. for (var i = 0; i < texture.Length; ++i)
  16. {
  17. var color = texture[i];
  18. color.a = (byte)(color.a * opacity);
  19. texture[i] = color;
  20. }
  21. }
  22. [BurstCompile]
  23. public static void FlipTextureY(ref NativeArray<Color32> texture, int width, int height)
  24. {
  25. if (width == 0 || height == 0)
  26. return;
  27. var outputTexture = new NativeArray<Color32>(texture.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
  28. for (var y = 0; y < height; ++y)
  29. {
  30. var inRow = ((height - 1) - y) * width;
  31. var outRow = y * width;
  32. for (var x = 0; x < width; ++x)
  33. {
  34. var inIndex = x + inRow;
  35. var outIndex = x + outRow;
  36. outputTexture[outIndex] = texture[inIndex];
  37. }
  38. }
  39. texture.DisposeIfCreated();
  40. texture = outputTexture;
  41. }
  42. public struct MergeOutput
  43. {
  44. public RectInt rect;
  45. public NativeArray<Color32> image;
  46. }
  47. [BurstCompile]
  48. public static unsafe void MergeTextures(in NativeArray<IntPtr> textures, in NativeArray<RectInt> textureSizes, in NativeArray<BlendModes> blendModes, out MergeOutput output)
  49. {
  50. GetCombinedRect(in textureSizes, out var combinedRect);
  51. var outputTexture = new NativeArray<Color32>(combinedRect.width * combinedRect.height, Allocator.Persistent);
  52. var outStartX = combinedRect.x;
  53. var outStartY = combinedRect.y;
  54. var outWidth = combinedRect.width;
  55. var outHeight = combinedRect.height;
  56. for (var i = 0; i < textures.Length; ++i)
  57. {
  58. var inputColor = (Color32*)textures[i];
  59. var inputBlend = blendModes[i];
  60. var inX = textureSizes[i].x;
  61. var inY = textureSizes[i].y;
  62. var inWidth = textureSizes[i].width;
  63. var inHeight = textureSizes[i].height;
  64. for (var y = 0; y < inHeight; ++y)
  65. {
  66. var outPosY = (y + inY) - outStartY;
  67. // If pixel is outside of output texture's Y, move to the next pixel.
  68. if (outPosY < 0 || outPosY >= outHeight)
  69. continue;
  70. // Flip Y position on the input texture, because
  71. // Aseprite textures are stored "upside-down"
  72. var inRow = ((inHeight - 1) - y) * inWidth;
  73. var outRow = outPosY * outWidth;
  74. for (var x = 0; x < inWidth; ++x)
  75. {
  76. var outPosX = (x + inX) - outStartX;
  77. // If pixel is outside of output texture's X, move to the next pixel.
  78. if (outPosX < 0 || outPosX >= outWidth)
  79. continue;
  80. var inBufferIndex = inRow + x;
  81. var outBufferIndex = outRow + outPosX;
  82. if (outBufferIndex < 0 || outBufferIndex > (outWidth * outHeight))
  83. continue;
  84. var inColor = inputColor[inBufferIndex];
  85. var prevOutColor = outputTexture[outBufferIndex];
  86. Color32 outColor;
  87. switch (inputBlend)
  88. {
  89. case BlendModes.Darken:
  90. PixelBlends.Darken(in prevOutColor, in inColor, out outColor);
  91. break;
  92. case BlendModes.Multiply:
  93. PixelBlends.Multiply(in prevOutColor, in inColor, out outColor);
  94. break;
  95. case BlendModes.ColorBurn:
  96. PixelBlends.ColorBurn(in prevOutColor, in inColor, out outColor);
  97. break;
  98. case BlendModes.Lighten:
  99. PixelBlends.Lighten(in prevOutColor, in inColor, out outColor);
  100. break;
  101. case BlendModes.Screen:
  102. PixelBlends.Screen(in prevOutColor, in inColor, out outColor);
  103. break;
  104. case BlendModes.ColorDodge:
  105. PixelBlends.ColorDodge(in prevOutColor, in inColor, out outColor);
  106. break;
  107. case BlendModes.Addition:
  108. PixelBlends.Addition(in prevOutColor, in inColor, out outColor);
  109. break;
  110. case BlendModes.Overlay:
  111. PixelBlends.Overlay(in prevOutColor, in inColor, out outColor);
  112. break;
  113. case BlendModes.SoftLight:
  114. PixelBlends.SoftLight(in prevOutColor, in inColor, out outColor);
  115. break;
  116. case BlendModes.HardLight:
  117. PixelBlends.HardLight(in prevOutColor, in inColor, out outColor);
  118. break;
  119. case BlendModes.Difference:
  120. PixelBlends.Difference(in prevOutColor, in inColor, out outColor);
  121. break;
  122. case BlendModes.Exclusion:
  123. PixelBlends.Exclusion(in prevOutColor, in inColor, out outColor);
  124. break;
  125. case BlendModes.Subtract:
  126. PixelBlends.Subtract(in prevOutColor, in inColor, out outColor);
  127. break;
  128. case BlendModes.Divide:
  129. PixelBlends.Divide(in prevOutColor, in inColor, out outColor);
  130. break;
  131. case BlendModes.Hue:
  132. PixelBlends.Hue(in prevOutColor, in inColor, out outColor);
  133. break;
  134. case BlendModes.Saturation:
  135. PixelBlends.Saturation(in prevOutColor, in inColor, out outColor);
  136. break;
  137. case BlendModes.Color:
  138. PixelBlends.ColorBlend(in prevOutColor, in inColor, out outColor);
  139. break;
  140. case BlendModes.Luminosity:
  141. PixelBlends.Luminosity(in prevOutColor, in inColor, out outColor);
  142. break;
  143. case BlendModes.Normal:
  144. default:
  145. PixelBlends.Normal(in prevOutColor, in inColor, out outColor);
  146. break;
  147. }
  148. outputTexture[outBufferIndex] = outColor;
  149. }
  150. }
  151. }
  152. output = new MergeOutput()
  153. {
  154. rect = combinedRect,
  155. image = outputTexture
  156. };
  157. }
  158. [BurstCompile]
  159. static void GetCombinedRect(in NativeArray<RectInt> rects, out RectInt combinedRect)
  160. {
  161. combinedRect = rects[0];
  162. for (var i = 1; i < rects.Length; ++i)
  163. {
  164. var rectToFitIn = rects[i];
  165. FitRectInsideRect(ref combinedRect, in rectToFitIn);
  166. }
  167. }
  168. [BurstCompile]
  169. static void FitRectInsideRect(ref RectInt baseRect, in RectInt rectToFitIn)
  170. {
  171. if (baseRect.xMin > rectToFitIn.xMin)
  172. baseRect.xMin = rectToFitIn.xMin;
  173. if (baseRect.yMin > rectToFitIn.yMin)
  174. baseRect.yMin = rectToFitIn.yMin;
  175. if (baseRect.xMax < rectToFitIn.xMax)
  176. baseRect.xMax = rectToFitIn.xMax;
  177. if (baseRect.yMax < rectToFitIn.yMax)
  178. baseRect.yMax = rectToFitIn.yMax;
  179. }
  180. }
  181. }