/// <summary> /// Simple Visual Comparison. /// </summary> /// <returns></returns> public bool CompareImage() { DispatcherHelper.DoEvents(1000); MasterImageComparer comparer = new MasterImageComparer(index); comparer.ToleranceSettings = ImageComparisonSettings.CreateCustomTolerance(DefaultTolerance()); return(comparer.Compare(HWND)); }
public void PerPixelTest(ImageComparisonSettings settings, Color32 initColor, Color32 alterColor, int alterCount, bool mustThrow) { int w = settings.TargetWidth; int h = settings.TargetHeight; int count = w * h; var exp = new Texture2D(w, h); var act = new Texture2D(w, h); var pixels = new Color32[count]; for (int i = 0; i < pixels.Length; ++i) { pixels[i] = initColor; } exp.SetPixels32(pixels); exp.Apply(); // Spread the bad pixels. Assume.That(alterCount >= 0 && alterCount <= count); int alterPeriod = Mathf.RoundToInt(Mathf.Clamp(alterCount * 0.95f / count, 1f, alterCount)); int alterNext = 0; while (alterCount > 0) { pixels[alterNext] = alterColor; --alterCount; alterNext += alterPeriod; } act.SetPixels32(pixels); act.Apply(); try { if (mustThrow) { Assert.That(() => ImageAssert.AreEqual(exp, act, settings), Throws.InstanceOf <AssertionException>()); } else { Assert.That(() => ImageAssert.AreEqual(exp, act, settings), Throws.Nothing); } } finally { Object.DestroyImmediate(exp); Object.DestroyImmediate(act); } }
/// <summary> /// TEMP /// </summary> /// <param name="videoGroup"></param> /// <param name="tolerance"></param> /// <param name="masterName"></param> public bool CompareImage(string videoGroup, string tolerance, string masterName) { if (masterName != "none" || masterName != string.Empty || masterName != null) { index.FileName = masterName; } MasterImageComparer comparer = new MasterImageComparer(index); comparer.ResizeWindowForDpi = resizeWindowForDpi; if (tolerance == null || tolerance == string.Empty) { comparer.ToleranceSettings = ImageComparisonSettings.CreateCustomTolerance(DefaultTolerance()); } else { XmlDocument customTolerance = new XmlDocument(); customTolerance.LoadXml(tolerance); ImageComparisonSettings.CreateCustomTolerance((XmlNode)customTolerance.DocumentElement); } return(comparer.Compare(HWND)); }
[Timeout(450 * 1000)] // Increase timeout to handle complex scenes with many shaders and XR variants public IEnumerator Run(GraphicsTestCase testCase) { #if UNITY_EDITOR while (SceneView.sceneViews.Count > 0) { var sceneView = SceneView.sceneViews[0] as SceneView; sceneView.Close(); } #endif SceneManagement.SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var testSettingsInScene = Object.FindObjectOfType <GraphicsTestSettings>(); var vfxTestSettingsInScene = Object.FindObjectOfType <VFXGraphicsTestSettings>(); var imageComparisonSettings = new ImageComparisonSettings() { AverageCorrectnessThreshold = VFXGraphicsTestSettings.defaultAverageCorrectnessThreshold }; if (testSettingsInScene != null) { imageComparisonSettings = testSettingsInScene.ImageComparisonSettings; } if (XRGraphicsAutomatedTests.enabled) { bool xrCompatible = vfxTestSettingsInScene != null ? vfxTestSettingsInScene.xrCompatible : true; Unity.Testing.XR.Runtime.ConfigureMockHMD.SetupTest(xrCompatible, 0, imageComparisonSettings); } //Setup frame rate capture float simulateTime = VFXGraphicsTestSettings.defaultSimulateTime; int captureFrameRate = VFXGraphicsTestSettings.defaultCaptureFrameRate; float fixedTimeStepScale = VFXGraphicsTestSettings.defaultFixedTimeStepScale; if (vfxTestSettingsInScene != null) { simulateTime = vfxTestSettingsInScene.simulateTime; captureFrameRate = vfxTestSettingsInScene.captureFrameRate; fixedTimeStepScale = vfxTestSettingsInScene.fixedTimeStepScale; } float period = 1.0f / captureFrameRate; Time.captureFramerate = captureFrameRate; UnityEngine.VFX.VFXManager.fixedTimeStep = period * fixedTimeStepScale; UnityEngine.VFX.VFXManager.maxDeltaTime = period; //Waiting for the capture frame rate to be effective const int maxFrameWaiting = 8; int maxFrame = maxFrameWaiting; while (Time.deltaTime != period && maxFrame-- > 0) { yield return(new WaitForEndOfFrame()); } Assert.Greater(maxFrame, 0); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera) { var vfxComponents = Resources.FindObjectsOfTypeAll <VisualEffect>(); var rt = RenderTexture.GetTemporary(imageComparisonSettings.TargetWidth, imageComparisonSettings.TargetHeight, 24); camera.targetTexture = rt; //Waiting for the rendering to be ready, if at least one component has been culled, camera is ready maxFrame = maxFrameWaiting; while (vfxComponents.All(o => o.culled) && maxFrame-- > 0) { yield return(new WaitForEndOfFrame()); } Assert.Greater(maxFrame, 0); foreach (var component in vfxComponents) { component.Reinit(); } #if UNITY_EDITOR //When we change the graph, if animator was already enable, we should reinitialize animator to force all BindValues var animators = Resources.FindObjectsOfTypeAll <Animator>(); foreach (var animator in animators) { animator.Rebind(); } var audioSources = Resources.FindObjectsOfTypeAll <AudioSource>(); #endif var paramBinders = Resources.FindObjectsOfTypeAll <VFXPropertyBinder>(); foreach (var paramBinder in paramBinders) { var binders = paramBinder.GetPropertyBinders <VFXBinderBase>(); foreach (var binder in binders) { binder.Reset(); } } if (XRGraphicsAutomatedTests.running) { camera.targetTexture = null; } int waitFrameCount = (int)(simulateTime / period); int startFrameIndex = Time.frameCount; int expectedFrameIndex = startFrameIndex + waitFrameCount; while (Time.frameCount != expectedFrameIndex) { yield return(new WaitForEndOfFrame()); #if UNITY_EDITOR foreach (var audioSource in audioSources) { if (audioSource.clip != null && audioSource.playOnAwake) { audioSource.PlayDelayed(Mathf.Repeat(simulateTime, audioSource.clip.length)); } } #endif } try { camera.targetTexture = null; ImageAssert.AreEqual(testCase.ReferenceImage, camera, imageComparisonSettings); } finally { RenderTexture.ReleaseTemporary(rt); } } }
public IEnumerator Run(GraphicsTestCase testCase) { #if UNITY_EDITOR while (SceneView.sceneViews.Count > 0) { var sceneView = SceneView.sceneViews[0] as SceneView; sceneView.Close(); } #endif SceneManagement.SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera) { var vfxComponents = Resources.FindObjectsOfTypeAll <VisualEffect>(); #if UNITY_EDITOR var vfxAssets = vfxComponents.Select(o => o.visualEffectAsset).Where(o => o != null).Distinct(); foreach (var vfx in vfxAssets) { //Use Reflection as workaround of the access issue in .net 4 (TODO : Clean this as soon as possible) //var graph = vfx.GetResource().GetOrCreateGraph(); is possible with .net 3.5 but compilation fail with 4.0 var visualEffectAssetExt = AppDomain.CurrentDomain.GetAssemblies().Select(o => o.GetType("UnityEditor.VFX.VisualEffectAssetExtensions")) .Where(o => o != null) .FirstOrDefault(); var fnGetResource = visualEffectAssetExt.GetMethod("GetResource"); fnGetResource = fnGetResource.MakeGenericMethod(new Type[] { typeof(VisualEffectAsset) }); var resource = fnGetResource.Invoke(null, new object[] { vfx }); var fnGetOrCreate = visualEffectAssetExt.GetMethod("GetOrCreateGraph"); var graph = fnGetOrCreate.Invoke(null, new object[] { resource }) as VFXGraph; graph.RecompileIfNeeded(); } #endif var rt = RenderTexture.GetTemporary(captureSize, captureSize, 24); camera.targetTexture = rt; foreach (var component in vfxComponents) { component.Reinit(); } #if UNITY_EDITOR //When we change the graph, if animator was already enable, we should reinitialize animator to force all BindValues var animators = Resources.FindObjectsOfTypeAll <Animator>(); foreach (var animator in animators) { animator.Rebind(); } var audioSources = Resources.FindObjectsOfTypeAll <AudioSource>(); #endif var paramBinders = Resources.FindObjectsOfTypeAll <VFXPropertyBinder>(); foreach (var paramBinder in paramBinders) { var binders = paramBinder.GetParameterBinders <VFXBinderBase>(); foreach (var binder in binders) { binder.Reset(); } } int waitFrameCount = (int)(simulateTime / frequency); int startFrameIndex = Time.frameCount; int expectedFrameIndex = startFrameIndex + waitFrameCount; while (Time.frameCount != expectedFrameIndex) { yield return(null); #if UNITY_EDITOR foreach (var audioSource in audioSources) { if (audioSource.clip != null && audioSource.playOnAwake) { audioSource.PlayDelayed(Mathf.Repeat(simulateTime, audioSource.clip.length)); } } #endif } Texture2D actual = null; try { camera.targetTexture = null; actual = new Texture2D(captureSize, captureSize, TextureFormat.RGB24, false); RenderTexture.active = rt; actual.ReadPixels(new Rect(0, 0, captureSize, captureSize), 0, 0); RenderTexture.active = null; actual.Apply(); var imageComparisonSettings = new ImageComparisonSettings() { AverageCorrectnessThreshold = 5e-4f }; var testSettingsInScene = Object.FindObjectOfType <GraphicsTestSettings>(); if (testSettingsInScene != null) { imageComparisonSettings.AverageCorrectnessThreshold = testSettingsInScene.ImageComparisonSettings.AverageCorrectnessThreshold; } if (!ExcludedTestsButKeepLoadScene.Any(o => testCase.ScenePath.Contains(o)) && !(SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal && UnstableMetalTests.Any(o => testCase.ScenePath.Contains(o)))) { ImageAssert.AreEqual(testCase.ReferenceImage, actual, imageComparisonSettings); } else { Debug.LogFormat("GraphicTest '{0}' result has been ignored", testCase.ReferenceImage); } } finally { RenderTexture.ReleaseTemporary(rt); if (actual != null) { UnityEngine.Object.Destroy(actual); } } } }
public IEnumerator Run(GraphicsTestCase testCase) { #if UNITY_EDITOR while (SceneView.sceneViews.Count > 0) { var sceneView = SceneView.sceneViews[0] as SceneView; sceneView.Close(); } #endif SceneManagement.SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var testSettingsInScene = Object.FindObjectOfType <GraphicsTestSettings>(); var vfxTestSettingsInScene = Object.FindObjectOfType <VFXGraphicsTestSettings>(); if (XRGraphicsAutomatedTests.enabled) { if (vfxTestSettingsInScene == null || vfxTestSettingsInScene.xrCompatible) { XRGraphicsAutomatedTests.running = true; } else { Assert.Ignore("Test scene is not compatible with XR and will be skipped."); } } //Setup frame rate capture float simulateTime = VFXGraphicsTestSettings.defaultSimulateTime; int captureFrameRate = VFXGraphicsTestSettings.defaultCaptureFrameRate; if (vfxTestSettingsInScene != null) { simulateTime = vfxTestSettingsInScene.simulateTime; captureFrameRate = vfxTestSettingsInScene.captureFrameRate; } float period = 1.0f / captureFrameRate; Time.captureFramerate = captureFrameRate; UnityEngine.VFX.VFXManager.fixedTimeStep = period; UnityEngine.VFX.VFXManager.maxDeltaTime = period; //Waiting for the capture frame rate to be effective const int maxFrameWaiting = 8; int maxFrame = maxFrameWaiting; while (Time.deltaTime != period && maxFrame-- > 0) { yield return(null); } Assert.Greater(maxFrame, 0); int captureSizeWidth = 512; int captureSizeHeight = 512; if (testSettingsInScene != null) { captureSizeWidth = testSettingsInScene.ImageComparisonSettings.TargetWidth; captureSizeHeight = testSettingsInScene.ImageComparisonSettings.TargetHeight; } var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera) { var vfxComponents = Resources.FindObjectsOfTypeAll <VisualEffect>(); var rt = RenderTexture.GetTemporary(captureSizeWidth, captureSizeHeight, 24); camera.targetTexture = rt; //Waiting for the rendering to be ready, if at least one component has been culled, camera is ready maxFrame = maxFrameWaiting; while (vfxComponents.All(o => o.culled) && maxFrame-- > 0) { yield return(null); } Assert.Greater(maxFrame, 0); foreach (var component in vfxComponents) { component.Reinit(); } #if UNITY_EDITOR //When we change the graph, if animator was already enable, we should reinitialize animator to force all BindValues var animators = Resources.FindObjectsOfTypeAll <Animator>(); foreach (var animator in animators) { animator.Rebind(); } var audioSources = Resources.FindObjectsOfTypeAll <AudioSource>(); #endif var paramBinders = Resources.FindObjectsOfTypeAll <VFXPropertyBinder>(); foreach (var paramBinder in paramBinders) { var binders = paramBinder.GetPropertyBinders <VFXBinderBase>(); foreach (var binder in binders) { binder.Reset(); } } int waitFrameCount = (int)(simulateTime / period); int startFrameIndex = Time.frameCount; int expectedFrameIndex = startFrameIndex + waitFrameCount; while (Time.frameCount != expectedFrameIndex) { yield return(null); #if UNITY_EDITOR foreach (var audioSource in audioSources) { if (audioSource.clip != null && audioSource.playOnAwake) { audioSource.PlayDelayed(Mathf.Repeat(simulateTime, audioSource.clip.length)); } } #endif } Texture2D actual = null; try { camera.targetTexture = null; actual = new Texture2D(captureSizeWidth, captureSizeHeight, TextureFormat.RGB24, false); RenderTexture.active = rt; actual.ReadPixels(new Rect(0, 0, captureSizeWidth, captureSizeHeight), 0, 0); RenderTexture.active = null; actual.Apply(); var imageComparisonSettings = new ImageComparisonSettings() { AverageCorrectnessThreshold = 5e-4f }; if (testSettingsInScene != null) { imageComparisonSettings.AverageCorrectnessThreshold = testSettingsInScene.ImageComparisonSettings.AverageCorrectnessThreshold; } ImageAssert.AreEqual(testCase.ReferenceImage, actual, imageComparisonSettings); } finally { RenderTexture.ReleaseTemporary(rt); if (actual != null) { UnityEngine.Object.Destroy(actual); } } } }