/// <summary> /// Generate one shader. /// </summary> public ShaderMixinSource GenerateShaderForReduction(IMaterialNode materialNode) { shaderForReduction = true; var textureVisitor = new MaterialTextureVisitor(Material); var allTextures = textureVisitor.GetAllTextureValues(materialNode); textureVisitor.AssignDefaultTextureKeys(allTextures.Distinct(), null); return(GetShaderMixinSource(GetShaderSource(materialNode))); }
/// <summary> /// Assign the default texture keys to this model. /// </summary> private void AssignModelTextureKeys() { var textureVisitor = new MaterialTextureVisitor(Material); var allTextures = new List <MaterialTextureNode>(); var allSampler = new List <NodeParameterSampler>(); foreach (var referenceName in Material.ColorNodes.Select(x => x.Value)) { var startNode = Material.FindNode(referenceName); if (startNode != null) { allTextures.AddRange(textureVisitor.GetAllTextureValuesWithGenerics(startNode)); allSampler.AddRange(textureVisitor.GetAllSamplerValues(startNode)); } } textureVisitor.AssignDefaultTextureKeys(allTextures.Distinct(), allSampler.Distinct()); }
/// <summary> /// Get the next texture parameter key from the displacement pool. /// </summary> /// <returns>A parameter key.</returns> private static ParameterKey <Graphics.Texture> GetNextDisplacementTextureKey(MaterialTextureVisitor textureVisitor) { return(textureVisitor.GetNextTextureKey(DisplacementTextureKeys, ref textureVisitor.nextDisplacementIndex)); }
/// <summary> /// Get the next texture parameter key from the normal map pool. /// </summary> /// <returns>A parameter key.</returns> private static ParameterKey <Graphics.Texture> GetNextNormalMapTextureKey(MaterialTextureVisitor textureVisitor) { return(textureVisitor.GetNextTextureKey(NormalMapTextureKeys, ref textureVisitor.nextNormalMapIndex)); }
/// <summary> /// Get the next texture parameter key from the specular pool. /// </summary> /// <returns>A parameter key.</returns> private static ParameterKey <Graphics.Texture> GetNextSpecularTextureKey(MaterialTextureVisitor textureVisitor) { return(textureVisitor.GetNextTextureKey(SpecularTextureKeys, ref textureVisitor.nextSpecularIndex)); }
/// <summary> /// Compute the parameters and store them in the material. /// </summary> /// <param name="log">The logger.</param> /// <returns>A boolean stating that the parameters were incorrectly created.</returns> public bool CreateParameterCollectionData(Logger log = null) { Parameters.Clear(); var hasErrors = false; var materialShaderCreator = new MaterialTreeShaderCreator(Material); var shaders = materialShaderCreator.GenerateModelShaders(); if (log != null) { (materialShaderCreator.Logger).CopyTo(log); } foreach (var keyValue in Material.Parameters) { // NOTE: cheap way to activate alpha blending Parameters.Set(keyValue.Key, keyValue.Value); if (keyValue.Key == MaterialParameters.UseTransparent && Material.GetParameter(MaterialParameters.UseTransparent)) { // using non premultiply alpha blending var blendStateDescr = new BlendStateDescription(Blend.SourceAlpha, Blend.InverseSourceAlpha); var blendState = new FakeBlendState(blendStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.BlendStateKey, ContentReference.Create((BlendState)blendState)); // disable face culling // TODO: make this programmable var rasterizerStateDescr = new RasterizerStateDescription(CullMode.None); var rasterizerState = new FakeRasterizerState(rasterizerStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.RasterizerStateKey, ContentReference.Create((RasterizerState)rasterizerState)); // disable depth write var depthStencilStateDescr = new DepthStencilStateDescription(true, false); var depthStencilState = new FakeDepthStencilState(depthStencilStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.DepthStencilStateKey, ContentReference.Create((DepthStencilState)depthStencilState)); } else if (keyValue.Key == MaterialParameters.UseTransparentMask && Material.GetParameter(MaterialParameters.UseTransparentMask)) { // disable face culling // TODO: make this programmable var rasterizerStateDescr = new RasterizerStateDescription(CullMode.None); var rasterizerState = new FakeRasterizerState(rasterizerStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.RasterizerStateKey, ContentReference.Create((RasterizerState)rasterizerState)); // enable depth write var depthStencilStateDescr = new DepthStencilStateDescription(true, true); var depthStencilState = new FakeDepthStencilState(depthStencilStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.DepthStencilStateKey, ContentReference.Create((DepthStencilState)depthStencilState)); } } var textureVisitor = new MaterialTextureVisitor(Material); var allTextures = textureVisitor.GetAllModelTextureValuesWithGenerics(); foreach (var texture in allTextures) { if (texture.TextureReference == null || (texture.TextureReference.Id == Guid.Empty && String.IsNullOrEmpty(texture.TextureReference.Location))) { if (log != null) { log.Error("[Material] Material {0} is missing a texture", materialUrl); } hasErrors = true; } else { Parameters.Set(texture.UsedParameterKey, new ContentReference <Texture2D>(texture.TextureReference.Id, texture.TextureReference.Location)); AddSampler(texture.Sampler); } } var allSamplers = textureVisitor.GetAllSamplerValues(); foreach (var sampler in allSamplers) { AddSampler(sampler); } var parameterVisitor = new MaterialParametersVisitor(Material); var parameters = parameterVisitor.GetParameters(); foreach (var keyValue in parameters) { // The code is separated from the previous code since the key is not generated the same way. if (keyValue.Value is MaterialTextureNode) { var textureNode = (MaterialTextureNode)keyValue.Value; if (textureNode != null) { if (textureNode.TextureReference == null || textureNode.TextureReference.Id == Guid.Empty || String.IsNullOrEmpty(textureNode.TextureReference.Location)) { if (log != null) { log.Error("[Material] Material {0} is missing a texture", materialUrl); } hasErrors = true; } else { Parameters.Set(keyValue.Key, new ContentReference <Texture2D>(textureNode.TextureReference.Id, textureNode.TextureReference.Location)); } } } else if (keyValue.Value is NodeParameterSampler) { var sampler = (NodeParameterSampler)keyValue.Value; if (sampler.SamplerParameterKey == null && keyValue.Key is ParameterKey <SamplerState> ) { sampler.SamplerParameterKey = (ParameterKey <SamplerState>)keyValue.Key; } AddSampler(sampler); } else { Parameters.Set(keyValue.Key, keyValue.Value); } } // NOTE: this can set the shader uniforms and potentially override what was in Material.Parameters foreach (var keyValue in shaders) { if (log != null && (keyValue.Key == MaterialParameters.BumpMap || keyValue.Key == MaterialParameters.EmissiveMap || keyValue.Key == MaterialParameters.ReflectionMap)) { log.Warning("[Material] Material {0} contains the key {1} which is not yet handled by the engine.", materialUrl, keyValue.Key); } Parameters.Set(keyValue.Key, keyValue.Value); } return(hasErrors); }