コード例 #1
0
        public MaterialDescription Run(MaterialDescription material, UDirectory materialPath, PixelFormat outputFormat = PixelFormat.ETC1)
        {
            if (material == null) throw new ArgumentNullException("material");

            var assetManager = new AssetManager();
            var modifiedMaterial = material.Clone();
            var textureVisitor = new MaterialTextureVisitor(modifiedMaterial);
            var nodeReplacer = new MaterialNodeReplacer(modifiedMaterial);
            var textureNodes = textureVisitor.GetAllModelTextureValues();

            foreach (var textureNode in textureNodes)
            {
                var itemAsset = assetSession.FindAsset(textureNode.TextureReference.Id);
                if(itemAsset == null)
                    throw new InvalidOperationException("The referenced texture is not included in the project session.");

                var textureAsset = (TextureAsset)itemAsset.Asset;
                if (textureAsset.Format != TextureFormat.Compressed || textureAsset.Alpha == AlphaFormat.None)
                    continue; // the texture has no alpha so there is no need to divide the texture into two sub-textures

                var originalLocation = textureNode.TextureReference.Location;

                throw new NotImplementedException("TODO: Need to reimplement this with removed data layer.");
                using (var image = assetManager.Load<Image>(originalLocation))
                {
                    CreateAndSaveSeparateTextures(image, originalLocation, textureAsset.GenerateMipmaps, outputFormat);
                    assetManager.Unload(image); // matching unload to the previous asset manager load call
                }

                // make new tree
                var colorNode = new MaterialTextureNode(GenerateColorTextureURL(originalLocation), textureNode.TexcoordIndex, Vector2.One, Vector2.Zero);
                var alphaNode = new MaterialTextureNode(GenerateAlphaTextureURL(originalLocation), textureNode.TexcoordIndex, Vector2.One, Vector2.Zero);
                var substituteAlphaNode = new MaterialShaderClassNode { MixinReference = new AssetReference<EffectShaderAsset>(Guid.Empty, "ComputeColorSubstituteAlphaWithColor") };
                substituteAlphaNode.CompositionNodes.Add("color1", colorNode);
                substituteAlphaNode.CompositionNodes.Add("color2", alphaNode);

                // set the parameters of the children so that they match the original texture
                var children = new[] { colorNode, alphaNode };
                foreach (var childTexture in children)
                {
                    childTexture.Sampler.AddressModeU = textureNode.Sampler.AddressModeU;
                    childTexture.Sampler.AddressModeV = textureNode.Sampler.AddressModeV;
                    childTexture.Sampler.Filtering = textureNode.Sampler.Filtering;
                    childTexture.Offset = textureNode.Offset;
                    childTexture.Sampler.SamplerParameterKey = textureNode.Sampler.SamplerParameterKey;
                    childTexture.Scale = textureNode.Scale;
                    childTexture.TexcoordIndex = textureNode.TexcoordIndex;
                }

                // copy the parameter key on the color and let the one of the alpha null so that it is set automatically to available value later
                colorNode.Key = textureNode.Key;
                alphaNode.Key = null;

                // update all the material references to the new node
                nodeReplacer.Replace(textureNode, substituteAlphaNode);
            }
            
            return modifiedMaterial;
        }
コード例 #2
0
        public MaterialDescription Run(MaterialDescription material, UDirectory materialPath, PixelFormat outputFormat = PixelFormat.ETC1)
        {
            if (material == null)
            {
                throw new ArgumentNullException("material");
            }

            var assetManager     = new AssetManager();
            var modifiedMaterial = material.Clone();
            var textureVisitor   = new MaterialTextureVisitor(modifiedMaterial);
            var nodeReplacer     = new MaterialNodeReplacer(modifiedMaterial);
            var textureNodes     = textureVisitor.GetAllModelTextureValues();

            foreach (var textureNode in textureNodes)
            {
                var itemAsset = assetSession.FindAsset(textureNode.TextureReference.Id);
                if (itemAsset == null)
                {
                    throw new InvalidOperationException("The referenced texture is not included in the project session.");
                }

                var textureAsset = (TextureAsset)itemAsset.Asset;
                if (textureAsset.Format != TextureFormat.Compressed || textureAsset.Alpha == AlphaFormat.None)
                {
                    continue; // the texture has no alpha so there is no need to divide the texture into two sub-textures
                }
                var originalLocation = textureNode.TextureReference.Location;

                throw new NotImplementedException("TODO: Need to reimplement this with removed data layer.");
                using (var image = assetManager.Load <Image>(originalLocation))
                {
                    CreateAndSaveSeparateTextures(image, originalLocation, textureAsset.GenerateMipmaps, outputFormat);
                    assetManager.Unload(image); // matching unload to the previous asset manager load call
                }

                // make new tree
                var colorNode           = new MaterialTextureNode(GenerateColorTextureURL(originalLocation), textureNode.TexcoordIndex, Vector2.One, Vector2.Zero);
                var alphaNode           = new MaterialTextureNode(GenerateAlphaTextureURL(originalLocation), textureNode.TexcoordIndex, Vector2.One, Vector2.Zero);
                var substituteAlphaNode = new MaterialShaderClassNode {
                    MixinReference = new AssetReference <EffectShaderAsset>(Guid.Empty, "ComputeColorSubstituteAlphaWithColor")
                };
                substituteAlphaNode.CompositionNodes.Add("color1", colorNode);
                substituteAlphaNode.CompositionNodes.Add("color2", alphaNode);

                // set the parameters of the children so that they match the original texture
                var children = new[] { colorNode, alphaNode };
                foreach (var childTexture in children)
                {
                    childTexture.Sampler.AddressModeU = textureNode.Sampler.AddressModeU;
                    childTexture.Sampler.AddressModeV = textureNode.Sampler.AddressModeV;
                    childTexture.Sampler.Filtering    = textureNode.Sampler.Filtering;
                    childTexture.Offset = textureNode.Offset;
                    childTexture.Sampler.SamplerParameterKey = textureNode.Sampler.SamplerParameterKey;
                    childTexture.Scale         = textureNode.Scale;
                    childTexture.TexcoordIndex = textureNode.TexcoordIndex;
                }

                // copy the parameter key on the color and let the one of the alpha null so that it is set automatically to available value later
                colorNode.Key = textureNode.Key;
                alphaNode.Key = null;

                // update all the material references to the new node
                nodeReplacer.Replace(textureNode, substituteAlphaNode);
            }

            return(modifiedMaterial);
        }
