public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { var inputValue = GetSlotValue(InputSlotId, generationMode); var outputValue = GetSlotValue(OutputSlotId, generationMode); sb.AppendLine("{0} {1};", FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(), GetVariableNameForSlot(OutputSlotId)); if (!generationMode.IsPreview()) { sb.TryAppendIndentation(); sb.Append("{0} _{1}_Flip = {0} ({2}", FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(), GetVariableNameForNode(), Convert.ToInt32(m_RedChannel)); if (channelCount > 1) { sb.Append(", {0}", Convert.ToInt32(m_GreenChannel)); } if (channelCount > 2) { sb.Append(", {0}", Convert.ToInt32(m_BlueChannel)); } if (channelCount > 3) { sb.Append(", {0}", Convert.ToInt32(m_AlphaChannel)); } sb.Append(");"); sb.AppendNewLine(); } sb.AppendLine("{0}({1}, _{2}_Flip, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue); }
void AppendVtSample(ShaderStringBuilder sb, string propertiesName, string vtInputVariable, string infoVariable, int layerIndex, string outputVariableName) { sb.TryAppendIndentation(); sb.Append(outputVariableName); sb.Append(" = "); sb.Append("SampleVTLayerWithTextureType("); sb.Append(propertiesName); sb.Append(", "); sb.Append(vtInputVariable); sb.Append(", "); sb.Append(infoVariable); sb.Append(", "); sb.Append(layerIndex.ToString()); sb.Append(");"); sb.AppendNewLine(); }
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { var outputGraphPrecision = asset?.outputGraphPrecision ?? GraphPrecision.Single; var outputPrecision = outputGraphPrecision.ToConcrete(concretePrecision); if (asset == null || hasError) { var outputSlots = new List <MaterialSlot>(); GetOutputSlots(outputSlots); foreach (var slot in outputSlots) { sb.AppendLine($"{slot.concreteValueType.ToShaderString(outputPrecision)} {GetVariableNameForSlot(slot.id)} = {slot.GetDefaultValue(GenerationMode.ForReals)};"); } return; } var inputVariableName = $"_{GetVariableNameForNode()}"; GenerationUtils.GenerateSurfaceInputTransferCode(sb, asset.requirements, asset.inputStructName, inputVariableName); // declare output variables foreach (var outSlot in asset.outputs) { sb.AppendLine("{0} {1};", outSlot.concreteValueType.ToShaderString(outputPrecision), GetVariableNameForSlot(outSlot.id)); } var arguments = new List <string>(); foreach (AbstractShaderProperty prop in asset.inputs) { // setup the property concrete precision (fallback to node concrete precision when it's switchable) prop.SetupConcretePrecision(this.concretePrecision); var inSlotId = m_PropertyIds[m_PropertyGuids.IndexOf(prop.guid.ToString())]; arguments.Add(GetSlotValue(inSlotId, generationMode, prop.concretePrecision)); if (prop.isConnectionTestable) { arguments.Add(IsSlotConnected(inSlotId) ? "true" : "false"); } } var dropdowns = asset.dropdowns; foreach (var dropdown in dropdowns) { var name = GetDropdownEntryName(dropdown.referenceName); if (dropdown.ContainsEntry(name)) { arguments.Add(dropdown.IndexOfName(name).ToString()); } else { arguments.Add(dropdown.value.ToString()); } } // pass surface inputs through arguments.Add(inputVariableName); foreach (var outSlot in asset.outputs) { arguments.Add(GetVariableNameForSlot(outSlot.id)); } foreach (var feedbackSlot in asset.vtFeedbackVariables) { string feedbackVar = GetVariableNameForNode() + "_" + feedbackSlot; sb.AppendLine("{0} {1};", ConcreteSlotValueType.Vector4.ToShaderString(ConcretePrecision.Single), feedbackVar); arguments.Add(feedbackVar); } sb.TryAppendIndentation(); sb.Append(asset.functionName); sb.Append("("); bool firstArg = true; foreach (var arg in arguments) { if (!firstArg) { sb.Append(", "); } firstArg = false; sb.Append(arg); } sb.Append(");"); sb.AppendNewLine(); }
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { bool success = false; if (IsSlotConnected(VirtualTextureInputId)) { var vtProperty = GetSlotProperty(VirtualTextureInputId) as VirtualTextureShaderProperty; if (vtProperty != null) { var layerOutputVariables = new List <string>(); int layerCount = vtProperty.value.layers.Count; for (int i = 0; i < layerCount; i++) { if (IsSlotConnected(OutputSlotIds[i])) { // declare output variables up front string layerOutputVariable = GetVariableNameForSlot(OutputSlotIds[i]); sb.AppendLine("$precision4 " + layerOutputVariable + ";"); layerOutputVariables.Add(layerOutputVariable); } } if (layerOutputVariables.Count > 0) { // assign feedback variable sb.TryAppendIndentation(); if (!noFeedback) { sb.Append("float4 "); sb.Append(GetFeedbackVariableName()); sb.Append(" = "); } sb.Append(GetFunctionName(out var unused)); sb.Append("("); sb.Append(GetSlotValue(UVInputId, generationMode)); switch (lodCalculation) { case LodCalculation.VtLevel_Lod: case LodCalculation.VtLevel_Bias: sb.Append(", "); sb.Append((lodCalculation == LodCalculation.VtLevel_Lod) ? GetSlotValue(LODInputId, generationMode) : GetSlotValue(BiasInputId, generationMode)); break; case LodCalculation.VtLevel_Derivatives: sb.Append(", "); sb.Append(GetSlotValue(DxInputId, generationMode)); sb.Append(", "); sb.Append(GetSlotValue(DyInputId, generationMode)); break; } sb.Append(", "); sb.Append(vtProperty.referenceName); foreach (string layerOutputVariable in layerOutputVariables) { sb.Append(", "); sb.Append(layerOutputVariable); } sb.Append(");"); sb.AppendNewLine(); success = true; } } } if (!success) { // set all outputs to zero for (int i = 0; i < kMaxLayers; i++) { if (IsSlotConnected(OutputSlotIds[i])) { // declare output variables up front string layerOutputVariable = GetVariableNameForSlot(OutputSlotIds[i]); sb.AppendLine("$precision4 " + layerOutputVariable + " = 0;"); } } // TODO: should really just disable feedback in this case (need different feedback interface to do this) sb.AppendLine("$precision4 " + GetFeedbackVariableName() + " = 1;"); } }
public static void GetKeywordPermutationDeclarations(ShaderStringBuilder sb, List <List <KeyValuePair <ShaderKeyword, int> > > permutations) { if (permutations.Count == 0) { return; } for (int p = 0; p < permutations.Count; p++) { // ShaderStringBuilder.Append doesnt apply indentation sb.TryAppendIndentation(); // Append correct if bool isLast = false; if (p == 0) { sb.Append("#if "); } else if (p == permutations.Count - 1) { sb.Append("#else"); isLast = true; } else { sb.Append("#elif "); } // Last permutation is always #else if (!isLast) { // Track whether && is required bool appendAnd = false; // Iterate all keywords that are part of the permutation for (int i = 0; i < permutations[p].Count; i++) { // When previous keyword was inserted subsequent requires && string and = appendAnd ? " && " : string.Empty; switch (permutations[p][i].Key.keywordType) { case KeywordType.Enum: { sb.Append($"{and}defined({permutations[p][i].Key.referenceName}_{permutations[p][i].Key.entries[permutations[p][i].Value].referenceName})"); appendAnd = true; break; } case KeywordType.Boolean: { // HLSL does not support a !value predicate if (permutations[p][i].Value != 0) { continue; } sb.Append($"{and}defined({permutations[p][i].Key.referenceName})"); appendAnd = true; break; } default: throw new ArgumentOutOfRangeException(); } } } sb.AppendNewLine(); // Define the matching permutation keyword sb.IncreaseIndent(); sb.AppendLine($"#define KEYWORD_PERMUTATION_{p}"); sb.DecreaseIndent(); } // End statement sb.AppendLine("#endif"); }