Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
MaterialAssetCompiler.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 
4 using System.Threading.Tasks;
5 
6 using SiliconStudio.Assets;
7 using SiliconStudio.Assets.Compiler;
8 using SiliconStudio.BuildEngine;
9 using SiliconStudio.Core;
10 using SiliconStudio.Core.IO;
11 using SiliconStudio.Core.Mathematics;
12 using SiliconStudio.Core.Serialization;
13 using SiliconStudio.Core.Serialization.Assets;
14 using SiliconStudio.Paradox.Assets.Materials.Nodes;
15 using SiliconStudio.Paradox.Assets.Materials.Processor.Visitors;
16 using SiliconStudio.Paradox.Effects.Data;
17 using System.Linq;
18 
19 namespace SiliconStudio.Paradox.Assets.Materials
20 {
21  internal class MaterialAssetCompiler : AssetCompilerBase<MaterialAsset>
22  {
23  protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, MaterialAsset asset, AssetCompilerResult result)
24  {
25  result.ShouldWaitForPreviousBuilds = true;
26  result.BuildSteps = new ListBuildStep { new MaterialCompileCommand(urlInStorage, AssetItem, asset, context) };
27  }
28 
29  private class MaterialCompileCommand : AssetCommand<MaterialAsset>
30  {
31  private readonly AssetItem assetItem;
32 
33  private readonly AssetCompilerContext context;
34 
35  private UFile assetUrl;
36 
37  public MaterialCompileCommand(string url, AssetItem assetItem, MaterialAsset value, AssetCompilerContext context)
38  : base(url, value)
39  {
40  this.assetItem = assetItem;
41  this.context = context;
42  assetUrl = new UFile(url);
43  }
44 
45  private bool IsTextureReferenceValid(MaterialTextureNode node)
46  {
47  return assetItem.Package.Session.FindAsset(node.TextureReference.Location) != null;
48  }
49 
50  public override System.Collections.Generic.IEnumerable<ObjectUrl> GetInputFiles()
51  {
52  var materialTextureVisitor = new MaterialTextureVisitor(asset.Material);
53  foreach (var textureLocation in materialTextureVisitor.GetAllTextureValues().Where(IsTextureReferenceValid).Select(x => x.TextureReference.Location).Distinct())
54  yield return new ObjectUrl(UrlType.Internal, textureLocation);
55 
56  foreach (var inputFile in base.GetInputFiles())
57  yield return inputFile;
58  }
59 
60  protected override void ComputeParameterHash(BinarySerializationWriter writer)
61  {
62  base.ComputeParameterHash(writer);
63  writer.Serialize(ref assetUrl, ArchiveMode.Serialize);
64  }
65 
66  protected override Task<ResultStatus> DoCommandOverride(ICommandContext commandContext)
67  {
68  var material = asset.Material.Clone();
69 
70  // Replace all empty Texture nodes by black color texture nodes (allow a display of the element even if material is incomplete)
71  var emptyTextureNodeKeys = material.Nodes.Where(m=> m.Value is MaterialTextureNode && !IsTextureReferenceValid((MaterialTextureNode)m.Value)).Select(m => m.Key).ToList();
72  foreach (var emptyTextureNodeKey in emptyTextureNodeKeys)
73  {
74  commandContext.Logger.Warning("Texture node '{0}' of material '{1}' is not pointing to a valid texture reference. " +
75  "This node will be replaced by black color Node.", emptyTextureNodeKey, assetItem.Location);
76  material.Nodes[emptyTextureNodeKey] = new MaterialColorNode(new Color4(0));
77  }
78 
79  // Reduce trees on CPU
80  var materialReducer = new MaterialTreeReducer(material);
81  materialReducer.ReduceTrees();
82 
83  foreach (var reducedTree in materialReducer.ReducedTrees)
84  {
85  material.Nodes[reducedTree.Key] = reducedTree.Value;
86  }
87 
88  // Reduce on GPU
89  // TODO: Adapt GPU reduction so that it is compatible Android color/alpha separation
90  // TODO: Use the build engine processed output textures instead of the imported one (not existing any more)
91  // TODO: Set the reduced texture output format
92  // TODO: The graphics device cannot be shared with the Previewer
93  //var graphicsDevice = (GraphicsDevice)context.Attributes.GetOrAdd(CompilerContext.GraphicsDeviceKey, key => GraphicsDevice.New(DeviceCreationFlags.None, GraphicsProfile.Level_11_0));
94  //using (var materialTextureLayerFlattener = new MaterialTextureLayerFlattener(material, graphicsDevice))
95  //{
96  // materialTextureLayerFlattener.PrepareForFlattening(new UDirectory(assetUrl.Directory));
97  // if (materialTextureLayerFlattener.HasCommands)
98  // {
99  // var compiler = EffectCompileCommand.GetOrCreateEffectCompiler(context);
100  // materialTextureLayerFlattener.Run(compiler);
101  // // store Material with modified textures
102  // material = materialTextureLayerFlattener.Material;
103  // }
104  //}
105 
106  // Separate the textures into color/alpha components on Android to be able to use native ETC1 compression
107  if (context.Platform == PlatformType.Android)
108  {
109  var alphaComponentSplitter = new TextureAlphaComponentSplitter(assetItem.Package.Session);
110  material = alphaComponentSplitter.Run(material, new UDirectory(assetUrl.GetDirectory())); // store Material with alpha substituted textures
111  }
112 
113  // Create the parameters
114  var materialParameterCreator = new MaterialParametersCreator(material, assetUrl);
115  if (materialParameterCreator.CreateParameterCollectionData(commandContext.Logger))
116  return Task.FromResult(ResultStatus.Failed);
117 
118  var materialData = new MaterialData { Parameters = materialParameterCreator.Parameters };
119 
120  var assetManager = new AssetManager();
121  assetManager.Save(assetUrl, materialData);
122 
123  return Task.FromResult(ResultStatus.Successful);
124  }
125 
126  public override string ToString()
127  {
128  return (assetUrl ?? "[File]") + " (Material) > " + (assetUrl ?? "[Location]");
129  }
130  }
131  }
132 }
Result of a compilation of assets when using IAssetCompiler.Compile
PlatformType
Describes the platform operating system.
Definition: PlatformType.cs:9
Data type for SiliconStudio.Paradox.Effects.Material.
Definition: EngineData.cs:153
A command processing an Asset.
Definition: AssetCommand.cs:11
An asset item part of a Package accessible through SiliconStudio.Assets.Package.Assets.
Definition: AssetItem.cs:17
Implements SerializationStream as a binary writer.
ResultStatus
Status of a command.
Definition: ResultStatus.cs:8
The context used when compiling an asset in a Package.
Represents a color in the form of rgba.
Definition: Color4.cs:42
Defines a normalized directory path. See UPath for details. This class cannot be inherited.
Definition: UDirectory.cs:13
Defines a normalized file path. See UPath for details. This class cannot be inherited.
Definition: UFile.cs:13