コード例 #3
0
        /// <summary>
        /// Build the ShaderMixinSource to evaluate the binaryNode.
        /// </summary>
        /// <param name="node">The MaterialShaderClassNode binaryNode used as source to find the ShaderMixinSource.</param>
        /// <returns>The corresponding ShaderMixinSource.</returns>
        private ShaderSource GetShaderSource(MaterialShaderClassNode node)
        {
            if (!node.MixinReference.HasLocation())
            {
                return(new ShaderClassSource("ComputeColor"));
            }
            var mixinName = Path.GetFileNameWithoutExtension(node.MixinReference.Location);

            object[] generics = null;
            if (node.Generics.Count > 0)
            {
                // TODO: correct generic order
                var mixinGenerics = new List <object>();
                foreach (var genericKey in node.Generics.Keys)
                {
                    var generic = node.Generics[genericKey];
                    if (generic is NodeParameterTexture)
                    {
                        var textureReference = ((NodeParameterTexture)generic).Reference;
                        var foundNode        = Material.FindNode(textureReference);
                        while (foundNode != null && !(foundNode is MaterialTextureNode))
                        {
                            var refNode = foundNode as MaterialReferenceNode;
                            if (refNode == null)
                            {
                                break;
                            }

                            foundNode = Material.FindNode(refNode.Name);
                        }

                        var foundTextureNode = foundNode as MaterialTextureNode;
                        if (foundTextureNode == null || foundTextureNode.UsedParameterKey == null)
                        {
                            Logger.Warning("[Material] The generic texture reference in node [" + node + "] is incorrect.");
                            mixinGenerics.Add("Texturing.Texture0");
                        }
                        else
                        {
                            mixinGenerics.Add(foundTextureNode.UsedParameterKey.ToString());
                        }
                    }
                    else if (generic is NodeParameterSampler)
                    {
                        var pk = ((NodeParameterSampler)generic).SamplerParameterKey;
                        if (pk == null)
                        {
                            Logger.Warning("[Material] The generic sampler reference in node [" + node + "] is incorrect.");
                            mixinGenerics.Add("Texturing.Sampler");
                        }
                        else
                        {
                            mixinGenerics.Add(pk.ToString());
                        }
                    }
                    else if (generic is NodeParameterFloat)
                    {
                        mixinGenerics.Add(((NodeParameterFloat)generic).Value.ToString(CultureInfo.InvariantCulture));
                    }
                    else if (generic is NodeParameterInt)
                    {
                        mixinGenerics.Add(((NodeParameterInt)generic).Value.ToString(CultureInfo.InvariantCulture));
                    }
                    else if (generic is NodeParameterFloat2)
                    {
                        mixinGenerics.Add(GetAsShaderString(((NodeParameterFloat2)generic).Value));
                    }
                    else if (generic is NodeParameterFloat3)
                    {
                        mixinGenerics.Add(GetAsShaderString(((NodeParameterFloat3)generic).Value));
                    }
                    else if (generic is NodeParameterFloat4)
                    {
                        mixinGenerics.Add(GetAsShaderString(((NodeParameterFloat4)generic).Value));
                    }
                    else if (generic is NodeParameter)
                    {
                        mixinGenerics.Add(((NodeParameter)generic).Reference);
                    }
                    else
                    {
                        throw new Exception("[Material] Unknown node type: " + generic.GetType());
                    }
                }
                generics = mixinGenerics.ToArray();
            }

            var shaderClassSource = new ShaderClassSource(mixinName, generics);

            if (node.CompositionNodes.Count == 0)
            {
                return(shaderClassSource);
            }

            var mixin = new ShaderMixinSource();

            mixin.Mixins.Add(shaderClassSource);

            foreach (var comp in node.CompositionNodes)
            {
                if (comp.Value != null)
                {
                    var compShader = GetShaderSource(comp.Value);
                    if (compShader != null)
                    {
                        mixin.Compositions.Add(comp.Key, compShader);
                    }
                }
            }

            return(mixin);
        }