AlphaShot.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace alphaShot
  4. {
  5. //code from essu and Kenzato
  6. public static class AlphaShot
  7. {
  8. public static byte[] Capture(int ResolutionX, int ResolutionY, int DownscalingRate, int AntiAliasing)
  9. {
  10. //File.WriteAllLines(GameObject.FindObjectsOfType<SkinnedMeshRenderer>().Select(x => x.material.shader.name).Distinct().OrderBy(x => x).ToArray();
  11. var c = Camera.main;
  12. var t1 = PerformCapture(true, ResolutionX * DownscalingRate, ResolutionY * DownscalingRate, AntiAliasing);
  13. var t2 = PerformCapture(false, ResolutionX * DownscalingRate, ResolutionY * DownscalingRate, AntiAliasing);
  14. var p1 = t1.GetPixels();
  15. var p2 = t2.GetPixels();
  16. for (int i = 0; i < p1.Length; i++)
  17. {
  18. var pp1 = p1[i];
  19. var pp2 = p2[i];
  20. var pp1a = pp1.a;
  21. var pp2a = pp2.a;
  22. pp1.a = 1.0f;
  23. pp2.a = 1.0f;
  24. p1[i] = Color.Lerp(pp1, pp2, pp2a);
  25. p1[i].a = Mathf.Clamp01(pp2a * 4);
  26. }
  27. t1.SetPixels(p1);
  28. t1.Apply();
  29. TextureScale.Bilinear(t1, ResolutionX, ResolutionY);
  30. byte[] output = t1.EncodeToPNG();
  31. GameObject.Destroy(t1);
  32. GameObject.Destroy(t2);
  33. return output;
  34. }
  35. public static Texture2D PerformCapture(bool captureAlphaOnly, int ResolutionX, int ResolutionY, int AntiAliasing)
  36. {
  37. var go = new GameObject();
  38. Camera RenderCam = go.AddComponent<Camera>();
  39. RenderCam.CopyFrom(Camera.main);
  40. CopyComponents(Camera.main.gameObject, RenderCam.gameObject);
  41. var backRenderTexture = RenderCam.targetTexture;
  42. var backRect = RenderCam.rect;
  43. var oldBackground = RenderCam.backgroundColor;
  44. var oldFlags = RenderCam.clearFlags;
  45. var width = ResolutionX;
  46. var height = ResolutionY;
  47. var tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
  48. var rt = RenderTexture.GetTemporary(width, height, 32, RenderTextureFormat.Default, RenderTextureReadWrite.Default, AntiAliasing);
  49. var lst = new List<SkinnedMeshRenderer>();
  50. if (captureAlphaOnly)
  51. {
  52. Graphics.SetRenderTarget(rt);
  53. GL.Clear(true, true, Color.clear);
  54. Graphics.SetRenderTarget(null);
  55. }
  56. else
  57. {
  58. foreach (var smr in GameObject.FindObjectsOfType<SkinnedMeshRenderer>())
  59. if (smr.enabled)
  60. {
  61. //if (smr.material.renderQueue > 2500 || smr.material.renderQueue == -1 && smr.material.shader.renderQueue > 2500)
  62. if (smr.material.shader.name == "Shader Forge/PBRsp_alpha" ||
  63. smr.material.shader.name == "Shader Forge/PBRsp_alpha_culloff" ||
  64. smr.material.shader.name == "Shader Forge/PBRsp_texture_alpha" ||
  65. smr.material.shader.name == "Shader Forge/PBRsp_texture_alpha_culloff" ||
  66. smr.material.shader.name == "Unlit/Transparent")
  67. {
  68. lst.Add(smr);
  69. smr.enabled = false;
  70. }
  71. }
  72. }
  73. RenderCam.backgroundColor = new Color(0f, 0f, 0f, 0f);
  74. RenderCam.clearFlags = captureAlphaOnly ? CameraClearFlags.Depth : CameraClearFlags.Color;
  75. RenderCam.targetTexture = rt;
  76. RenderCam.rect = new Rect(0, 0, 1f, 1f);
  77. RenderCam.Render();
  78. RenderCam.targetTexture = backRenderTexture;
  79. RenderCam.rect = backRect;
  80. RenderTexture.active = rt;
  81. tex.ReadPixels(new Rect(0f, 0f, width, height), 0, 0);
  82. tex.Apply();
  83. RenderTexture.active = null;
  84. RenderCam.backgroundColor = oldBackground;
  85. RenderCam.clearFlags = oldFlags;
  86. RenderTexture.ReleaseTemporary(rt);
  87. foreach (var smr in lst)
  88. smr.enabled = true;
  89. return tex;
  90. }
  91. static void CopyComponents(GameObject original, GameObject target)
  92. {
  93. foreach (Component component in original.GetComponents<Component>())
  94. {
  95. var newComponent = CopyComponent(component, target);
  96. if (component is MonoBehaviour)
  97. {
  98. var behavior = (MonoBehaviour)component;
  99. (newComponent as MonoBehaviour).enabled = behavior.enabled;
  100. }
  101. }
  102. }
  103. //https://answers.unity.com/questions/458207/copy-a-component-at-runtime.html
  104. static Component CopyComponent(Component original, GameObject destination)
  105. {
  106. System.Type type = original.GetType();
  107. Component copy = destination.AddComponent(type);
  108. // Copied fields can be restricted with BindingFlags
  109. System.Reflection.FieldInfo[] fields = type.GetFields();
  110. foreach (System.Reflection.FieldInfo field in fields)
  111. {
  112. field.SetValue(copy, field.GetValue(original));
  113. }
  114. return copy;
  115. }
  116. }
  117. }