EffectEvla.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #if UNITY_EDITOR
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEditor;
  7. /// <summary>
  8. /// 主要用于计算overdraw像素
  9. /// </summary>
  10. public class EffectEvla
  11. {
  12. public Camera _camera;
  13. SingleEffectEvla singleEffectEvla;
  14. public float time = 0;
  15. //采集特效数据的区域大小
  16. int rtSizeWidth = 512;
  17. int rtSizeHeight = 512;
  18. public int maxOverDrwa;
  19. // RenderTexture rt;
  20. private ParticleEffectScript particleEffectScript;
  21. public EffectEvla(ParticleEffectScript particleEffectScript, Camera camera)
  22. {
  23. this.particleEffectScript = particleEffectScript;
  24. SetCamera(camera);
  25. particleEffectScript.RenderTexture = new RenderTexture(rtSizeWidth, rtSizeHeight, 0, RenderTextureFormat.ARGB32);
  26. singleEffectEvla = new SingleEffectEvla(1);
  27. }
  28. public void SetCamera(Camera camera)
  29. {
  30. _camera = camera;
  31. Shader shader= Shader.Find("ParticleEffectProfiler/OverDraw");
  32. Debug.Log(shader);
  33. }
  34. public void Update()
  35. {
  36. time += Time.deltaTime;
  37. RecordOverDrawData(singleEffectEvla);
  38. }
  39. public EffectEvlaData[] GetEffectEvlaData()
  40. {
  41. return singleEffectEvla.GetEffectEvlaDatas();
  42. }
  43. #region overdraw
  44. public void RecordOverDrawData(SingleEffectEvla singleEffectEvla)
  45. {
  46. int pixTotal = 0;
  47. int pixActualDraw = 0;
  48. GetCameraOverDrawData(out pixTotal, out pixActualDraw);
  49. // 往数据+1
  50. singleEffectEvla.UpdateOneData(pixTotal, pixActualDraw);
  51. }
  52. public void GetCameraOverDrawData(out int pixTotal, out int pixActualDraw)
  53. {
  54. //记录当前激活的渲染纹理
  55. RenderTexture activeTextrue = RenderTexture.active;
  56. //渲染指定范围的rt,并记录范围内所有rgb像素值
  57. _camera.targetTexture = particleEffectScript.RenderTexture;
  58. _camera.Render();
  59. RenderTexture.active = particleEffectScript.RenderTexture;
  60. Texture2D texture = new Texture2D(particleEffectScript.RenderTexture.width, particleEffectScript.RenderTexture.height, TextureFormat.ARGB32, false);
  61. texture.ReadPixels(new Rect(0, 0, particleEffectScript.RenderTexture.width, particleEffectScript.RenderTexture.height), 0, 0);
  62. texture.Apply();
  63. GetOverDrawData(texture, out pixTotal, out pixActualDraw);
  64. particleEffectScript.Texture2D = texture;
  65. //恢复之前激活的渲染纹理
  66. RenderTexture.active = activeTextrue;
  67. // Texture2D.DestroyImmediate(texture);
  68. // rt.Release();
  69. _camera.targetTexture = null;
  70. }
  71. public void GetOverDrawData(Texture2D texture, out int pixTotal, out int pixActualDraw)
  72. {
  73. var texw = texture.width;
  74. var texh = texture.height;
  75. var pixels = texture.GetPixels();
  76. int index = 0;
  77. pixTotal = 0;
  78. pixActualDraw = 0;
  79. maxOverDrwa = 0;
  80. for (var y = 0; y < texh; y++)
  81. {
  82. for (var x = 0; x < texw; x++)
  83. {
  84. float r = pixels[index].r;
  85. float g = pixels[index].g;
  86. float b = pixels[index].b;
  87. bool isEmptyPix = IsEmptyPix(r, g, b);
  88. if (!isEmptyPix)
  89. {
  90. pixTotal++;
  91. }
  92. int drawThisPixTimes = DrawPixTimes(r, g, b);
  93. if (maxOverDrwa < drawThisPixTimes)
  94. {
  95. maxOverDrwa = drawThisPixTimes;
  96. }
  97. if (drawThisPixTimes != 0)
  98. {
  99. pixActualDraw += drawThisPixTimes;
  100. }
  101. index++;
  102. }
  103. }
  104. Debug.Log(maxOverDrwa);
  105. }
  106. //计算单像素的绘制次数
  107. public int DrawPixTimes(float r, float g, float b)
  108. {
  109. return DrawPixTimesForGamma(g);
  110. }
  111. //Linear空间下的计算方式
  112. private int DrawPixTimesForLinear(float g)
  113. {
  114. //在OverDraw.Shader中像素每渲染一次,g值就会叠加0.04
  115. return Convert.ToInt32(g / 0.04);
  116. }
  117. //Gamma空间下的计算方式 by Blaze火神
  118. private int DrawPixTimesForGamma(float g)
  119. {
  120. //对g值进行Gamma校正
  121. float GLo = g / 12.92f;
  122. float GHi = Mathf.Pow((g + 0.055f) / 1.055f, 2.4f);
  123. float res = (g <= 0.04045f) ? GLo : GHi;
  124. return Convert.ToInt32(res / 0.04);
  125. }
  126. public bool IsEmptyPix(float r, float g, float b)
  127. {
  128. return r == 0 && g == 0 && b == 0;
  129. }
  130. #endregion
  131. }
  132. #endif