123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- using System.Linq;
- using System.IO;
- using NUnit.Framework;
- using UnityEngine;
- using UnityEditor.Graphing;
-
- namespace UnityEditor.ShaderGraph.UnitTests
- {
- [TestFixture]
- class TargetTests
- {
- [OneTimeSetUp]
- public void RunBeforeAnyTests()
- {
- Debug.unityLogger.logHandler = new ConsoleLogHandler();
- }
-
- [Test]
- public void CanCreateBlankGraph()
- {
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- Assert.IsNotNull(graph.activeTargets);
- Assert.AreEqual(0, graph.activeTargets.Count());
- }
-
- public static bool s_ForceVFXFakeTargetVisible = false;
- #if !VFX_GRAPH_10_0_0_OR_NEWER
- //A barebone VFXTarget for testing coverage.
- sealed class VFXTarget : UnityEditor.ShaderGraph.Target
- {
- public VFXTarget()
- {
- displayName = "Fake VFX Target"; //Should not be displayed outside the test runner.
- isHidden = !s_ForceVFXFakeTargetVisible;
- }
-
- public override void GetActiveBlocks(ref UnityEditor.ShaderGraph.TargetActiveBlockContext context)
- {
- context.AddBlock(ShaderGraph.BlockFields.SurfaceDescription.BaseColor);
- context.AddBlock(ShaderGraph.BlockFields.SurfaceDescription.Alpha);
- }
-
- public override void GetFields(ref TargetFieldContext context)
- {
- }
-
- public override void Setup(ref TargetSetupContext context)
- {
- }
-
- public override bool IsActive() => false;
- public override bool WorksWithSRP(UnityEngine.Rendering.RenderPipelineAsset scriptableRenderPipeline)
- {
- return false;
- }
-
- public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, System.Action onChange, System.Action<System.String> registerUndo)
- {
- }
- }
- #endif
-
- [Test]
- public void CanInitializeOutputTargets()
- {
- s_ForceVFXFakeTargetVisible = true;
- GraphData graph = new GraphData();
- graph.AddContexts();
- graph.InitializeOutputs(new[] { new VFXTarget() }, null);
-
- Assert.IsNotNull(graph.activeTargets);
- Assert.AreEqual(1, graph.activeTargets.Count());
- Assert.AreEqual(typeof(VFXTarget), graph.activeTargets.ElementAt(0).GetType());
- s_ForceVFXFakeTargetVisible = false;
- }
-
- [Test]
- public void CanAddTarget()
- {
- s_ForceVFXFakeTargetVisible = true;
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- var vfxTarget = graph.allPotentialTargets.FirstOrDefault(x => x is VFXTarget);
- graph.SetTargetActive(vfxTarget);
-
- Assert.IsNotNull(graph.activeTargets);
- Assert.AreEqual(1, graph.activeTargets.Count());
- Assert.AreEqual(vfxTarget, graph.activeTargets.ElementAt(0));
- s_ForceVFXFakeTargetVisible = false;
- }
-
- [Test]
- public void ActiveTargetsArePotentialTargets()
- {
- s_ForceVFXFakeTargetVisible = true;
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- var vfxTarget = new VFXTarget();
- graph.SetTargetActive(vfxTarget);
- Assert.IsTrue(graph.allPotentialTargets.Contains(vfxTarget));
-
- s_ForceVFXFakeTargetVisible = false;
- }
-
- [Test]
- public void GetTargetIndexWorks()
- {
- s_ForceVFXFakeTargetVisible = true;
-
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- int targetIndex = graph.GetTargetIndexByKnownType(typeof(VFXTarget));
- Assert.IsTrue(targetIndex >= 0);
-
- var vfxTarget = new VFXTarget();
- graph.SetTargetActive(vfxTarget);
-
- var targetIndex2 = graph.GetTargetIndex(vfxTarget);
- Assert.AreEqual(targetIndex, targetIndex2);
-
- var nonActiveVFXTarget = new VFXTarget();
- Assert.AreEqual(-1, graph.GetTargetIndex(nonActiveVFXTarget));
-
- s_ForceVFXFakeTargetVisible = false;
- }
-
- [Test]
- public void CanRemoveTarget()
- {
- s_ForceVFXFakeTargetVisible = true;
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- var vfxTarget = new VFXTarget();
- graph.InitializeOutputs(new[] { vfxTarget }, null);
-
- graph.SetTargetInactive(vfxTarget);
-
- Assert.IsNotNull(graph.activeTargets);
- Assert.AreEqual(0, graph.activeTargets.Count());
- s_ForceVFXFakeTargetVisible = false;
- }
-
- [Test]
- public void CanSetBlockActive()
- {
- s_ForceVFXFakeTargetVisible = true;
- GraphData graph = new GraphData();
- graph.AddContexts();
- graph.InitializeOutputs(new[] { new VFXTarget() }, new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.BaseColor, BlockFields.SurfaceDescription.NormalTS });
-
- // Block active state should match VFX Target's default GetActiveBlocks
- var blocks = graph.GetNodes<BlockNode>().ToList();
- Assert.AreEqual(2, blocks.Count);
- Assert.AreEqual(BlockFields.SurfaceDescription.BaseColor, blocks[0].descriptor);
- Assert.AreEqual(true, blocks[0].isActive);
- Assert.AreEqual(BlockFields.SurfaceDescription.NormalTS, blocks[1].descriptor);
- Assert.AreEqual(false, blocks[1].isActive);
- s_ForceVFXFakeTargetVisible = false;
- }
-
- [Test]
- public void CanUpdateBlockActiveState()
- {
- s_ForceVFXFakeTargetVisible = true;
- GraphData graph = new GraphData();
- graph.AddContexts();
- graph.InitializeOutputs(new[] { new VFXTarget() }, new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.BaseColor, BlockFields.SurfaceDescription.NormalTS });
-
- // Remove VFX target
- var vfxTarget = graph.allPotentialTargets.FirstOrDefault(x => x is VFXTarget);
- graph.SetTargetInactive(vfxTarget);
-
- var activeBlocks = graph.GetActiveBlocksForAllActiveTargets();
- graph.UpdateActiveBlocks(activeBlocks);
-
- // All blocks should be inactive as there are no active targets
- var blocks = graph.GetNodes<BlockNode>().ToList();
- Assert.AreEqual(2, blocks.Count);
- Assert.AreEqual(BlockFields.SurfaceDescription.BaseColor, blocks[0].descriptor);
- Assert.AreEqual(false, blocks[0].isActive);
- Assert.AreEqual(BlockFields.SurfaceDescription.NormalTS, blocks[1].descriptor);
- Assert.AreEqual(false, blocks[1].isActive);
- s_ForceVFXFakeTargetVisible = false;
- }
-
- abstract class TestShaderTarget : UnityEditor.ShaderGraph.Target
- {
- public override void GetActiveBlocks(ref UnityEditor.ShaderGraph.TargetActiveBlockContext context)
- {
- context.AddBlock(ShaderGraph.BlockFields.SurfaceDescription.BaseColor);
- context.AddBlock(ShaderGraph.BlockFields.SurfaceDescription.Alpha);
- }
-
- public override void GetFields(ref TargetFieldContext context)
- {
- }
-
- public static PassDescriptor BuildPass()
- {
- PassDescriptor pass = new PassDescriptor()
- {
- // Definition
- displayName = "DepthOnly",
- referenceName = "SHADERPASS_DEPTHONLY",
- lightMode = "DepthOnly",
- useInPreview = true,
-
- // Template
- passTemplatePath = "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Templates/ShaderPass.template",
- sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(),
-
- // Port Mask
- validVertexBlocks = new BlockFieldDescriptor[] { BlockFields.VertexDescription.Position, BlockFields.VertexDescription.Normal, BlockFields.VertexDescription.Tangent },
- validPixelBlocks = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.Alpha, BlockFields.SurfaceDescription.AlphaClipThreshold },
-
- // Fields
- structs = new StructCollection { { Structs.Attributes }, { Structs.SurfaceDescriptionInputs }, { Structs.VertexDescriptionInputs } },
- fieldDependencies = FieldDependencies.Default,
-
- // Conditional State
- renderStates = null,
- pragmas = new PragmaCollection { { Pragma.Target(ShaderModel.Target30) }, { Pragma.MultiCompileInstancing }, { Pragma.Vertex("vert") }, { Pragma.Fragment("frag") } },
- defines = null,
- keywords = null,
- includes = null,
- customInterpolators = null,
- };
- return pass;
- }
-
- public static SubShaderDescriptor BuildSubShader()
- {
- SubShaderDescriptor result = new SubShaderDescriptor()
- {
- pipelineTag = "TestPipeline",
- renderType = "Opaque",
- renderQueue = "Geometry",
- generatesPreview = true,
- passes = new PassCollection()
- };
- result.passes.Add(BuildPass());
- return result;
- }
-
- public override bool IsActive() => true;
-
- public override bool WorksWithSRP(UnityEngine.Rendering.RenderPipelineAsset scriptableRenderPipeline) => true;
-
- public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, System.Action onChange, System.Action<System.String> registerUndo)
- {
- }
- }
-
- sealed class MultiShaderTarget : TestShaderTarget
- {
- public MultiShaderTarget()
- {
- displayName = "MultiShader Test Target";
- isHidden = false;
- }
-
- public override void Setup(ref TargetSetupContext context)
- {
- context.AddSubShader(BuildSubShader()); // primary shader
- var ss2 = BuildSubShader();
- ss2.additionalShaderID = "{Name}-second";
- context.AddSubShader(ss2);
- }
- }
-
- [Test]
- public void CanBuildMultipleShaders()
- {
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- var multiTarget = new MultiShaderTarget();
- graph.SetTargetActive(multiTarget);
- Assert.IsTrue(graph.allPotentialTargets.Contains(multiTarget));
-
- graph.OnEnable();
- graph.ValidateGraph();
-
- var generator = new Generator(graph, graph.outputNode, GenerationMode.ForReals, "MyTestShader");
- var generatedShaders = generator.allGeneratedShaders.ToList();
-
- Assert.AreEqual(2, generatedShaders.Count);
- Assert.IsTrue(generatedShaders[0].shaderName == "MyTestShader");
- Assert.IsTrue(generatedShaders[1].shaderName == "MyTestShader-second");
- Assert.IsTrue(generatedShaders[0].codeString.Contains("Shader \"MyTestShader\""));
- Assert.IsTrue(generatedShaders[1].codeString.Contains("Shader \"MyTestShader-second\""));
-
- // save graph to file on disk and import it...
- var path = AssetDatabase.GenerateUniqueAssetPath("Assets/multiShaderTest.ShaderGraph");
- FileUtilities.WriteShaderGraphToDisk(path, graph);
-
- AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate | ImportAssetOptions.DontDownloadFromCacheServer);
-
- // check that we actually have two shader assets in the import result
- // (they won't work, but they should exist)
- var assets = AssetDatabase.LoadAllAssetsAtPath(path);
- int shaderCount = assets.OfType<Shader>().Count();
- Assert.AreEqual(2, shaderCount);
-
- AssetDatabase.DeleteAsset(path);
- }
-
- sealed class DependencyShaderNameTarget : TestShaderTarget
- {
- public DependencyShaderNameTarget()
- {
- displayName = "DependencyShaderName Test Target";
- isHidden = false;
- }
-
- public override void Setup(ref TargetSetupContext context)
- {
- var ss = BuildSubShader();
- ss.shaderDependencies = new()
- {
- new ShaderDependency() { dependencyName = "TestDep1", shaderName = "Name-blah" },
- new ShaderDependency() { dependencyName = "TestDep2", shaderName = "{Name}-blah" }
- };
- context.AddSubShader(ss);
- }
- }
-
- [Test]
- public void ShaderNamesAreCorrectReplacedForDependencies()
- {
- GraphData graph = new GraphData();
- graph.AddContexts();
-
- var testTarget = new DependencyShaderNameTarget();
- graph.SetTargetActive(testTarget);
- graph.OnEnable();
- graph.ValidateGraph();
-
- var generator = new Generator(graph, graph.outputNode, GenerationMode.ForReals, "MyTestShader");
- var shaderCodeString = generator.generatedShader;
- Assert.IsTrue(shaderCodeString.Contains("Dependency \"TestDep1\" = \"Name-blah\""));
- Assert.IsTrue(shaderCodeString.Contains("Dependency \"TestDep2\" = \"MyTestShader-blah\""));
- }
- }
- }
|