protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext) { var material = asset.Material.Clone(); // Replace all empty Texture nodes by black color texture nodes (allow a display of the element even if material is incomplete) var emptyTextureNodeKeys = material.Nodes.Where(m => m.Value is MaterialTextureNode && !IsTextureReferenceValid((MaterialTextureNode)m.Value)).Select(m => m.Key).ToList(); foreach (var emptyTextureNodeKey in emptyTextureNodeKeys) { commandContext.Logger.Warning("Texture node '{0}' of material '{1}' is not pointing to a valid texture reference. " + "This node will be replaced by black color Node.", emptyTextureNodeKey, assetItem.Location); material.Nodes[emptyTextureNodeKey] = new MaterialColorNode(new Color4(0)); } // Reduce trees on CPU var materialReducer = new MaterialTreeReducer(material); materialReducer.ReduceTrees(); foreach (var reducedTree in materialReducer.ReducedTrees) { material.Nodes[reducedTree.Key] = reducedTree.Value; } // Reduce on GPU // TODO: Adapt GPU reduction so that it is compatible Android color/alpha separation // TODO: Use the build engine processed output textures instead of the imported one (not existing any more) // TODO: Set the reduced texture output format // TODO: The graphics device cannot be shared with the Previewer //var graphicsDevice = (GraphicsDevice)context.Attributes.GetOrAdd(CompilerContext.GraphicsDeviceKey, key => GraphicsDevice.New(DeviceCreationFlags.None, GraphicsProfile.Level_11_0)); //using (var materialTextureLayerFlattener = new MaterialTextureLayerFlattener(material, graphicsDevice)) //{ // materialTextureLayerFlattener.PrepareForFlattening(new UDirectory(assetUrl.Directory)); // if (materialTextureLayerFlattener.HasCommands) // { // var compiler = EffectCompileCommand.GetOrCreateEffectCompiler(context); // materialTextureLayerFlattener.Run(compiler); // // store Material with modified textures // material = materialTextureLayerFlattener.Material; // } //} // Separate the textures into color/alpha components on Android to be able to use native ETC1 compression if (context.Platform == PlatformType.Android) { var alphaComponentSplitter = new TextureAlphaComponentSplitter(assetItem.Package.Session); material = alphaComponentSplitter.Run(material, new UDirectory(assetUrl.GetDirectory())); // store Material with alpha substituted textures } // Create the parameters var materialParameterCreator = new MaterialParametersCreator(material, assetUrl); if (materialParameterCreator.CreateParameterCollectionData(commandContext.Logger)) { return(Task.FromResult(ResultStatus.Failed)); } var materialData = new MaterialData { Parameters = materialParameterCreator.Parameters }; var assetManager = new AssetManager(); assetManager.Save(assetUrl, materialData); return(Task.FromResult(ResultStatus.Successful)); }
public void TestSplitTexture() { var sessionResult = PackageSession.Load("../../sources/engine/SiliconStudio.Paradox.Assets.Tests/SiliconStudio.Paradox.Assets.Tests.pdxpkg"); var session = sessionResult.Session; var materialItem = session.FindAsset("Cube/TestMaterial"); var material = (MaterialAsset)materialItem.Asset; var solver = new TextureAlphaComponentSplitter(session); var modifiedMaterial = solver.Run(material.Material, materialItem.Location.GetDirectory()); Assert.AreEqual(3, modifiedMaterial.Nodes.Count); Assert.AreEqual(1, modifiedMaterial.ColorNodes.Count); // test that the original structure of the material hasn't changed var originalRootNode = modifiedMaterial.Nodes[modifiedMaterial.ColorNodes.First().Value]; Assert.IsTrue(originalRootNode is MaterialBinaryNode); var originalBinaryRootNode = (MaterialBinaryNode)originalRootNode; Assert.AreEqual((int)MaterialBinaryOperand.Overlay, (int)originalBinaryRootNode.Operand); Assert.IsTrue(originalBinaryRootNode.LeftChild is MaterialBinaryNode); Assert.IsTrue(originalBinaryRootNode.RightChild is MaterialBinaryNode); var originalRootLeftChildNode = (MaterialBinaryNode)originalBinaryRootNode.LeftChild; var originalRootRightChildNode = (MaterialBinaryNode)originalBinaryRootNode.RightChild; Assert.AreEqual((int)MaterialBinaryOperand.Screen, (int)originalRootLeftChildNode.Operand); Assert.AreEqual((int)MaterialBinaryOperand.Saturate, (int)originalRootRightChildNode.Operand); Assert.IsTrue(originalRootLeftChildNode.LeftChild is MaterialReferenceNode); Assert.IsTrue(originalRootLeftChildNode.RightChild is MaterialReferenceNode); Assert.IsTrue(originalRootRightChildNode.RightChild is MaterialFloat4Node); var originalRootLeftLeftChildNode = (MaterialReferenceNode)originalRootLeftChildNode.LeftChild; var originalRootLeftRightChildNode = (MaterialReferenceNode)originalRootLeftChildNode.RightChild; var originalRootRightLeftChildNode = originalRootRightChildNode.LeftChild; var originalRootRightRightChildNode = (MaterialFloat4Node)originalRootRightChildNode.RightChild; Assert.AreEqual("diffuseFactor", originalRootLeftLeftChildNode.Name); Assert.AreEqual("diffuseTexture", originalRootLeftRightChildNode.Name); var rawUnreferencedRootLeftLeftChildNode = modifiedMaterial.Nodes["diffuseFactor"]; var rawUnreferencedRootLeftRightChildNode = modifiedMaterial.Nodes["diffuseTexture"]; Assert.IsTrue(rawUnreferencedRootLeftLeftChildNode is MaterialFloat4Node); var unreferencedRootLeftLeftChildNode = (MaterialFloat4Node)rawUnreferencedRootLeftLeftChildNode; var unreferencedRootLeftRightChildNode = rawUnreferencedRootLeftRightChildNode; Assert.AreEqual(new Vector4(0.1f, 0.2f, 0.3f, 0.4f), unreferencedRootLeftLeftChildNode.Value); Assert.AreEqual(new Vector4(1f, 2f, 3f, 4f), originalRootRightRightChildNode.Value); var originalTextureNodes = new List<MaterialTextureNode> { (MaterialTextureNode)((MaterialBinaryNode)((MaterialBinaryNode)material.Material.Nodes["diffuse"]).RightChild).LeftChild, (MaterialTextureNode)material.Material.Nodes["diffuseTexture"] }; var modifiedTextureNodes = new List<IMaterialNode> { originalRootRightLeftChildNode, unreferencedRootLeftRightChildNode }; // test that the old MaterialTextureReferences has been substituted for (int i = 0; i < originalTextureNodes.Count; i++) { var originalTextureNode = originalTextureNodes[i]; var modifiedTextureNode = modifiedTextureNodes[i]; Assert.IsTrue(modifiedTextureNode is MaterialShaderClassNode); var newShaderNode = (MaterialShaderClassNode)modifiedTextureNode; Assert.AreEqual("ComputeColorSubstituteAlphaWithColor", Path.GetFileNameWithoutExtension(newShaderNode.MixinReference.Location)); Assert.IsTrue(newShaderNode.CompositionNodes.ContainsKey("color1")); Assert.IsTrue(newShaderNode.CompositionNodes.ContainsKey("color2")); Assert.IsTrue(newShaderNode.CompositionNodes["color1"] is MaterialTextureNode); Assert.IsTrue(newShaderNode.CompositionNodes["color2"] is MaterialTextureNode); var leftNode = (MaterialTextureNode)newShaderNode.CompositionNodes["color1"]; var rightNode = (MaterialTextureNode)newShaderNode.CompositionNodes["color2"]; var textureNodes = new List<MaterialTextureNode> { leftNode, rightNode }; foreach (var textureNode in textureNodes) { Assert.AreEqual(originalTextureNode.Sampler.AddressModeU, textureNode.Sampler.AddressModeU); Assert.AreEqual(originalTextureNode.Sampler.AddressModeV, textureNode.Sampler.AddressModeV); Assert.AreEqual(originalTextureNode.Sampler.Filtering, textureNode.Sampler.Filtering); Assert.AreEqual(originalTextureNode.Offset, textureNode.Offset); Assert.AreEqual(originalTextureNode.Sampler.SamplerParameterKey, textureNode.Sampler.SamplerParameterKey); Assert.AreEqual(originalTextureNode.Scale, textureNode.Scale); Assert.AreEqual(originalTextureNode.TexcoordIndex, textureNode.TexcoordIndex); } Assert.AreEqual(originalTextureNode.Key, leftNode.Key); Assert.AreEqual(null, rightNode.Key); const string textureName = "cube_Untitled"; const string leftNodeSupposedLocation = "Cube/" + TextureAlphaComponentSplitter.SplittedTextureNamePrefix + textureName + TextureAlphaComponentSplitter.SplittedColorTextureNameSuffix; const string rightNodeSupposedLocation = "Cube/" + TextureAlphaComponentSplitter.SplittedTextureNamePrefix + textureName + TextureAlphaComponentSplitter.SplittedAlphaTextureNameSuffix; Assert.AreEqual(leftNodeSupposedLocation, leftNode.TextureName); Assert.AreEqual(rightNodeSupposedLocation, rightNode.TextureName); Assert.IsTrue(AssetManager.FileProvider.FileExists(leftNodeSupposedLocation)); Assert.IsTrue(AssetManager.FileProvider.FileExists(rightNodeSupposedLocation)); } }