您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

412 行
15 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class PlayModeTestsUI : MonoBehaviour
{
static PlayModeTestsUI _instance;
public static PlayModeTestsUI instance
{
get
{
if (_instance == null )
{
_instance = FindObjectOfType<PlayModeTestsUI>();
}
return _instance;
}
}
public static bool Exists
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<PlayModeTestsUI>();
return false;
}
return _instance != null;
}
}
[SerializeField] int frameWait = 100;
[SerializeField] GameObject resultsPanel, waitingPanel, scenePanel;
[SerializeField] Text overallAvgText;
[SerializeField] RectTransform overallAvgFill;
[SerializeField] Text overallMaxText;
[SerializeField] RectTransform overallMaxFill;
[SerializeField] RectTransform testResultPrefab;
[SerializeField] ScrollRect scrollView;
[SerializeField] RawImage resultImage;
Material resultComparerMaterial;
[SerializeField] Gradient fillGradient = new Gradient() { colorKeys = new GradientColorKey[] {
new GradientColorKey( Color.red, 0.5f),
new GradientColorKey( Color.yellow, 0.75f),
new GradientColorKey( Color.green, 0.97f),
} };
int numOfResults = 1;
List<GameObject> testResults;
int[] avgResults;
int[] maxResults;
Text[] resultsLabels;
Text[] resultsAvgValue;
RectTransform[] resultsAvgFill;
Text[] resultsMaxValue;
RectTransform[] resultsMaxFill;
EventSystem eventSystem;
GameObject lastSelected;
Texture2D currentTemplate;
RenderTexture currentRT;
RenderTexture resultRT;
Text scenePanelText;
Image waitingImage;
// Use this for initialization
void Start ()
{
// kill itself if already in scene.
if (Exists)
{
Debug.Log("Kill UIObject because it already exists.");
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
//Debug.Log("Need to create " + (UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings - 1) + " test result object.");
// Set scroll view content to fit all results
scrollView.content.anchorMin = new Vector2(0f, 0f);
scrollView.content.anchorMax = new Vector2(1f, 0f);
scrollView.content.offsetMin = new Vector2(0f, - (UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings - 1f) * 200f);
scrollView.content.offsetMax = new Vector2(0f, 0f);
// Init results arrays
numOfResults = UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings - 1;
avgResults = new int[numOfResults];
maxResults = new int[numOfResults];
resultsLabels = new Text[numOfResults];
resultsAvgValue = new Text[numOfResults];
resultsAvgFill = new RectTransform[numOfResults];
resultsMaxValue = new Text[numOfResults];
resultsMaxFill = new RectTransform[numOfResults];
testResults = new List<GameObject>(numOfResults);
// Create results UI
for (int i = 0; i < numOfResults; ++i)
{
RectTransform singleTestResult = Instantiate(testResultPrefab);
testResults.Add(singleTestResult.gameObject);
resultsLabels[i] = singleTestResult.Find("Label").GetComponent<Text>();
resultsAvgValue[i] = singleTestResult.Find("Avg_Value/Text").GetComponent<Text>();
resultsAvgFill[i] = singleTestResult.Find("Avg_Value/Fill").GetComponent<RectTransform>();
resultsMaxValue[i] = singleTestResult.Find("Max_Value/Text").GetComponent<Text>();
resultsMaxFill[i] = singleTestResult.Find("Max_Value/Fill").GetComponent<RectTransform>();
singleTestResult.SetParent(scrollView.content);
singleTestResult.anchorMin = new Vector2(0, 0);
singleTestResult.anchorMax = new Vector2(1, 0);
singleTestResult.offsetMin = new Vector2(0, scrollView.content.rect.height - (i + 1) * 200f);
singleTestResult.offsetMax = new Vector2(0, singleTestResult.offsetMin.y + 200f);
int sceneIndex = i;
singleTestResult.GetComponent<Button>().onClick.AddListener(delegate () { LoadSceneResult(sceneIndex); });
//* Test the values
SetResult(i, 1.0f * i / (numOfResults - 1), 0.5f);
}
CalculateOverall();
scrollView.Rebuild( UnityEngine.UI.CanvasUpdate.PostLayout );
eventSystem = GetComponentInChildren<EventSystem>();
eventSystem.SetSelectedGameObject(testResults[0]);
resultsPanel.SetActive(false);
waitingPanel.SetActive(false);
scenePanel.SetActive(false);
resultComparerMaterial = Instantiate( resultImage.material );
resultImage.material = resultComparerMaterial;
// Initialize render textures
currentRT = new RenderTexture(1920, 1080, 0, RenderTextureFormat.ARGB32);
resultRT = new RenderTexture(1920, 1080, 0, RenderTextureFormat.ARGB32);
scenePanelText = scenePanel.transform.Find("Text").GetComponent<Text>();
waitingImage = waitingPanel.transform.Find("Image").GetComponent<Image>();
// Load scenes and calculate the results.
StartCoroutine(CalculateAllResults());
}
void SetResult(int _index, float _avgValue, float _maxValue)
{
avgResults[_index] = Mathf.RoundToInt(_avgValue * 100f);
resultsAvgValue[_index].text = avgResults[_index].ToString() + "%";
resultsAvgFill[_index].localScale = new Vector3(_avgValue, 1f, 1f);
resultsAvgFill[_index].GetComponent<Image>().color = fillGradient.Evaluate(_avgValue);
maxResults[_index] = Mathf.RoundToInt(_maxValue * 100f);
resultsMaxValue[_index].text = maxResults[_index].ToString() + "%";
resultsMaxFill[_index].localScale = new Vector3(_maxValue, 1f, 1f);
resultsAvgFill[_index].GetComponent<Image>().color = fillGradient.Evaluate(1f-_maxValue);
}
void CalculateOverall()
{
float overallAvgResult = 0f;
float overallMaxResult = 0f;
for (int i=0; i<numOfResults; ++i)
{
overallAvgResult += 1.0f * avgResults[i];
overallMaxResult += 1.0f * maxResults[i];
}
overallAvgResult /= numOfResults;
overallMaxResult /= numOfResults;
overallAvgFill.localScale = new Vector3(overallAvgResult * 0.01f, 1f, 1f);
overallAvgText.text = Mathf.RoundToInt(overallAvgResult).ToString() + "%";
overallAvgFill.GetComponent<Image>().color = fillGradient.Evaluate(overallAvgResult * 0.01f);
overallMaxFill.localScale = new Vector3(overallMaxResult * 0.01f, 1f, 1f);
overallMaxText.text = Mathf.RoundToInt(overallMaxResult).ToString() + "%";
overallMaxFill.GetComponent<Image>().color = fillGradient.Evaluate(1f- overallMaxResult * 0.01f);
}
IEnumerator CalculateAllResults()
{
resultsPanel.SetActive(false);
waitingPanel.SetActive(true);
scenePanel.SetActive(false);
waitingImage.fillAmount = 0f;
for (int i=0; i<numOfResults;++i)
{
yield return CalculateResult(i);
waitingImage.fillAmount = 1f * (1f+i) / numOfResults;
waitingImage.color = Color.Lerp(Color.blue, Color.green, 1f * i / (numOfResults - 1));
}
CalculateOverall();
UnityEngine.SceneManagement.SceneManager.LoadScene(0);
resultsPanel.SetActive(true);
waitingPanel.SetActive(false);
scenePanel.SetActive(false);
yield return null;
}
IEnumerator CalculateResult(int _index)
{
UnityEngine.SceneManagement.SceneManager.LoadScene(_index + 1);
yield return null;
var testSetup = FindObjectOfType<UnityEngine.Experimental.Rendering.SetupSceneForRenderPipelineTest>();
testSetup.Setup();
for (int f = 0; f < frameWait; ++f)
{
yield return null;
}
resultsLabels[_index].text = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
Debug.Log("Get " + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
// find the reference image
currentTemplate = Resources.Load<Texture2D>(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name + ".unity");
resultImage.texture = currentTemplate;
// Descriptor for the render textures
RenderTextureDescriptor desc = new RenderTextureDescriptor()
{
width = currentTemplate.width,
height = currentTemplate.height,
autoGenerateMips = false,
colorFormat = RenderTextureFormat.ARGB32,
msaaSamples = testSetup.msaaSamples,
sRGB = true,
volumeDepth = 1,
dimension = UnityEngine.Rendering.TextureDimension.Tex2D,
};
// re-create the render textures to correct size
DestroyImmediate(currentRT);
currentRT = new RenderTexture(desc);
DestroyImmediate(resultRT);
resultRT = new RenderTexture(desc);
currentRT.filterMode = resultRT.filterMode = FilterMode.Bilinear;
currentRT.wrapMode = resultRT.wrapMode = TextureWrapMode.Clamp;
// render the scene
var oldTarget = testSetup.cameraToUse.targetTexture;
testSetup.cameraToUse.targetTexture = currentRT;
testSetup.cameraToUse.Render();
testSetup.cameraToUse.targetTexture = oldTarget;
// render comparision RT
resultComparerMaterial.SetFloat("_ResultSplit", 1f);
resultComparerMaterial.SetInt("_Mode", 4);
resultComparerMaterial.SetTexture("_MainTex", currentTemplate);
resultComparerMaterial.SetTexture("_CompareTex", currentRT);
Graphics.Blit(currentTemplate, resultRT, resultComparerMaterial);
// Readback the rendered texture
var oldActive = RenderTexture.active;
RenderTexture.active = resultRT;
var captured = new Texture2D(resultRT.width, resultRT.height, TextureFormat.RGB24, false);
captured.ReadPixels(new Rect(0, 0, testSetup.width, testSetup.height), 0, 0);
RenderTexture.active = oldActive;
// compare
Vector2 compareResult = ReadCompareTexture(captured);
SetResult(_index, 1f - compareResult.x, compareResult.y);
// Set the compare material values for display if needed
resultComparerMaterial.SetFloat("_Split", 0.5f);
resultComparerMaterial.SetFloat("_ResultSplit", 0f);
resultComparerMaterial.SetInt("_Mode", 4);
yield return null;
}
private Vector2 ReadCompareTexture(Texture2D captured)
{
if (captured == null)
return Vector2.one;
var pixels = captured.GetPixels();
int numberOfPixels = pixels.Length;
float sumOfDiff = 0;
float maxDiff = 0f;
for (int i = 0; i < numberOfPixels; i++)
{
maxDiff = Mathf.Max(maxDiff, pixels[i].r);
sumOfDiff += pixels[i].r;
}
return new Vector2(Mathf.Sqrt(sumOfDiff / numberOfPixels), maxDiff);
}
private Vector2 CompareTextures(Texture2D fromDisk, Texture2D captured)
{
if (fromDisk == null || captured == null)
return Vector2.one;
if (fromDisk.width != captured.width
|| fromDisk.height != captured.height)
return Vector2.one;
var pixels1 = fromDisk.GetPixels();
var pixels2 = captured.GetPixels();
if (pixels1.Length != pixels2.Length)
return Vector2.one;
int numberOfPixels = pixels1.Length;
float sumOfSquaredColorDistances = 0;
float maxSquaredColorDistance = 0f;
for (int i = 0; i < numberOfPixels; i++)
{
Color p1 = pixels1[i];
Color p2 = pixels2[i];
Color diff = p1 - p2;
diff = diff * diff;
maxSquaredColorDistance = Mathf.Max(maxSquaredColorDistance, (diff.r + diff.g + diff.b) / 3.0f);
sumOfSquaredColorDistances += (diff.r + diff.g + diff.b) / 3.0f;
}
return new Vector2( Mathf.Sqrt(sumOfSquaredColorDistances / numberOfPixels), maxSquaredColorDistance );
}
void LoadSceneResult(int _index)
{
if ((_index <0 ) || (_index >= ( UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings-1))) return;
Debug.Log("Load Scene Results : " + _index);
// CalculateResult(_index);
StartCoroutine(CalculateResult(_index));
scenePanelText.text = resultsLabels[_index].text;
resultsPanel.SetActive(false);
waitingPanel.SetActive(false);
scenePanel.SetActive(true);
}
// Update is called once per frame
void Update ()
{
if (resultsPanel.activeSelf)
{
if (eventSystem.currentSelectedGameObject != lastSelected)
{
lastSelected = eventSystem.currentSelectedGameObject;
if (testResults.Contains(lastSelected)) scrollView.verticalNormalizedPosition = 1.0f - 1.0f * testResults.IndexOf(lastSelected) / (numOfResults - 1f);
}
}
if (scenePanel.activeSelf)
{
// Scale the raw image to display at the correct aspect ratio
Rect parentRect = resultImage.rectTransform.parent.GetComponent<RectTransform>().rect;
float parentRatio = parentRect.width / parentRect.height;
float templateRatio = resultImage.texture.width / resultImage.texture.height;
Debug.Log("Parent : " + parentRect.width + " / " + parentRect.height + " ||| Child : " + resultImage.texture.width + " / " + resultImage.texture.height);
float resultRatio = 2f * parentRatio / templateRatio;
if (resultRatio > 1)
{
resultImage.rectTransform.anchorMin = new Vector2(0.5f / resultRatio, 0f);
resultImage.rectTransform.anchorMax = new Vector2(1f - 0.5f / resultRatio, 1f);
}
else
{
resultImage.rectTransform.anchorMin = new Vector2(0f, 0.5f / resultRatio);
resultImage.rectTransform.anchorMax = new Vector2(1f, 1f - 0.5f / resultRatio);
}
resultComparerMaterial.SetFloat("_Split", Mathf.Clamp01(resultComparerMaterial.GetFloat("_Split") + Input.GetAxis("Horizontal") * Time.deltaTime));
resultComparerMaterial.SetFloat("_ResultSplit", Mathf.Clamp01(resultComparerMaterial.GetFloat("_ResultSplit") + Input.GetAxis("Vertical") * Time.deltaTime));
if (Input.GetButtonDown("Fire3")) resultComparerMaterial.SetInt("_Mode", (resultComparerMaterial.GetInt("_Mode") + 1) % 6);
if (Input.GetButtonDown("Fire2"))
{
resultsPanel.SetActive(true);
waitingPanel.SetActive(false);
scenePanel.SetActive(false);
}
}
}
}