예제 #1
0
            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));
            }
        }