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

290 行
12 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEditor.SceneManagement;
using Object = UnityEngine.Object;
using UnityEngine.Experimental.Rendering;
using UnityEngine.TestTools;
namespace UnityEditor.Experimental.Rendering
{
public class GraphicsTests
{
// Change the SRP before a full batch of tests
public virtual string _SRP_ID { get { return "NONE"; } }
[MenuItem("Internal/GraphicTest Tools/Set Tests Pipelines",false, 0)]
public static void SetTestsPipelines()
{
_doOnlyFirstRenderPipelineAsset = !EditorUtility.DisplayDialog(
"Graphic Tests",
"Do you want to run the test(s) on all available Render Pipeline assets or only the first (main) one ?",
"Hell YEAH, go for it !",
"No thanks, just one please.");
}
private static bool? _doOnlyFirstRenderPipelineAsset;
private static bool doOnlyFirstRenderPipelineAsset
{
get
{
if (!_doOnlyFirstRenderPipelineAsset.HasValue) SetTestsPipelines();
return _doOnlyFirstRenderPipelineAsset.Value;
}
}
[OneTimeSetUp]
public void OneTimeSetUp()
{
BackupSceneManagerSetup();
SetupRenderPipeAsset();
SetupQualitySettings();
}
[OneTimeTearDown]
public void OnTimeTearDown()
{
//Debug.Log("OneTimeTearDown");
RestoreRenderPipeAsset();
RestoreSceneManagerSetup();
RestoreQualitySettings();
}
public static RenderPipelineAsset GetRenderPipelineAsset(string _SRP_ID)
{
string absolutePath = TestFrameworkTools.s_Path.Aggregate(TestFrameworkTools.s_RootPath, Path.Combine);
string filePath = Path.Combine(absolutePath, TestFrameworkTools.renderPipelineAssets[_SRP_ID] );
filePath = filePath.Replace(Application.dataPath, "");
filePath = filePath.Remove(0, 1);
//Debug.Log("Before combine: " + filePath);
filePath = Path.Combine("Assets", filePath);
//Debug.Log("RP Asset is at : " + filePath);
return (RenderPipelineAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(RenderPipelineAsset));
}
public static RenderPipelineAsset beforeTestsRenderPipeAsset;
public static RenderPipelineAsset wantedTestsRenderPipeAsset;
public void SetupRenderPipeAsset()
{
//Debug.Log("Set " + _SRP_ID + " render pipeline. Previous was "+ ( (UnityEngine.Rendering.GraphicsSettings.renderPipelineAsset == null)? "null":UnityEngine.Rendering.GraphicsSettings.renderPipelineAsset.name) );
beforeTestsRenderPipeAsset = UnityEngine.Rendering.GraphicsSettings.renderPipelineAsset;
wantedTestsRenderPipeAsset = GetRenderPipelineAsset(_SRP_ID);
if (wantedTestsRenderPipeAsset != beforeTestsRenderPipeAsset)
UnityEngine.Rendering.GraphicsSettings.renderPipelineAsset = wantedTestsRenderPipeAsset;
}
public void RestoreRenderPipeAsset()
{
//Debug.Log("RestoreRenderPipeAsset from " + wantedTestsRenderPipeAsset.name + " to " + ((beforeTestsRenderPipeAsset == null)?"null":beforeTestsRenderPipeAsset.name));
if (wantedTestsRenderPipeAsset != beforeTestsRenderPipeAsset)
{
//Debug.Log("RestoreRenderPipeAsset -> Actual restore");
UnityEngine.Rendering.GraphicsSettings.renderPipelineAsset = beforeTestsRenderPipeAsset;
}
}
public static SceneSetup[] sceneManagerSetupBeforeTest;
public void BackupSceneManagerSetup()
{
sceneManagerSetupBeforeTest = EditorSceneManager.GetSceneManagerSetup();
}
public void RestoreSceneManagerSetup()
{
if ( (sceneManagerSetupBeforeTest == null) || ( sceneManagerSetupBeforeTest.Length == 0 ) )
{
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
}
else
{
EditorSceneManager.RestoreSceneManagerSetup(sceneManagerSetupBeforeTest);
}
}
public int qualityLevel = 0;
public void SetupQualitySettings()
{
qualityLevel = QualitySettings.GetQualityLevel();
List<string> qualityNames = new List<string>(QualitySettings.names);
if (!qualityNames.Contains("Graphic Tests"))
{
EditorUtility.DisplayDialog("Add a Quality Setting", "To run properly the Graphic Test, please add a Quality Setting named \"Graphic Tests\".", "Ok");
throw new Exception("Missing QualitySetting");
}
QualitySettings.SetQualityLevel( qualityNames.IndexOf("Graphic Tests"));
QualitySettings.masterTextureLimit = 0;
QualitySettings.anisotropicFiltering = AnisotropicFiltering.ForceEnable;
QualitySettings.realtimeReflectionProbes = true;
QualitySettings.billboardsFaceCameraPosition = true;
QualitySettings.resolutionScalingFixedDPIFactor = 1f;
QualitySettings.shadowmaskMode = ShadowmaskMode.DistanceShadowmask;
QualitySettings.blendWeights = BlendWeights.FourBones;
QualitySettings.vSyncCount = 1;
QualitySettings.lodBias = 2;
QualitySettings.maximumLODLevel = 0;
QualitySettings.particleRaycastBudget = 4096;
QualitySettings.asyncUploadTimeSlice = 2;
QualitySettings.asyncUploadBufferSize = 4;
QualitySettings.antiAliasing = 0;
QualitySettings.SetQualityLevel( qualityNames.IndexOf("Graphic Tests"), true);
}
public void RestoreQualitySettings()
{
QualitySettings.SetQualityLevel(qualityLevel, true);
}
// the actual test
public static IEnumerator TestScene(TestFrameworkTools.TestInfo testInfo)
{
var prjRelativeGraphsPath = TestFrameworkTools.s_Path.Aggregate(TestFrameworkTools.s_RootPath, Path.Combine);
var filePath = Path.Combine(prjRelativeGraphsPath, testInfo.relativePath);
// open the scene
EditorSceneManager.OpenScene(filePath);
SetupSceneForRenderPipelineTest testSetup = Object.FindObjectOfType<SetupSceneForRenderPipelineTest> ();
Assert.IsNotNull(testSetup, "No SetupSceneForRenderPipelineTest in scene " + testInfo.name);
Assert.IsNotNull(testSetup.cameraToUse, "No configured camera in <SetupSceneForRenderPipelineTest>");
if (testSetup.renderPipelines == null || testSetup.renderPipelines.Length == 0)
yield break;
for (int r = 0; r < (doOnlyFirstRenderPipelineAsset?1:testSetup.renderPipelines.Length); ++r)
{
if (r==0)
testSetup.Setup();
else
testSetup.Setup(r);
for (int i = 0; i < testInfo.frameWait; ++i)
{
yield return null;
}
while (UnityEditor.Lightmapping.isRunning)
{
yield return null;
}
// Force rendering of all realtime reflection probes
ReflectionProbe[] probes = GameObject.FindObjectsOfType<ReflectionProbe>();
int[] renderIDs = new int[probes.Length];
for (int i = 0; i < probes.Length; ++i)
{
if (probes[i].mode == UnityEngine.Rendering.ReflectionProbeMode.Realtime)
renderIDs[i] = probes[i].RenderProbe();
else
renderIDs[i] = -1;
}
for (int i = 0; i < probes.Length; ++i)
{
if (renderIDs[i] != -1)
{
while (!probes[i].IsFinishedRendering(renderIDs[i])) yield return null;
}
}
testSetup.thingToDoBeforeTest.Invoke();
// Render the camera
Texture2D captured = TestFrameworkTools.RenderSetupToTexture(testSetup);
// Load the template
Texture2D fromDisk = new Texture2D(2, 2);
string dumpFileLocation = "";
if (!TestFrameworkTools.FindReferenceImage(testInfo, ref fromDisk, captured, ref dumpFileLocation))
Assert.Fail("Template file not found for {0}, creating it at {1}.", testInfo.name, dumpFileLocation);
// Compare
var areEqual = TestFrameworkTools.CompareTextures(fromDisk, captured, testInfo.threshold);
if (!areEqual)
{
var failedPath = Path.Combine(Directory.GetParent(Application.dataPath).ToString(), "SRP_Failed");
Directory.CreateDirectory(failedPath);
var misMatchLocationResult = Path.Combine(failedPath, string.Format("{0}.{1}", testInfo.name, "png"));
var misMatchLocationTemplate = Path.Combine(failedPath, string.Format("{0}.template.{1}", testInfo.name, "png"));
// Add associated renderpipeline label image if it exists
string rpLabelPath = AssetDatabase.GetAssetPath(testSetup.renderPipelines[r]);
Texture2D rpLabel = AssetDatabase.LoadAssetAtPath<Texture2D>(rpLabelPath.Remove(rpLabelPath.Length - 5)+"png");
if (rpLabel != null)
{
Color[] rpLabelPixels = rpLabel.GetPixels();
Color[] targetPixels = captured.GetPixels(0, 0, rpLabel.width, rpLabel.height);
for (int p = 0; p < rpLabelPixels.Length; ++p)
{
targetPixels[p] = Color.Lerp(targetPixels[p], rpLabelPixels[p], rpLabelPixels[p].a);
targetPixels[p].a = 1f;
}
captured.SetPixels(0, 0, rpLabel.width, rpLabel.height, targetPixels);
captured.Apply();
}
var generated = captured.EncodeToPNG();
File.WriteAllBytes(misMatchLocationResult, generated);
File.Copy(dumpFileLocation, misMatchLocationTemplate, true);
Object.DestroyImmediate(captured);
}
Assert.IsTrue(areEqual, "Scene from {0}, did not match .template file.", testInfo.relativePath);
if (!areEqual) // No need to continue the test on other renderpipelines, it would overwrite the fail capture
{
testSetup.TearDown();
yield break;
}
}
testSetup.TearDown();
}
// Graphic Tests Subclasses that inherit the functions bot provide different SRP_ID
public class HDRP : GraphicsTests
{
public override string _SRP_ID { get { return "HDRP"; } }
[UnityTest]
public IEnumerator HDRP_Test([ValueSource(typeof(TestFrameworkTools.CollectScenes), "HDRP")]TestFrameworkTools.TestInfo testInfo)
{
return TestScene(testInfo);
}
}
public class LWRP : GraphicsTests
{
public override string _SRP_ID { get { return "LWRP"; } }
[UnityTest]
public IEnumerator LWRP_Test([ValueSource(typeof(TestFrameworkTools.CollectScenes), "LWRP")]TestFrameworkTools.TestInfo testInfo)
{
return TestScene(testInfo);
}
}
}
}