private void BlendShadingModel(MaterialBlendLayerContext parent, MaterialBlendLayerPerStageContext pendingPixelLayerContext, MaterialBlendLayerPerStageContext parentPixelLayerContext) { var shaderBlendingSource = new ShaderMixinSource(); shaderBlendingSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingBlend")); parent.SetStreamBlend(MaterialShaderStage.Pixel, parent.BlendMapForShadingModel); // Add shader source already setup for the parent foreach (var shaderSource in pendingPixelLayerContext.ShaderSources) { shaderBlendingSource.AddCompositionToArray("layers", shaderSource); } // Add shader source generated for blending this layer foreach (var shaderSource in parent.ShadingModels.Generate(this)) { shaderBlendingSource.AddCompositionToArray("layers", shaderSource); } parent.ShadingModels.Clear(); parentPixelLayerContext.ShaderSources.Add(shaderBlendingSource); pendingPixelLayerContext.Reset(); parent.BlendMapForShadingModel = null; }
public ShaderSource GetSource(RenderVoxelVolumeData data) { var writermixin = new ShaderMixinSource(); writermixin.Mixins.Add(storage); foreach (var attr in data.AttributeIndirect) { writermixin.AddCompositionToArray("AttributesIndirect", attr); } foreach (var attr in data.AttributeModifiers) { writermixin.AddCompositionToArray("Modifiers", attr); } return(writermixin); }
private void Generate(MaterialShaderStage stage, MaterialGeneratorContext context) { if (!context.HasSurfaceShaders(stage)) { return; } // Blend setup for this layer context.SetStream(stage, BlendStream, BlendMap, MaterialKeys.BlendMap, MaterialKeys.BlendValue); // Generate a dynamic shader name // Create a mixin var shaderMixinSource = new ShaderMixinSource(); shaderMixinSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceStreamsBlend")); // Add all streams foreach (var stream in context.Streams[stage]) { shaderMixinSource.AddCompositionToArray("blends", context.GetStreamBlendShaderSource(stream)); } var materialBlendLayerMixin = context.GenerateSurfaceShader(stage); // Add the shader to the mixin shaderMixinSource.AddComposition("layer", materialBlendLayerMixin); context.ResetSurfaceShaders(stage); context.AddSurfaceShader(stage, shaderMixinSource); }
/// <summary> /// Squash <see cref="ShaderSources"/> to a single ShaderSource (compatible with IComputeColor) /// </summary> /// <returns>The squashed <see cref="ShaderSource"/> or null if nothing to squash</returns> public ShaderSource ComputeShaderSource() { if (ShaderSources.Count == 0) { return(null); } ShaderSource result; // If there is only a single op, don't generate a mixin if (ShaderSources.Count == 1) { result = ShaderSources[0]; } else { var mixin = new ShaderMixinSource(); result = mixin; mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceArray")); // Squash all operations into MaterialLayerArray foreach (var operation in ShaderSources) { mixin.AddCompositionToArray("layers", operation); } } return(result); }
public ShaderSource GenerateSurfaceShader(MaterialShaderStage stage) { var surfaceShaders = GetSurfaceShaders(stage); if (surfaceShaders.Count == 0) { return(null); } ShaderSource result; // If there is only a single op, don't generate a mixin if (surfaceShaders.Count == 1) { result = surfaceShaders[0]; } else { var mixin = new ShaderMixinSource(); result = mixin; mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceArray")); // Squash all operations into MaterialLayerArray foreach (var operation in surfaceShaders) { mixin.AddCompositionToArray("layers", operation); } } surfaceShaders.Clear(); Streams[stage].Clear(); return(result); }
/// <summary> /// Squash <see cref="ShaderSources"/> to a single ShaderSource (compatible with IComputeColor) /// </summary> /// <returns>The squashed <see cref="ShaderSource"/> or null if nothing to squash</returns> public ShaderSource ComputeShaderSource() { if (ShaderSources.Count == 0) { return null; } ShaderSource result; // If there is only a single op, don't generate a mixin if (ShaderSources.Count == 1) { result = ShaderSources[0]; } else { var mixin = new ShaderMixinSource(); result = mixin; mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceArray")); // Squash all operations into MaterialLayerArray foreach (var operation in ShaderSources) { mixin.AddCompositionToArray("layers", operation); } } return result; }
public ShaderSource GetVoxelizationShader(VoxelizationPass pass, ProcessedVoxelVolume data) { bool singleClip = UpdatesOneClipPerFrame(); ShaderSource VoxelizationMethodSource = pass.method.GetVoxelizationShader(); ShaderMixinSource cachedMixin = new ShaderMixinSource(); cachedMixin.Mixins.Add(storage); cachedMixin.AddComposition("method", VoxelizationMethodSource); if (singleClip) { cachedMixin.AddMacro("singleClip", true); } string IndirectStoreMacro = ""; for (int i = 0; i < pass.AttributesIndirect.Count; i++) { string iStr = i.ToString(); IndirectStoreMacro += $"AttributesIndirect[{iStr}].IndirectWrite(fragmentsBuffer, writeindex + {pass.AttributesIndirect[i].BufferOffset});\n"; } cachedMixin.AddMacro("IndirectStoreMacro", IndirectStoreMacro); foreach (var attr in pass.AttributesTemp) { cachedMixin.AddCompositionToArray("AttributesTemp", attr.GetVoxelizationShader()); } foreach (var attr in pass.AttributesDirect) { cachedMixin.AddCompositionToArray("AttributesDirect", attr.GetVoxelizationShader()); } foreach (var attr in pass.AttributesIndirect) { cachedMixin.AddCompositionToArray("AttributesIndirect", attr.GetVoxelizationShader()); } return(cachedMixin); }
public ShaderSource GetShaderFloat4(List <IVoxelModifierEmissionOpacity> modifiers) { var mixin = new ShaderMixinSource(); mixin.Mixins.Add(writer); StorageMethod.Apply(mixin); foreach (var attr in modifiers) { ShaderSource applier = attr.GetApplier("Anisotropic"); if (applier != null) { mixin.AddCompositionToArray("Modifiers", applier); } } return(mixin); }
virtual public ShaderSource GetVoxelizationShader(List <VoxelModifierEmissionOpacity> modifiers) { var mixin = new ShaderMixinSource(); mixin.Mixins.Add(Writer); StorageMethod.Apply(mixin); foreach (var modifier in modifiers) { if (!modifier.Enabled) { continue; } ShaderSource applier = modifier.GetApplier(ApplierKey); if (applier != null) { mixin.AddCompositionToArray("Modifiers", applier); } } return(mixin); }
private void BlendStreams(MaterialBlendLayerContext layer) { // Generate Vertex and Pixel surface shaders foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { // If we don't have any stream set, we have nothing to blend var stageContext = layer.GetContextPerStage(stage); if (stageContext.Streams.Count == 0) { continue; } // Blend setup for this layer layer.SetStreamBlend(stage, layer.BlendMap); // Generate a dynamic shader name // Create a mixin var shaderMixinSource = new ShaderMixinSource(); shaderMixinSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceStreamsBlend")); // Add all streams that we need to blend foreach (var stream in stageContext.Streams) { shaderMixinSource.AddCompositionToArray("blends", GetStreamBlendShaderSource(stream)); } stageContext.Streams.Clear(); // Squash all ShaderSources to a single shader source var materialBlendLayerMixin = stageContext.ComputeShaderSource(); stageContext.ShaderSources.Clear(); // Add the shader to the mixin shaderMixinSource.AddComposition("layer", materialBlendLayerMixin); // Squash the shader sources stageContext.ShaderSources.Add(shaderMixinSource); } }
public void PopLayer() { // If current shading model is not set, if (CurrentShadingModel == null && Current.ShadingModels.Count > 0) { CurrentShadingModel = Current.ShadingModels; } var sameShadingModel = Current.ShadingModels.Equals(CurrentShadingModel); if (!sameShadingModel) { shadingModelCount++; } var shouldBlendShadingModels = CurrentShadingModel != null && (!sameShadingModel || Current.Parent == null); // current shading model different from next shading model // -------------------------------------------------------------------- // Copy the shading surfaces and the stream initializer to the parent. // -------------------------------------------------------------------- if (Current.Parent != null) { foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { // the initializers Current.Parent.StreamInitializers[stage].AddRange(Current.StreamInitializers[stage]); // skip pixel shader if shading model need to be blended if (stage == MaterialShaderStage.Pixel && shouldBlendShadingModels) { continue; } // the surface shaders Current.Parent.SurfaceShaders[stage].AddRange(Current.SurfaceShaders[stage]); } } // ------------------------------------------------- // Blend shading models between layers if necessary // ------------------------------------------------- if (shouldBlendShadingModels) { var shadingSources = CurrentShadingModel.Generate(this); // If we are in a multi-shading-blending, only blend shading models after 1st shading model if (shadingModelCount > 1) { var shaderBlendingSource = new ShaderMixinSource(); shaderBlendingSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceBlendShading")); foreach (var shaderSource in shadingSources) { shaderBlendingSource.AddCompositionToArray("layers", shaderSource); } shadingSources = new List <ShaderSource>() { shaderBlendingSource }; } var currentOrParentLayer = Current.Parent ?? Current; foreach (var shaderSource in shadingSources) { currentOrParentLayer.SurfaceShaders[MaterialShaderStage.Pixel].Add(shaderSource); } } // In case of the root material, add all stream modifiers just at the end and call final callbacks if (Current.Parent == null) { foreach (var modifierKey in inputStreamModifiers.Keys) { Current.SurfaceShaders[modifierKey.Key].Add(inputStreamModifiers[modifierKey]); } // Clear final callback foreach (var callbackKeyPair in finalCallbacks) { var stage = callbackKeyPair.Key; var callbacks = callbackKeyPair.Value; foreach (var callback in callbacks) { callback(stage, this); } callbacks.Clear(); } } // ---------------------------------------------- // Pop to Parent and set Current // ---------------------------------------------- if (Current.Parent != null && !sameShadingModel) { CurrentShadingModel = Current.ShadingModels; } if (Current.Parent != null) { Current = Current.Parent; } }
private void ProcessIntermediateLayer(MaterialBlendLayerContext layer, bool isLastChild) { var parent = layer.Parent; var hasParentShadingModel = parent.ShadingModelCount > 0; // If current shading model is not set, if (!hasParentShadingModel && layer.ShadingModelCount > 0) { layer.ShadingModels.CopyTo(parent.ShadingModels); hasParentShadingModel = true; parent.ShadingModelCount++; } var sameShadingModel = hasParentShadingModel && layer.ShadingModels.Equals(parent.ShadingModels); if (sameShadingModel) { // If shading model is not changing, we generate the BlendStream shaders BlendStreams(layer); } else { parent.ShadingModelCount++; } var parentPixelLayerContext = parent.GetContextPerStage(MaterialShaderStage.Pixel); var pendingPixelLayerContext = parent.PendingPixelLayerContext; // Copy streams to parent foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { var stageContext = layer.GetContextPerStage(stage); var parentStageContext = parent.GetContextPerStage(stage); // the Initializers parentStageContext.StreamInitializers.AddRange(stageContext.StreamInitializers); // skip pixel shader if shading model need to be blended if (stage == MaterialShaderStage.Pixel) { if (!sameShadingModel) { continue; } // If same shading model, use temporarely the ParentPixelLayerContext parentStageContext = pendingPixelLayerContext; } // Add shaders except Pixels if we have a different ShadingModel parentStageContext.ShaderSources.AddRange(stageContext.ShaderSources); } var forceBlendingShadingModel = isLastChild && (parent.ShadingModelCount > 1 || !sameShadingModel); if (!sameShadingModel || forceBlendingShadingModel) { if (forceBlendingShadingModel && parent.BlendMapForShadingModel == null) { if (!sameShadingModel) { foreach (var shaderSource in pendingPixelLayerContext.ShaderSources) { parentPixelLayerContext.ShaderSources.Add(shaderSource); } pendingPixelLayerContext.Reset(); foreach (var shaderSource in parent.ShadingModels.Generate(this)) { parentPixelLayerContext.ShaderSources.Add(shaderSource); } parent.ShadingModels.Clear(); layer.ShadingModels.CopyTo(parent.ShadingModels); } parent.BlendMapForShadingModel = layer.BlendMap; var currentPixelLayerContext = layer.GetContextPerStage(MaterialShaderStage.Pixel); pendingPixelLayerContext.ShaderSources.AddRange(currentPixelLayerContext.ShaderSources); } // Do we need to blend shading model? if (parent.BlendMapForShadingModel != null) { var shaderBlendingSource = new ShaderMixinSource(); shaderBlendingSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingBlend")); parent.SetStreamBlend(MaterialShaderStage.Pixel, parent.BlendMapForShadingModel); // Add shader source already setup for the parent foreach (var shaderSource in pendingPixelLayerContext.ShaderSources) { shaderBlendingSource.AddCompositionToArray("layers", shaderSource); } // Add shader source generated for blending this layer foreach (var shaderSource in parent.ShadingModels.Generate(this)) { shaderBlendingSource.AddCompositionToArray("layers", shaderSource); } parent.ShadingModels.Clear(); parentPixelLayerContext.ShaderSources.Add(shaderBlendingSource); pendingPixelLayerContext.Reset(); parent.BlendMapForShadingModel = null; } else { foreach (var shaderSource in pendingPixelLayerContext.ShaderSources) { parentPixelLayerContext.ShaderSources.Add(shaderSource); } pendingPixelLayerContext.Reset(); foreach (var shaderSource in parent.ShadingModels.Generate(this)) { parentPixelLayerContext.ShaderSources.Add(shaderSource); } parent.ShadingModels.Clear(); parent.BlendMapForShadingModel = layer.BlendMap; // Copy the shading model of this layer to the parent layer.ShadingModels.CopyTo(parent.ShadingModels); } // If the shading model is different, the current attributes of the layer are not part of this blending // So they will contribute to the next blending if (!sameShadingModel && !forceBlendingShadingModel) { var currentPixelLayerContext = layer.GetContextPerStage(MaterialShaderStage.Pixel); pendingPixelLayerContext.ShaderSources.AddRange(currentPixelLayerContext.ShaderSources); } } }