// This entry point handles adding our upstream antecedents to the generator's list of active nodes. // Custom Interpolator Nodes have no way of expressing that their Custom Interpolator Block is a dependent within existing generator code. internal void ProcessExistingStackData(List <AbstractMaterialNode> vertexNodes, List <MaterialSlot> vertexSlots, List <AbstractMaterialNode> pixelNodes, IActiveFieldsSet activeFields) { if (CustomInterpolatorUtils.generatorSkipFlag) { return; } bool needsGraphFeature = false; // departing from current generation code, we will select what to generate based on some graph analysis. foreach (var cin in pixelNodes.OfType <CustomInterpolatorNode>().ToList()) { // The CustomBlockNode's subtree. var anties = GetAntecedents(cin.e_targetBlockNode)?.Where(a => !vertexNodes.Contains(a) && !pixelNodes.Contains(a)); // cin contains an inlined value, so there is nothing to do. if (anties == null) { continue; } else if (isNodePreview) { foreach (var ant in anties) { // sorted insertion, based on dependencies already present in pixelNodes (an issue because we're faking for the preview). InsertAntecedent(pixelNodes, ant); } } else // it's a full compile and cin isn't inlined, so do all the things. { if (!customBlockNodes.Contains(cin.e_targetBlockNode)) { activeFields.AddAll(cin.e_targetBlockNode.descriptor); // add the BlockFieldDescriptor for VertexDescription customBlockNodes.Add(cin.e_targetBlockNode); } // vertex nodes should not require hierarchical insertion, but if they do (master preview is failing)-- use the "InsertAntecedent" solve above. vertexNodes.AddRange(anties); if (!vertexNodes.Contains(cin.e_targetBlockNode)) { vertexNodes.Add(cin.e_targetBlockNode); } if (!vertexSlots.Contains(cin.e_targetBlockNode.FindSlot <MaterialSlot>(0))) { vertexSlots.Add(cin.e_targetBlockNode.FindSlot <MaterialSlot>(0)); } needsGraphFeature = true; } } // if a target has allowed custom interpolators, it should expect that the vertex feature can be forced on. if (needsGraphFeature) { activeFields.AddAll(Fields.GraphVertex); } }
static void AddRequiredFields( List <string> passRequiredFields, // fields the pass requires IActiveFieldsSet activeFields) { if (passRequiredFields != null) { foreach (var requiredField in passRequiredFields) { activeFields.AddAll(requiredField); } } }
// This entry point is to inject custom interpolator fields into the appropriate structs for struct generation. internal List <StructDescriptor> CopyModifyExistingPassStructs(IEnumerable <StructDescriptor> passStructs, IActiveFieldsSet activeFields) { if (CustomInterpolatorUtils.generatorSkipFlag) { return(passStructs.ToList()); } var newPassStructs = new List <StructDescriptor>(); // StructDescriptor is (kind-of) immutable, so we need to do some copy/modify shenanigans to make this work. foreach (var ps in passStructs) { if (ps.populateWithCustomInterpolators) { var agg = new List <FieldDescriptor>(); foreach (var cib in customBlockNodes) { var fd = new FieldDescriptor(ps.name, cib.customName, "", ShaderValueTypeFrom((int)cib.customWidth), subscriptOptions: StructFieldOptions.Generated); agg.Add(fd); activeFields.AddAll(fd); } newPassStructs.Add(new StructDescriptor { name = ps.name, packFields = ps.packFields, fields = ps.fields.Union(agg).ToArray() }); } else { newPassStructs.Add(ps); } } foreach (var cid in customBlockNodes.Select(bn => bn.descriptor)) { activeFields.AddAll(cid); } return(newPassStructs); }
public static void GenerateVertexDescriptionStruct(ShaderStringBuilder builder, List <MaterialSlot> slots, string structName = k_VertexDescriptionStructName, IActiveFieldsSet activeFields = null) { builder.AppendLine("struct {0}", structName); using (builder.BlockSemicolonScope()) { foreach (var slot in slots) { string hlslName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName); builder.AppendLine("{0} {1};", slot.concreteValueType.ToShaderString(slot.owner.concretePrecision), hlslName); if (activeFields != null) { activeFields.AddAll(structName + "." + hlslName); } } } }
public static void GenerateSurfaceDescriptionStruct(ShaderStringBuilder surfaceDescriptionStruct, List <MaterialSlot> slots, string structName = "SurfaceDescription", IActiveFieldsSet activeFields = null, bool useIdsInNames = false) { surfaceDescriptionStruct.AppendLine("struct {0}", structName); using (surfaceDescriptionStruct.BlockSemicolonScope()) { foreach (var slot in slots) { string hlslName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName); if (useIdsInNames) { hlslName = $"{hlslName}_{slot.id}"; } surfaceDescriptionStruct.AppendLine("{0} {1};", slot.concreteValueType.ToShaderString(slot.owner.concretePrecision), hlslName); if (activeFields != null) { activeFields.AddAll(structName + "." + hlslName); } } } }