4 using System.Collections.Generic;
7 using SiliconStudio.Core.IO;
8 using SiliconStudio.Core.Mathematics;
9 using SiliconStudio.Core.Serialization.Assets;
10 using SiliconStudio.Paradox.Assets.Materials.Nodes;
11 using SiliconStudio.Paradox.Assets.Materials.Processor.Visitors;
12 using SiliconStudio.Paradox.Effects;
13 using SiliconStudio.Paradox.Graphics;
14 using SiliconStudio.Paradox.Graphics.Data;
15 using SiliconStudio.Paradox.Shaders;
16 using SiliconStudio.Paradox.Shaders.Compiler;
18 namespace SiliconStudio.
Paradox.Assets.Materials.Processor.Flattener
22 #region Private members
27 private static int textureIndex = 0;
42 private readonly List<MaterialReductionInfo> commandList =
new List<MaterialReductionInfo>();
46 #region Public properties
56 public bool HasCommands
60 return commandList.Count > 0;
66 #region Public methods
74 graphicsDevice = device;
95 if (commandList.Count > 0)
98 plane = GeometricPrimitive.Plane.New(graphicsDevice, 2.0f, 2.0f);
101 assetManager.Serializer.RegisterSerializer(
new GpuTextureSerializer2<
Graphics.Texture2D>(graphicsDevice));
103 var textures =
new Dictionary<string, Texture2D>();
106 var compilerParameters =
new CompilerParameters { Platform = GraphicsPlatform.Direct3D11, Profile = GraphicsProfile.Level_11_0 };
108 foreach (var command
in commandList)
110 var computeColorShader = materialTreeShaderCreator.GenerateShaderForReduction(command.OldNode);
111 if (computeColorShader == null)
116 finalShader.Compositions.Add(
"outColor", computeColorShader);
117 var results = compiler.Compile(finalShader, compilerParameters, null, null);
119 if (results.HasErrors)
122 command.TreeEffect =
new Graphics.Effect(graphicsDevice, results.MainBytecode, results.MainUsedParameters);
125 var allTextures = textureVisitor.GetAllTextureValues(command.OldNode);
126 foreach (var texSlot
in allTextures)
129 if (!textures.TryGetValue(texSlot.TextureName, out tex))
132 tex = assetManager.Load<
Texture2D>(texSlot.TextureName);
133 textures.Add(texSlot.TextureName, tex);
137 throw new FileNotFoundException(
"Texture " + texSlot.TextureName +
" not found");
139 command.TreeEffect.Parameters.Set(texSlot.UsedParameterKey, tex);
140 maxWidth = Math.Max(maxWidth, tex.Width);
141 maxHeight = Math.Max(maxHeight, tex.Height);
146 command.RenderTarget = Texture2D.New(graphicsDevice, maxWidth, maxHeight, PixelFormat.R8G8B8A8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget();
147 command.ToExecute =
true;
151 commandList.RemoveAll(x => !x.ToExecute);
155 foreach (var command
in commandList.Where(x => x.ToExecute))
157 lock (graphicsDevice)
159 graphicsDevice.Clear(command.RenderTarget, Color4.Black);
160 graphicsDevice.SetRenderTarget(command.RenderTarget);
162 graphicsDevice.SetRasterizerState(graphicsDevice.RasterizerStates.CullNone);
163 graphicsDevice.SetDepthStencilState(graphicsDevice.DepthStencilStates.None);
165 command.TreeEffect.Apply();
169 SaveTexture(command.RenderTarget.Texture, command.TextureUrl, assetManager);
174 nodeReplacer.Replace(command.OldNode, newNode);
177 command.ToExecute =
false;
180 foreach (var command
in commandList)
182 command.TreeEffect.Dispose();
183 command.RenderTarget.Dispose();
186 foreach (var texture
in textures)
188 texture.Value.Dispose();
192 foreach (var tex
in textures)
194 assetManager.Unload(tex);
198 result = commandList.All(x => !x.ToExecute);
211 reducer.ReduceTrees();
212 var reducedTrees = reducer.ReducedTrees;
215 foreach (var materialReference
in reducedTrees)
217 Material.Nodes[materialReference.Key] = materialReference.Value;
218 textureVisitor.AssignDefaultTextureKeys(materialReference.Value);
222 textureVisitor.ResetTextureIndices();
224 var basePath = (baseDir == null || baseDir.GetDirectory() ==
"" ?
"" : baseDir.ToString() +
"/") +
"__reduced_textures__";
226 foreach (var materialReferenceKey
in Material.Nodes)
228 if (materialReferenceKey.Value == null)
231 var materialReferenceName = materialReferenceKey.Key;
232 var materialNode = materialReferenceKey.Value;
233 textureVisitor.AssignDefaultTextureKeys(materialNode);
234 var nodesToReduce = reducer.GetReducibleSubTrees(materialNode);
236 for (var i = 0; i < nodesToReduce.Count; ++i)
238 var nodeToReduce = nodesToReduce[i];
239 var finalTextureUrl =
new UFile(basePath, materialReferenceName +
"_Texture" + (nodesToReduce.Count > 1 ? i.ToString() :
""), null);
240 var infos =
new MaterialReductionInfo { ToExecute =
false, TextureUrl = finalTextureUrl };
241 var canBeReduced = textureVisitor.HasUniqueTexcoord(nodeToReduce, out infos.TexcoordIndex);
242 infos.OldNode = nodeToReduce;
247 commandList.Add(infos);
254 #region Private methods
261 private void SaveTexture(
Paradox.Graphics.Texture texture,
string filename,
AssetManager assetManager)
263 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
264 using (var image = texture.GetDataAsImage())
266 using (var resultFileStream = File.OpenWrite(
"tex" + textureIndex +
".png"))
269 image.Save(resultFileStream, ImageFileType.Png);
272 assetManager.Save(filename, image);
284 private class MaterialReductionInfo
287 public bool ToExecute;
290 public UFile TextureUrl;
291 public IMaterialNode OldNode;
bool Run(EffectCompilerBase compiler)
Performs the maximal reduction.
void Dispose()
Release the allocated data.
static readonly Vector2 Zero
A SiliconStudio.Core.Mathematics.Vector2 with all of its components set to zero.
Represents a two dimensional mathematical vector.
A renderable texture view.
A mixin performing a combination of ShaderClassSource and other mixins.
Base class for implementations of IEffectCompiler, providing some helper functions.
Description of a material.
A geometric primitive. Use Cube, Cylinder, GeoSphere, Plane, Sphere, Teapot, Torus. See Draw+vertices to learn how to use it.
Parameters used for compilation.
TextureCoordinate
The texture coordinate.
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
static readonly Vector2 One
A SiliconStudio.Core.Mathematics.Vector2 with all of its components set to one.
Defines a normalized directory path. See UPath for details. This class cannot be inherited.
void PrepareForFlattening(UDirectory baseDir=null)
Create the structures to perform the reductions.
A Texture 2D frontend to SharpDX.Direct3D11.Texture2D.
MaterialTextureLayerFlattener(MaterialDescription mat, GraphicsDevice device)
Constructor.
A shader class used for mixin.
Defines a normalized file path. See UPath for details. This class cannot be inherited.