static public StringBuilder Build(VFXContext context, VFXCompilationMode compilationMode, VFXContextCompiledData contextData, HashSet <string> dependencies) { var templatePath = string.Format("{0}.template", context.codeGeneratorTemplate); dependencies.Add(AssetDatabase.AssetPathToGUID(templatePath)); return(Build(context, templatePath, compilationMode, contextData, dependencies)); }
public void SetCompilationMode(VFXCompilationMode mode) { if (m_CompilationMode != mode) { m_CompilationMode = mode; SetExpressionGraphDirty(); RecompileIfNeeded(false, true); } }
public void SetCompilationMode(VFXCompilationMode mode) { if (m_CompilationMode != mode) { m_CompilationMode = mode; SetExpressionGraphDirty(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(this)); } }
public void Compile(VFXCompilationMode compilationMode) { // Prevent doing anything ( and especially showing progesses ) in an empty graph. if (m_Graph.children.Count() < 1) { // Cleaning if (m_Graph.visualEffectResource != null) { m_Graph.visualEffectResource.ClearRuntimeData(); } m_ExpressionGraph = new VFXExpressionGraph(); m_ExpressionValues = new VFXExpressionValueContainerDesc[] {}; return; } Profiler.BeginSample("VFXEditor.CompileAsset"); try { float nbSteps = 12.0f; string assetPath = AssetDatabase.GetAssetPath(visualEffectResource); string progressBarTitle = "Compiling " + assetPath; EditorUtility.DisplayProgressBar(progressBarTitle, "Collecting dependencies", 0 / nbSteps); var models = new HashSet <ScriptableObject>(); m_Graph.CollectDependencies(models); var contexts = models.OfType <VFXContext>().ToArray(); foreach (var c in contexts) // Unflag all contexts { c.MarkAsCompiled(false); } var compilableContexts = models.OfType <VFXContext>().Where(c => c.CanBeCompiled()); var compilableData = models.OfType <VFXData>().Where(d => d.CanBeCompiled()); IEnumerable <VFXContext> implicitContexts = Enumerable.Empty <VFXContext>(); foreach (var d in compilableData) // Flag compiled contexts { implicitContexts = implicitContexts.Concat(d.InitImplicitContexts()); } compilableContexts = compilableContexts.Concat(implicitContexts.ToArray()); foreach (var c in compilableContexts) // Flag compiled contexts { c.MarkAsCompiled(true); } EditorUtility.DisplayProgressBar(progressBarTitle, "Collecting attributes", 1 / nbSteps); foreach (var data in compilableData) { data.CollectAttributes(); } EditorUtility.DisplayProgressBar(progressBarTitle, "Computing layers", 2 / nbSteps); foreach (var data in compilableData) { data.ComputeLayer(); } EditorUtility.DisplayProgressBar(progressBarTitle, "Compiling expression Graph", 3 / nbSteps); m_ExpressionGraph = new VFXExpressionGraph(); var exposedExpressionContext = ScriptableObject.CreateInstance <VFXImplicitContextOfExposedExpression>(); exposedExpressionContext.FillExpression(m_Graph); //Force all exposed expression to be visible, only for registering in CompileExpressions var expressionContextOptions = compilationMode == VFXCompilationMode.Runtime ? VFXExpressionContextOption.ConstantFolding : VFXExpressionContextOption.Reduction; m_ExpressionGraph.CompileExpressions(compilableContexts.Concat(new VFXContext[] { exposedExpressionContext }), expressionContextOptions); EditorUtility.DisplayProgressBar(progressBarTitle, "Generating bytecode", 4 / nbSteps); var expressionDescs = new List <VFXExpressionDesc>(); var valueDescs = new List <VFXExpressionValueContainerDesc>(); FillExpressionDescs(expressionDescs, valueDescs, m_ExpressionGraph); Dictionary <VFXContext, VFXContextCompiledData> contextToCompiledData = new Dictionary <VFXContext, VFXContextCompiledData>(); foreach (var context in compilableContexts) { contextToCompiledData.Add(context, new VFXContextCompiledData()); } EditorUtility.DisplayProgressBar(progressBarTitle, "Generating mappings", 5 / nbSteps); foreach (var context in compilableContexts) { var cpuMapper = m_ExpressionGraph.BuildCPUMapper(context); var contextData = contextToCompiledData[context]; contextData.cpuMapper = cpuMapper; contextData.parameters = context.additionalMappings.ToArray(); contextToCompiledData[context] = contextData; } var exposedParameterDescs = new List <VFXMapping>(); FillExposedDescs(exposedParameterDescs, m_ExpressionGraph, models.OfType <VFXParameter>()); var globalEventAttributeDescs = new List <VFXLayoutElementDesc>() { new VFXLayoutElementDesc() { name = "spawnCount", type = VFXValueType.Float } }; FillEventAttributeDescs(globalEventAttributeDescs, m_ExpressionGraph, compilableContexts); EditorUtility.DisplayProgressBar(progressBarTitle, "Generating Attribute layouts", 6 / nbSteps); foreach (var data in compilableData) { data.GenerateAttributeLayout(); } var generatedCodeData = new List <GeneratedCodeData>(); EditorUtility.DisplayProgressBar(progressBarTitle, "Generating shaders", 7 / nbSteps); GenerateShaders(generatedCodeData, m_ExpressionGraph, compilableContexts, contextToCompiledData, compilationMode); EditorUtility.DisplayProgressBar(progressBarTitle, "Saving shaders", 8 / nbSteps); SaveShaderFiles(m_Graph.visualEffectResource, generatedCodeData, contextToCompiledData); var bufferDescs = new List <VFXGPUBufferDesc>(); var cpuBufferDescs = new List <VFXCPUBufferDesc>(); var systemDescs = new List <VFXEditorSystemDesc>(); EditorUtility.DisplayProgressBar(progressBarTitle, "Generating systems", 9 / nbSteps); cpuBufferDescs.Add(new VFXCPUBufferDesc() { capacity = 1u, layout = globalEventAttributeDescs.ToArray(), stride = globalEventAttributeDescs.First().offset.structure, initialData = ComputeArrayOfStructureInitialData(globalEventAttributeDescs) }); var contextSpawnToSpawnInfo = new Dictionary <VFXContext, SpawnInfo>(); FillSpawner(contextSpawnToSpawnInfo, cpuBufferDescs, systemDescs, compilableContexts, m_ExpressionGraph, globalEventAttributeDescs, contextToCompiledData); var eventDescs = new List <VFXEventDesc>(); FillEvent(eventDescs, contextSpawnToSpawnInfo, compilableContexts); var attributeBufferDictionnary = new Dictionary <VFXData, int>(); var eventGpuBufferDictionnary = new Dictionary <VFXData, int>(); FillDependentBuffer(compilableData, bufferDescs, attributeBufferDictionnary, eventGpuBufferDictionnary); var contextSpawnToBufferIndex = contextSpawnToSpawnInfo.Select(o => new { o.Key, o.Value.bufferIndex }).ToDictionary(o => o.Key, o => o.bufferIndex); foreach (var data in compilableData) { data.FillDescs(bufferDescs, systemDescs, m_ExpressionGraph, contextToCompiledData, contextSpawnToBufferIndex, attributeBufferDictionnary, eventGpuBufferDictionnary); } // Update renderer settings VFXRendererSettings rendererSettings = GetRendererSettings(m_Graph.visualEffectResource.rendererSettings, compilableContexts.OfType <IVFXSubRenderer>()); m_Graph.visualEffectResource.rendererSettings = rendererSettings; EditorUtility.DisplayProgressBar(progressBarTitle, "Setting up systems", 10 / nbSteps); var expressionSheet = new VFXExpressionSheet(); expressionSheet.expressions = expressionDescs.ToArray(); expressionSheet.values = valueDescs.OrderBy(o => o.expressionIndex).ToArray(); expressionSheet.exposed = exposedParameterDescs.OrderBy(o => o.name).ToArray(); m_Graph.visualEffectResource.SetRuntimeData(expressionSheet, systemDescs.ToArray(), eventDescs.ToArray(), bufferDescs.ToArray(), cpuBufferDescs.ToArray()); m_ExpressionValues = expressionSheet.values; EditorUtility.DisplayProgressBar(progressBarTitle, "Importing VFX", 11 / nbSteps); Profiler.BeginSample("VFXEditor.CompileAsset:ImportAsset"); AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); //This should compile the shaders on the C++ size Profiler.EndSample(); } catch (Exception e) { Debug.LogError(string.Format("Exception while compiling expression graph: {0}: {1}", e, e.StackTrace)); // Cleaning if (m_Graph.visualEffectResource != null) { m_Graph.visualEffectResource.ClearRuntimeData(); } m_ExpressionGraph = new VFXExpressionGraph(); m_ExpressionValues = new VFXExpressionValueContainerDesc[] {}; } finally { Profiler.EndSample(); EditorUtility.ClearProgressBar(); } }
private static void GenerateShaders(List <GeneratedCodeData> outGeneratedCodeData, VFXExpressionGraph graph, IEnumerable <VFXContext> contexts, Dictionary <VFXContext, VFXContextCompiledData> contextToCompiledData, VFXCompilationMode compilationMode) { Profiler.BeginSample("VFXEditor.GenerateShaders"); try { foreach (var context in contexts) { var gpuMapper = graph.BuildGPUMapper(context); var uniformMapper = new VFXUniformMapper(gpuMapper, context.doesGenerateShader); // Add gpu and uniform mapper var contextData = contextToCompiledData[context]; contextData.gpuMapper = gpuMapper; contextData.uniformMapper = uniformMapper; contextToCompiledData[context] = contextData; if (context.doesGenerateShader) { var generatedContent = VFXCodeGenerator.Build(context, compilationMode, contextData); outGeneratedCodeData.Add(new GeneratedCodeData() { context = context, computeShader = context.codeGeneratorCompute, compilMode = compilationMode, content = generatedContent }); } } } finally { Profiler.EndSample(); } }
static private StringBuilder Build(VFXContext context, string templatePath, VFXCompilationMode compilationMode, VFXContextCompiledData contextData, HashSet <string> dependencies) { if (!context.SetupCompilation()) { return(null); } var stringBuilder = GetFlattenedTemplateContent(templatePath, new List <string>(), context.additionalDefines, dependencies); var allCurrentAttributes = context.GetData().GetAttributes().Where(a => (context.GetData().IsCurrentAttributeUsed(a.attrib, context)) || (context.contextType == VFXContextType.Init && context.GetData().IsAttributeStored(a.attrib))); // In init, needs to declare all stored attributes for intialization var allSourceAttributes = context.GetData().GetAttributes().Where(a => (context.GetData().IsSourceAttributeUsed(a.attrib, context))); var globalDeclaration = new VFXShaderWriter(); globalDeclaration.WriteCBuffer(contextData.uniformMapper, "parameters"); globalDeclaration.WriteLine(); globalDeclaration.WriteAttributeStruct(allCurrentAttributes.Select(a => a.attrib), "Attributes"); globalDeclaration.WriteLine(); globalDeclaration.WriteAttributeStruct(allSourceAttributes.Select(a => a.attrib), "SourceAttributes"); globalDeclaration.WriteLine(); globalDeclaration.WriteTexture(contextData.uniformMapper); var linkedEventOut = context.allLinkedOutputSlot.Where(s => ((VFXModel)s.owner).GetFirstOfType <VFXContext>().CanBeCompiled()).ToList(); globalDeclaration.WriteEventBuffer(eventListOutName, linkedEventOut.Count); //< Block processor var blockFunction = new VFXShaderWriter(); var blockCallFunction = new VFXShaderWriter(); var blockDeclared = new HashSet <string>(); var expressionToName = context.GetData().GetAttributes().ToDictionary(o => new VFXAttributeExpression(o.attrib) as VFXExpression, o => (new VFXAttributeExpression(o.attrib)).GetCodeString(null)); expressionToName = expressionToName.Union(contextData.uniformMapper.expressionToCode).ToDictionary(s => s.Key, s => s.Value); int cpt = 0; foreach (var current in context.activeFlattenedChildrenWithImplicit) { BuildBlock(contextData, linkedEventOut, blockFunction, blockCallFunction, blockDeclared, expressionToName, current, ref cpt); } //< Final composition var renderTemplatePipePath = VFXLibrary.currentSRPBinder.templatePath; var renderRuntimePipePath = VFXLibrary.currentSRPBinder.runtimePath; string renderPipeCommon = context.doesIncludeCommonCompute ? "Packages/com.unity.visualeffectgraph/Shaders/Common/VFXCommonCompute.hlsl" : VFXLibrary.currentSRPBinder.runtimePath + "/VFXCommon.hlsl"; string renderPipePasses = null; if (!context.codeGeneratorCompute && !string.IsNullOrEmpty(renderTemplatePipePath)) { renderPipePasses = renderTemplatePipePath + "/VFXPasses.template"; } var globalIncludeContent = new VFXShaderWriter(); globalIncludeContent.WriteLine("#define NB_THREADS_PER_GROUP 64"); globalIncludeContent.WriteLine("#define HAS_ATTRIBUTES 1"); globalIncludeContent.WriteLine("#define VFX_PASSDEPTH_ACTUAL (0)"); globalIncludeContent.WriteLine("#define VFX_PASSDEPTH_MOTION_VECTOR (1)"); globalIncludeContent.WriteLine("#define VFX_PASSDEPTH_SELECTION (2)"); globalIncludeContent.WriteLine("#define VFX_PASSDEPTH_SHADOW (3)"); foreach (var attribute in allCurrentAttributes) { globalIncludeContent.WriteLineFormat("#define VFX_USE_{0}_{1} 1", attribute.attrib.name.ToUpper(CultureInfo.InvariantCulture), "CURRENT"); } foreach (var attribute in allSourceAttributes) { globalIncludeContent.WriteLineFormat("#define VFX_USE_{0}_{1} 1", attribute.attrib.name.ToUpper(CultureInfo.InvariantCulture), "SOURCE"); } foreach (var additionnalHeader in context.additionalDataHeaders) { globalIncludeContent.WriteLine(additionnalHeader); } foreach (var additionnalDefine in context.additionalDefines) { globalIncludeContent.WriteLineFormat("#define {0} 1", additionnalDefine); } if (renderPipePasses != null) { globalIncludeContent.Write(GetFlattenedTemplateContent(renderPipePasses, new List <string>(), context.additionalDefines, dependencies)); } if (context.GetData() is ISpaceable) { var spaceable = context.GetData() as ISpaceable; globalIncludeContent.WriteLineFormat("#define {0} 1", spaceable.space == VFXCoordinateSpace.World ? "VFX_WORLD_SPACE" : "VFX_LOCAL_SPACE"); } globalIncludeContent.WriteLineFormat("#include \"{0}/VFXDefines.hlsl\"", renderRuntimePipePath); var perPassIncludeContent = new VFXShaderWriter(); perPassIncludeContent.WriteLine("#include \"" + renderPipeCommon + "\""); perPassIncludeContent.WriteLine("#include \"Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl\""); // Per-block includes var includes = Enumerable.Empty <string>(); foreach (var block in context.activeFlattenedChildrenWithImplicit) { includes = includes.Concat(block.includes); } var uniqueIncludes = new HashSet <string>(includes); foreach (var includePath in uniqueIncludes) { perPassIncludeContent.WriteLine(string.Format("#include \"{0}\"", includePath)); } ReplaceMultiline(stringBuilder, "${VFXGlobalInclude}", globalIncludeContent.builder); ReplaceMultiline(stringBuilder, "${VFXGlobalDeclaration}", globalDeclaration.builder); ReplaceMultiline(stringBuilder, "${VFXPerPassInclude}", perPassIncludeContent.builder); ReplaceMultiline(stringBuilder, "${VFXGeneratedBlockFunction}", blockFunction.builder); ReplaceMultiline(stringBuilder, "${VFXProcessBlocks}", blockCallFunction.builder); var mainParameters = contextData.gpuMapper.CollectExpression(-1).ToArray(); foreach (var match in GetUniqueMatches("\\${VFXLoadParameter:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var loadParameters = GenerateLoadParameter(pattern, mainParameters, expressionToName); ReplaceMultiline(stringBuilder, str, loadParameters.builder); } var additionalInterpolantsGeneration = new VFXShaderWriter(); var additionalInterpolantsDeclaration = new VFXShaderWriter(); var additionalInterpolantsPreparation = new VFXShaderWriter(); int normSemantic = 0; foreach (string fragmentParameter in context.fragmentParameters) { var filteredNamedExpression = mainParameters.FirstOrDefault(o => fragmentParameter == o.name && !(expressionToName.ContainsKey(o.exp) && expressionToName[o.exp] == o.name)); // if parameter already in the global scope, there's nothing to do if (filteredNamedExpression.exp != null) { additionalInterpolantsDeclaration.WriteDeclaration(filteredNamedExpression.exp.valueType, filteredNamedExpression.name, $"NORMAL{normSemantic++}"); additionalInterpolantsGeneration.WriteVariable(filteredNamedExpression.exp.valueType, filteredNamedExpression.name + "__", "0"); var expressionToNameLocal = new Dictionary <VFXExpression, string>(expressionToName); additionalInterpolantsGeneration.EnterScope(); { if (!expressionToNameLocal.ContainsKey(filteredNamedExpression.exp)) { additionalInterpolantsGeneration.WriteVariable(filteredNamedExpression.exp, expressionToNameLocal); additionalInterpolantsGeneration.WriteLine(); } additionalInterpolantsGeneration.WriteAssignement(filteredNamedExpression.exp.valueType, filteredNamedExpression.name + "__", expressionToNameLocal[filteredNamedExpression.exp]); additionalInterpolantsGeneration.WriteLine(); } additionalInterpolantsGeneration.ExitScope(); additionalInterpolantsGeneration.WriteAssignement(filteredNamedExpression.exp.valueType, "o." + filteredNamedExpression.name, filteredNamedExpression.name + "__"); additionalInterpolantsPreparation.WriteVariable(filteredNamedExpression.exp.valueType, filteredNamedExpression.name, "i." + filteredNamedExpression.name); } } ReplaceMultiline(stringBuilder, "${VFXAdditionalInterpolantsGeneration}", additionalInterpolantsGeneration.builder); ReplaceMultiline(stringBuilder, "${VFXAdditionalInterpolantsDeclaration}", additionalInterpolantsDeclaration.builder); ReplaceMultiline(stringBuilder, "${VFXAdditionalInterpolantsPreparation}", additionalInterpolantsPreparation.builder); //< Compute sourceIndex if (stringBuilder.ToString().Contains("${VFXComputeSourceIndex}")) { var r = GenerateComputeSourceIndex(context); ReplaceMultiline(stringBuilder, "${VFXComputeSourceIndex}", r.builder); } //< Load Attribute if (stringBuilder.ToString().Contains("${VFXLoadAttributes}")) { var loadAttributes = GenerateLoadAttribute(".*", context); ReplaceMultiline(stringBuilder, "${VFXLoadAttributes}", loadAttributes.builder); } foreach (var match in GetUniqueMatches("\\${VFXLoadAttributes:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var loadAttributes = GenerateLoadAttribute(pattern, context); ReplaceMultiline(stringBuilder, str, loadAttributes.builder); } //< Store Attribute if (stringBuilder.ToString().Contains("${VFXStoreAttributes}")) { var storeAttribute = GenerateStoreAttribute(".*", context, (uint)linkedEventOut.Count); ReplaceMultiline(stringBuilder, "${VFXStoreAttributes}", storeAttribute.builder); } foreach (var match in GetUniqueMatches("\\${VFXStoreAttributes:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var storeAttributes = GenerateStoreAttribute(pattern, context, (uint)linkedEventOut.Count); ReplaceMultiline(stringBuilder, str, storeAttributes.builder); } foreach (var addionalReplacement in context.additionalReplacements) { ReplaceMultiline(stringBuilder, addionalReplacement.Key, addionalReplacement.Value.builder); } // Replace defines SubstituteMacros(stringBuilder); if (VFXViewPreference.advancedLogs) { Debug.LogFormat("GENERATED_OUTPUT_FILE_FOR : {0}\n{1}", context.ToString(), stringBuilder.ToString()); } context.EndCompilation(); return(stringBuilder); }
static public StringBuilder Build(VFXContext context, VFXCompilationMode compilationMode, VFXContextCompiledData contextData) { var templatePath = string.Format("{0}.template", context.codeGeneratorTemplate); return(Build(context, templatePath, compilationMode, contextData)); }
static private StringBuilder Build(VFXContext context, string templatePath, VFXCompilationMode compilationMode, VFXContextCompiledData contextData) { var dependencies = new HashSet <ScriptableObject>(); context.CollectDependencies(dependencies); var stringBuilder = GetFlattenedTemplateContent(templatePath, new List <string>(), context.additionalDefines); var globalDeclaration = new VFXShaderWriter(); globalDeclaration.WriteCBuffer(contextData.uniformMapper, "parameters"); globalDeclaration.WriteTexture(contextData.uniformMapper); var linkedEventOut = context.allLinkedOutputSlot.Where(s => ((VFXModel)s.owner).GetFirstOfType <VFXContext>().CanBeCompiled()).ToList(); globalDeclaration.WriteEventBuffer(eventListOutName, linkedEventOut.Count); //< Block processor var blockFunction = new VFXShaderWriter(); var blockCallFunction = new VFXShaderWriter(); var blockDeclared = new HashSet <string>(); var expressionToName = context.GetData().GetAttributes().ToDictionary(o => new VFXAttributeExpression(o.attrib) as VFXExpression, o => (new VFXAttributeExpression(o.attrib)).GetCodeString(null)); expressionToName = expressionToName.Union(contextData.uniformMapper.expressionToCode).ToDictionary(s => s.Key, s => s.Value); foreach (var current in context.activeChildrenWithImplicit.Select((v, i) => new { block = v, blockIndex = i })) { var block = current.block; var blockIndex = current.blockIndex; var parameters = block.mergedAttributes.Select(o => { return(new VFXShaderWriter.FunctionParameter { name = o.attrib.name, expression = new VFXAttributeExpression(o.attrib) as VFXExpression, mode = o.mode }); }).ToList(); foreach (var parameter in block.parameters) { var expReduced = contextData.gpuMapper.FromNameAndId(parameter.name, blockIndex); if (VFXExpression.IsTypeValidOnGPU(expReduced.valueType)) { parameters.Add(new VFXShaderWriter.FunctionParameter { name = parameter.name, expression = expReduced, mode = VFXAttributeMode.None }); } } string methodName, commentMethod; GetFunctionName(block, out methodName, out commentMethod); if (!blockDeclared.Contains(methodName)) { blockDeclared.Add(methodName); blockFunction.WriteBlockFunction(contextData.gpuMapper, methodName, block.source, parameters, commentMethod); } //< Parameters (computed and/or extracted from uniform) var expressionToNameLocal = expressionToName; bool needScope = parameters.Any(o => !expressionToNameLocal.ContainsKey(o.expression)); if (needScope) { expressionToNameLocal = new Dictionary <VFXExpression, string>(expressionToNameLocal); blockCallFunction.EnterScope(); foreach (var exp in parameters.Select(o => o.expression)) { if (expressionToNameLocal.ContainsKey(exp)) { continue; } blockCallFunction.WriteVariable(exp, expressionToNameLocal); } } var indexEventCount = parameters.FindIndex(o => o.name == VFXAttribute.EventCount.name); if (indexEventCount != -1) { if ((parameters[indexEventCount].mode & VFXAttributeMode.Read) != 0) { throw new InvalidOperationException(string.Format("{0} isn't expected as read (special case)", VFXAttribute.EventCount.name)); } blockCallFunction.WriteLine(string.Format("{0} = 0u;", VFXAttribute.EventCount.name)); } blockCallFunction.WriteCallFunction(methodName, parameters, contextData.gpuMapper, expressionToNameLocal); if (indexEventCount != -1) { foreach (var outputSlot in block.outputSlots.SelectMany(o => o.LinkedSlots)) { var eventIndex = linkedEventOut.IndexOf(outputSlot); if (eventIndex != -1) { blockCallFunction.WriteLineFormat("{0}_{1} += {0};", VFXAttribute.EventCount.name, VFXCodeGeneratorHelper.GeneratePrefix((uint)eventIndex)); } } } if (needScope) { blockCallFunction.ExitScope(); } } //< Final composition var renderPipePath = UnityEngine.Experimental.VFX.VFXManager.renderPipeSettingsPath; string renderPipeCommon = "Packages/com.unity.visualeffectgraph/Shaders/Common/VFXCommonCompute.cginc"; string renderPipePasses = null; if (!context.codeGeneratorCompute && !string.IsNullOrEmpty(renderPipePath)) { renderPipeCommon = renderPipePath + "/VFXCommon.cginc"; renderPipePasses = renderPipePath + "/VFXPasses.template"; } var globalIncludeContent = new VFXShaderWriter(); globalIncludeContent.WriteLine("#define NB_THREADS_PER_GROUP 64"); foreach (var attribute in context.GetData().GetAttributes().Where(a => (context.contextType == VFXContextType.kInit && context.GetData().IsAttributeStored(a.attrib)) || (context.GetData().IsAttributeUsed(a.attrib, context)))) { globalIncludeContent.WriteLineFormat("#define VFX_USE_{0}_{1} 1", attribute.attrib.name.ToUpper(), "CURRENT"); } foreach (var attribute in context.GetData().GetAttributes().Where(a => context.GetData().IsSourceAttributeUsed(a.attrib, context))) { globalIncludeContent.WriteLineFormat("#define VFX_USE_{0}_{1} 1", attribute.attrib.name.ToUpper(), "SOURCE"); } foreach (var additionnalDefine in context.additionalDefines) { globalIncludeContent.WriteLineFormat("#define {0} 1", additionnalDefine); } if (renderPipePasses != null) { globalIncludeContent.Write(GetFlattenedTemplateContent(renderPipePasses, new List <string>(), context.additionalDefines)); } if (context.GetData() is ISpaceable) { var spaceable = context.GetData() as ISpaceable; globalIncludeContent.WriteLineFormat("#define {0} 1", spaceable.space == VFXCoordinateSpace.World ? "VFX_WORLD_SPACE" : "VFX_LOCAL_SPACE"); } globalIncludeContent.WriteLineFormat("#include \"{0}/VFXDefines.hlsl\"", renderPipePath); var perPassIncludeContent = new VFXShaderWriter(); perPassIncludeContent.WriteLine("#include \"" + renderPipeCommon + "\""); perPassIncludeContent.WriteLine("#include \"Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.cginc\""); // Per-block includes var includes = Enumerable.Empty <string>(); foreach (var block in context.activeChildrenWithImplicit) { includes = includes.Concat(block.includes); } var uniqueIncludes = new HashSet <string>(includes); foreach (var includePath in uniqueIncludes) { perPassIncludeContent.WriteLine(string.Format("#include \"{0}\"", includePath)); } ReplaceMultiline(stringBuilder, "${VFXGlobalInclude}", globalIncludeContent.builder); ReplaceMultiline(stringBuilder, "${VFXGlobalDeclaration}", globalDeclaration.builder); ReplaceMultiline(stringBuilder, "${VFXPerPassInclude}", perPassIncludeContent.builder); ReplaceMultiline(stringBuilder, "${VFXGeneratedBlockFunction}", blockFunction.builder); ReplaceMultiline(stringBuilder, "${VFXProcessBlocks}", blockCallFunction.builder); var mainParameters = contextData.gpuMapper.CollectExpression(-1).ToArray(); foreach (var match in GetUniqueMatches("\\${VFXLoadParameter:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var loadParameters = GenerateLoadParameter(pattern, mainParameters, expressionToName); ReplaceMultiline(stringBuilder, str, loadParameters.builder); } //< Compute sourceIndex if (stringBuilder.ToString().Contains("${VFXComputeSourceIndex}")) { var r = GenerateComputeSourceIndex(context); ReplaceMultiline(stringBuilder, "${VFXComputeSourceIndex}", r.builder); } //< Load Attribute if (stringBuilder.ToString().Contains("${VFXLoadAttributes}")) { var loadAttributes = GenerateLoadAttribute(".*", context); ReplaceMultiline(stringBuilder, "${VFXLoadAttributes}", loadAttributes.builder); } foreach (var match in GetUniqueMatches("\\${VFXLoadAttributes:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var loadAttributes = GenerateLoadAttribute(pattern, context); ReplaceMultiline(stringBuilder, str, loadAttributes.builder); } //< Store Attribute if (stringBuilder.ToString().Contains("${VFXStoreAttributes}")) { var storeAttribute = GenerateStoreAttribute(".*", context, (uint)linkedEventOut.Count); ReplaceMultiline(stringBuilder, "${VFXStoreAttributes}", storeAttribute.builder); } foreach (var match in GetUniqueMatches("\\${VFXStoreAttributes:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var storeAttributes = GenerateStoreAttribute(pattern, context, (uint)linkedEventOut.Count); ReplaceMultiline(stringBuilder, str, storeAttributes.builder); } foreach (var addionalReplacement in context.additionalReplacements) { ReplaceMultiline(stringBuilder, addionalReplacement.Key, addionalReplacement.Value.builder); } // Replace defines SubstituteMacros(stringBuilder); if (VFXViewPreference.advancedLogs) { Debug.LogFormat("GENERATED_OUTPUT_FILE_FOR : {0}\n{1}", context.ToString(), stringBuilder.ToString()); } return(stringBuilder); }
static private StringBuilder Build(VFXContext context, string templatePath, VFXCompilationMode compilationMode, VFXContextCompiledData contextData) { var stringBuilder = GetFlattenedTemplateContent(templatePath, new List <string>(), context.additionalDefines); var globalDeclaration = new VFXShaderWriter(); globalDeclaration.WriteCBuffer(contextData.uniformMapper, "parameters"); globalDeclaration.WriteTexture(contextData.uniformMapper); var linkedEventOut = context.allLinkedOutputSlot.Where(s => ((VFXModel)s.owner).GetFirstOfType <VFXContext>().CanBeCompiled()).ToList(); globalDeclaration.WriteEventBuffer(eventListOutName, linkedEventOut.Count); //< Block processor var blockFunction = new VFXShaderWriter(); var blockCallFunction = new VFXShaderWriter(); var blockDeclared = new HashSet <string>(); var expressionToName = context.GetData().GetAttributes().ToDictionary(o => new VFXAttributeExpression(o.attrib) as VFXExpression, o => (new VFXAttributeExpression(o.attrib)).GetCodeString(null)); expressionToName = expressionToName.Union(contextData.uniformMapper.expressionToCode).ToDictionary(s => s.Key, s => s.Value); int cpt = 0; foreach (var current in context.activeFlattenedChildrenWithImplicit) { BuildBlock(contextData, linkedEventOut, blockFunction, blockCallFunction, blockDeclared, expressionToName, current, ref cpt); } //< Final composition var renderPipePath = UnityEngine.Experimental.VFX.VFXManager.renderPipeSettingsPath; string renderPipeCommon = "Packages/com.unity.visualeffectgraph/Shaders/Common/VFXCommonCompute.cginc"; string renderPipePasses = null; if (!context.codeGeneratorCompute && !string.IsNullOrEmpty(renderPipePath)) { renderPipeCommon = renderPipePath + "/VFXCommon.cginc"; renderPipePasses = renderPipePath + "/VFXPasses.template"; } var globalIncludeContent = new VFXShaderWriter(); globalIncludeContent.WriteLine("#define NB_THREADS_PER_GROUP 64"); foreach (var attribute in context.GetData().GetAttributes().Where(a => (context.contextType == VFXContextType.Init && context.GetData().IsAttributeStored(a.attrib)) || (context.GetData().IsAttributeUsed(a.attrib, context)))) { globalIncludeContent.WriteLineFormat("#define VFX_USE_{0}_{1} 1", attribute.attrib.name.ToUpper(), "CURRENT"); } foreach (var attribute in context.GetData().GetAttributes().Where(a => context.GetData().IsSourceAttributeUsed(a.attrib, context))) { globalIncludeContent.WriteLineFormat("#define VFX_USE_{0}_{1} 1", attribute.attrib.name.ToUpper(), "SOURCE"); } foreach (var additionnalDefine in context.additionalDefines) { globalIncludeContent.WriteLineFormat("#define {0} 1", additionnalDefine); } if (renderPipePasses != null) { globalIncludeContent.Write(GetFlattenedTemplateContent(renderPipePasses, new List <string>(), context.additionalDefines)); } if (context.GetData() is ISpaceable) { var spaceable = context.GetData() as ISpaceable; globalIncludeContent.WriteLineFormat("#define {0} 1", spaceable.space == VFXCoordinateSpace.World ? "VFX_WORLD_SPACE" : "VFX_LOCAL_SPACE"); } globalIncludeContent.WriteLineFormat("#include \"{0}/VFXDefines.hlsl\"", renderPipePath); var perPassIncludeContent = new VFXShaderWriter(); perPassIncludeContent.WriteLine("#include \"" + renderPipeCommon + "\""); perPassIncludeContent.WriteLine("#include \"Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.cginc\""); // Per-block includes var includes = Enumerable.Empty <string>(); foreach (var block in context.activeFlattenedChildrenWithImplicit) { includes = includes.Concat(block.includes); } var uniqueIncludes = new HashSet <string>(includes); foreach (var includePath in uniqueIncludes) { perPassIncludeContent.WriteLine(string.Format("#include \"{0}\"", includePath)); } ReplaceMultiline(stringBuilder, "${VFXGlobalInclude}", globalIncludeContent.builder); ReplaceMultiline(stringBuilder, "${VFXGlobalDeclaration}", globalDeclaration.builder); ReplaceMultiline(stringBuilder, "${VFXPerPassInclude}", perPassIncludeContent.builder); ReplaceMultiline(stringBuilder, "${VFXGeneratedBlockFunction}", blockFunction.builder); ReplaceMultiline(stringBuilder, "${VFXProcessBlocks}", blockCallFunction.builder); var mainParameters = contextData.gpuMapper.CollectExpression(-1).ToArray(); foreach (var match in GetUniqueMatches("\\${VFXLoadParameter:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var loadParameters = GenerateLoadParameter(pattern, mainParameters, expressionToName); ReplaceMultiline(stringBuilder, str, loadParameters.builder); } //< Compute sourceIndex if (stringBuilder.ToString().Contains("${VFXComputeSourceIndex}")) { var r = GenerateComputeSourceIndex(context); ReplaceMultiline(stringBuilder, "${VFXComputeSourceIndex}", r.builder); } //< Load Attribute if (stringBuilder.ToString().Contains("${VFXLoadAttributes}")) { var loadAttributes = GenerateLoadAttribute(".*", context); ReplaceMultiline(stringBuilder, "${VFXLoadAttributes}", loadAttributes.builder); } foreach (var match in GetUniqueMatches("\\${VFXLoadAttributes:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var loadAttributes = GenerateLoadAttribute(pattern, context); ReplaceMultiline(stringBuilder, str, loadAttributes.builder); } //< Store Attribute if (stringBuilder.ToString().Contains("${VFXStoreAttributes}")) { var storeAttribute = GenerateStoreAttribute(".*", context, (uint)linkedEventOut.Count); ReplaceMultiline(stringBuilder, "${VFXStoreAttributes}", storeAttribute.builder); } foreach (var match in GetUniqueMatches("\\${VFXStoreAttributes:{(.*?)}}", stringBuilder.ToString())) { var str = match.Groups[0].Value; var pattern = match.Groups[1].Value; var storeAttributes = GenerateStoreAttribute(pattern, context, (uint)linkedEventOut.Count); ReplaceMultiline(stringBuilder, str, storeAttributes.builder); } foreach (var addionalReplacement in context.additionalReplacements) { ReplaceMultiline(stringBuilder, addionalReplacement.Key, addionalReplacement.Value.builder); } // Replace defines SubstituteMacros(stringBuilder); if (VFXViewPreference.advancedLogs) { Debug.LogFormat("GENERATED_OUTPUT_FILE_FOR : {0}\n{1}", context.ToString(), stringBuilder.ToString()); } return(stringBuilder); }