internal override void AppendNonBatchablePropertyDeclarations(ShaderStringBuilder builder, string delimiter = ";") { int numLayers = value.layers.Count; if (numLayers > 0) { if (!value.procedural) { // declare regular texture properties (for fallback case) for (int i = 0; i < value.layers.Count; i++) { string layerRefName = value.layers[i].layerRefName; builder.AppendLine( $"TEXTURE2D({layerRefName}); SAMPLER(sampler{layerRefName}); {concretePrecision.ToShaderString()}4 {layerRefName}_TexelSize;"); } } // declare texture stack builder.AppendIndentation(); builder.Append("DECLARE_STACK"); builder.Append((numLayers <= 1) ? "" : numLayers.ToString()); builder.Append("("); builder.Append(referenceName); builder.Append(","); for (int i = 0; i < value.layers.Count; i++) { if (i != 0) { builder.Append(","); } builder.Append(value.layers[i].layerRefName); } builder.Append(")"); builder.Append(delimiter); builder.AppendNewLine(); // declare the actual virtual texture property "variable" as a macro define to the BuildVTProperties function builder.AppendIndentation(); builder.Append("#define "); builder.Append(referenceName); builder.Append(" AddTextureType(BuildVTProperties_"); builder.Append(referenceName); builder.Append("()"); for (int i = 0; i < value.layers.Count; i++) { builder.Append(","); builder.Append("TEXTURETYPE_"); builder.Append(value.layers[i].layerTextureType.ToString().ToUpper()); } builder.Append(")"); builder.AppendNewLine(); } }
internal override string GetPropertyDeclarationString(string delimiter = ";") { ShaderStringBuilder s = new ShaderStringBuilder(); s.AppendLine("Gradient {0}_Definition()", referenceName); using (s.BlockScope()) { string[] colors = new string[8]; for (int i = 0; i < colors.Length; i++) { colors[i] = string.Format("g.colors[{0}] = {1}4(0, 0, 0, 0);", i, concretePrecision.ToShaderString()); } for (int i = 0; i < value.colorKeys.Length; i++) { colors[i] = string.Format("g.colors[{0}] = {1}4({2}, {3}, {4}, {5});" , i , concretePrecision.ToShaderString() , NodeUtils.FloatToShaderValue(value.colorKeys[i].color.r) , NodeUtils.FloatToShaderValue(value.colorKeys[i].color.g) , NodeUtils.FloatToShaderValue(value.colorKeys[i].color.b) , NodeUtils.FloatToShaderValue(value.colorKeys[i].time)); } string[] alphas = new string[8]; for (int i = 0; i < alphas.Length; i++) { alphas[i] = string.Format("g.alphas[{0}] = {1}2(0, 0);", i, concretePrecision.ToShaderString()); } for (int i = 0; i < value.alphaKeys.Length; i++) { alphas[i] = string.Format("g.alphas[{0}] = {1}2({2}, {3});" , i , concretePrecision.ToShaderString() , NodeUtils.FloatToShaderValue(value.alphaKeys[i].alpha) , NodeUtils.FloatToShaderValue(value.alphaKeys[i].time)); } s.AppendLine("Gradient g;"); s.AppendLine("g.type = {0};", (int)value.mode); s.AppendLine("g.colorsLength = {0};", value.colorKeys.Length); s.AppendLine("g.alphasLength = {0};", value.alphaKeys.Length); for (int i = 0; i < colors.Length; i++) { s.AppendLine(colors[i]); } for (int i = 0; i < alphas.Length; i++) { s.AppendLine(alphas[i]); } s.AppendLine("return g;", true); } s.AppendIndentation(); s.Append("#define {0} {0}_Definition()", referenceName); return(s.ToString()); }
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.AppendIndentation(); 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.AppendIndentation(); 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 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.AppendIndentation(); // 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"); }
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { if (asset == null || hasError) { var outputSlots = new List <MaterialSlot>(); GetOutputSlots(outputSlots); var outputPrecision = asset != null ? asset.outputPrecision : ConcretePrecision.Single; 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); foreach (var outSlot in asset.outputs) { sb.AppendLine("{0} {1};", outSlot.concreteValueType.ToShaderString(asset.outputPrecision), GetVariableNameForSlot(outSlot.id)); } var arguments = new List <string>(); foreach (var prop in asset.inputs) { prop.ValidateConcretePrecision(asset.graphPrecision); var inSlotId = m_PropertyIds[m_PropertyGuids.IndexOf(prop.guid.ToString())]; arguments.Add(GetSlotValue(inSlotId, generationMode, prop.concretePrecision)); } // 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.AppendIndentation(); 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.AppendIndentation(); 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 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.AppendIndentation(); 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(); }