您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

189 行
6.2 KiB

using UnityEngine.Graphing;
using System.Linq;
using System.Collections;
using System;
namespace UnityEngine.MaterialGraph
{
public abstract class FunctionNInNOut : AbstractMaterialNode, IGeneratesBodyCode
{
public FunctionNInNOut()
{
name = "FunctionNInNOut";
UpdateNodeAfterDeserialization();
}
public override void UpdateNodeAfterDeserialization()
{
base.UpdateNodeAfterDeserialization();
foreach (var slot in GetSlots<MaterialSlot>())
{
slot.showValue = true;
}
}
public int AddSlot(string displayName, string nameInShader, SlotType slotType, SlotValueType valueType, Vector4 defaultValue)
{
int nextSlotId;
if (slotType == SlotType.Output)
nextSlotId = -( GetOutputSlots<MaterialSlot>().Count() + 1 );
else
nextSlotId = GetInputSlots<MaterialSlot>().Count() + 1;
bool useDefaultValue = (valueType != SlotValueType.Texture2D);
AddSlot(new MaterialSlot(nextSlotId, displayName, nameInShader, slotType, valueType, defaultValue, useDefaultValue));
return nextSlotId;
}
public void RemoveOutputSlot()
{
var lastSlotId = -GetOutputSlots<ISlot>().Count();
RemoveSlotById(lastSlotId);
}
public void RemoveInputSlot()
{
var lastSlotId = GetInputSlots<ISlot>().Count();
RemoveSlotById(lastSlotId);
}
private void RemoveSlotById(int slotID)
{
if (slotID == 0)
return;
RemoveSlot(slotID);
}
public string GetSlotTypeName(int slotId)
{
return ConvertConcreteSlotValueTypeToString(FindSlot<MaterialSlot>(slotId).concreteValueType);
}
public ConcreteSlotValueType GetSlotValueType(int slotId)
{
return FindSlot<MaterialSlot>(slotId).concreteValueType;
}
protected string GetShaderOutputName(int slotId)
{
return FindSlot<MaterialSlot>(slotId).shaderOutputName;
}
// Must override this
protected abstract string GetFunctionName();
private string GetFunctionParameters()
{
string param = "";
int remainingParams = GetSlots<ISlot>().Count();
foreach (ISlot inSlot in GetSlots<ISlot>())
{
if (inSlot.isOutputSlot)
param += "out ";
if (FindSlot<MaterialSlot>(inSlot.id).concreteValueType != ConcreteSlotValueType.Texture2D
&& FindSlot<MaterialSlot>(inSlot.id).concreteValueType != ConcreteSlotValueType.SamplerState
)
param += precision;
param += GetSlotTypeName(inSlot.id) + " ";
param += GetShaderOutputName(inSlot.id);
if (remainingParams > 1)
param += ", ";
--remainingParams;
}
return param;
}
private string GetFunctionCallParameters(GenerationMode generationMode)
{
string param = "";
int remainingParams = GetSlots<ISlot>().Count();
foreach (ISlot inSlot in GetSlots<ISlot>())
{
if (FindSlot<MaterialSlot>(inSlot.id).concreteValueType == ConcreteSlotValueType.SamplerState)
param += GetSamplerInput(inSlot.id);
else
param += GetSlotValue(inSlot.id, generationMode);
if (remainingParams > 1)
param += ", ";
--remainingParams;
}
return param;
}
protected string GetFunctionPrototype()
{
return "inline " + "void" + " " + GetFunctionName() +
" (" +
GetFunctionParameters() +
")";
}
private string GetFunctionCall(GenerationMode generationMode)
{
string prefix = "";
string sufix = "";
foreach (ISlot slot in GetInputSlots<MaterialSlot>())
{
if (GetSlotValueType(slot.id) == ConcreteSlotValueType.Texture2D || GetSlotValueType(slot.id) == ConcreteSlotValueType.SamplerState)
{
prefix = "#ifdef UNITY_COMPILER_HLSL \n";
sufix = "\n #endif";
}
}
return prefix + GetFunctionName() +
" (" +
GetFunctionCallParameters(generationMode) +
");" + sufix;
}
private string GetOutputDeclaration()
{
string outDeclaration = "";
foreach (MaterialSlot outSlot in GetOutputSlots<MaterialSlot>())
{
outDeclaration += "\n " + precision + GetSlotTypeName(outSlot.id) + " " + GetVariableNameForSlot(outSlot.id) + ";\n";
}
return outDeclaration;
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetOutputDeclaration(), false);
outputString.AddShaderChunk(GetFunctionCall(generationMode), false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public string GetSamplerInput(int slotID)
{
//default sampler if no input is provided
var samplerName = "my_linear_repeat_sampler";
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(slotID);
if (samplerSlot != null)
{
var edgesSampler = owner.GetEdges(samplerSlot.slotReference).ToList();
if (edgesSampler.Count > 0)
{
var edge = edgesSampler[0];
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(edge.outputSlot.nodeGuid);
samplerName = ShaderGenerator.AdaptNodeOutput(fromNode, edge.outputSlot.slotId, ConcreteSlotValueType.SamplerState, true);
}
}
return samplerName;
}
}
}