浏览代码

Separate usage of 'graph requirements' from 'model requirements' to not pollute the surface input structure.

/main
Tim Cooper 7 年前
当前提交
e5c78ee9
共有 7 个文件被更改,包括 250 次插入224 次删除
  1. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderPBR.template
  2. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderUnlit.template
  3. 85
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  4. 106
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/AbstractLightweightMasterNode.cs
  5. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  6. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MasterNode.cs
  7. 259
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderPBR.template


fixed4 frag (GraphVertexOutput IN) : SV_Target
{
${LocalPixelShader}
SurfaceInputs surfaceInput = (SurfaceInputs)0;
${SurfaceInputs}

return FragmentLightingPBR(
IN.lwCustom,
surfaceInput.worldSpacePosition,
surfaceInput.worldSpaceNormal,
surfaceInput.worldSpaceTangent,
surfaceInput.worldSpaceBiTangent,
surfaceInput.worldSpaceViewDirection,
worldSpacePosition,
worldSpaceNormal,
worldSpaceTangent,
worldSpaceBiTangent,
worldSpaceViewDirection,
IN.fogCoord,
Albedo,

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderUnlit.template


fixed4 frag (GraphVertexOutput IN) : SV_Target
{
${LocalPixelShader}
SurfaceInputs surfaceInput;
${SurfaceInputs}

85
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs


requiresMeshUVs = meshUV
};
reqs = reqs.Union(nodeForRequirements.GetNodeSpecificRequirements());
ListPool<INode>.Release(activeNodeList);
return reqs;
}

protected string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode)
{
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
var surfaceDescription = new ShaderGenerator();
var sufraceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();

vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
surfaceDescription.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescription.Indent();
surfaceDescriptionStruct.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescriptionStruct.Indent();
surfaceDescription.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);
surfaceDescription.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + node.GetVariableNameForSlot(slot.id) + ";", false);
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + node.GetVariableNameForSlot(slot.id) + ";", false);
surfaceDescription.Deindent();
surfaceDescription.AddShaderChunk("};", false);
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
pixelShader.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
pixelShader.Indent();
sufraceDescriptionFunction.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
sufraceDescriptionFunction.Indent();
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceNormal), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceNormal), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceNormal), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceNormal), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceBiTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceBiTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceBiTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceBiTangent), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceViewDirection), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceViewDirection), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceViewDirection), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpacePosition), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpacePosition), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpacePosition), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
sufraceDescriptionFunction.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
var shaderProperties = new PropertyCollector();
CollectShaderProperties(shaderProperties, mode);

if (activeNode is IGeneratesFunction)
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, mode);
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(pixelShader, mode);
(activeNode as IGeneratesBodyCode).GenerateNodeCode(sufraceDescriptionFunction, mode);
pixelShader.AddShaderChunk("SurfaceDescription surface = (SurfaceDescription)0;", false);
sufraceDescriptionFunction.AddShaderChunk("SurfaceDescription surface = (SurfaceDescription)0;", false);
if (node is MasterNode)
{
foreach (var input in node.GetInputSlots<MaterialSlot>())

if (fromNode == null)
continue;
pixelShader.AddShaderChunk(string.Format("surface.{0} = {1};", input.shaderOutputName, fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
sufraceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", input.shaderOutputName, fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
}
}
}

pixelShader.AddShaderChunk(string.Format("surface.{0} = {0};", node.GetVariableNameForSlot(slot.id)), true);
sufraceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {0};", node.GetVariableNameForSlot(slot.id)), true);
pixelShader.AddShaderChunk("return surface;", false);
pixelShader.Deindent();
pixelShader.AddShaderChunk("}", false);
sufraceDescriptionFunction.AddShaderChunk("return surface;", false);
sufraceDescriptionFunction.Deindent();
sufraceDescriptionFunction.AddShaderChunk("}", false);
ListPool<INode>.Release(activeNodeList);
var finalShader = new ShaderGenerator();

finalShader.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
finalShader.AddShaderChunk(graphVertexInput, false);
finalShader.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescription.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
finalShader.AddShaderChunk(pixelShader.GetShaderString(2), false);
finalShader.AddShaderChunk(sufraceDescriptionFunction.GetShaderString(2), false);
finalShader.AddShaderChunk("ENDCG", false);
if (node is MasterNode)

106
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/AbstractLightweightMasterNode.cs


}
}
public override string GetSubShader(ShaderGraphRequirements shaderGraphRequirements)
public override string GetSubShader(ShaderGraphRequirements externalGraphRequiements)
{
var tagsVisitor = new ShaderGenerator();
var blendingVisitor = new ShaderGenerator();

m_MaterialOptions.GetDepthTest(zTestVisitor);
m_MaterialOptions.GetDepthWrite(zWriteVisitor);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
var surfaceInput = new ShaderGenerator();
// bitangent needs normal for x product
if (shaderGraphRequirements.requiresNormal > 0 || shaderGraphRequirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : NORMAL;", ShaderGeneratorNames.ObjectSpaceNormal), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.normal;", ShaderGeneratorNames.ObjectSpaceNormal), false);
surfaceInput.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceNormal), false);
}
if (shaderGraphRequirements.requiresTangent > 0 || shaderGraphRequirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TANGENT;", ShaderGeneratorNames.ObjectSpaceTangent), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.tangent;", ShaderGeneratorNames.ObjectSpaceTangent), false);
surfaceInput.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
surfaceInput.AddShaderChunk(string.Format("float3 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
ShaderGeneratorNames.ObjectSpaceBiTangent,
ShaderGeneratorNames.ObjectSpaceNormal,
ShaderGeneratorNames.ObjectSpaceTangent), false);
}
int interpolatorIndex = GetInterpolatorStartIndex();
if (shaderGraphRequirements.requiresViewDir > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ObjSpaceViewDir(v.vertex);", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
surfaceInput.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
interpolatorIndex++;
}
if (shaderGraphRequirements.requiresPosition > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpacePosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.vertex;", ShaderGeneratorNames.ObjectSpacePosition), false);
surfaceInput.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
interpolatorIndex++;
}
if (shaderGraphRequirements.NeedsTangentSpace())
{
surfaceInput.AddShaderChunk(string.Format("float3x3 tangentSpaceTransform = float3x3({0},{1},{2});",
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ObjectSpaceNormal), false);
}
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresNormal, surfaceInput,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresTangent, surfaceInput,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
var localPixelShader = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresBitangent, surfaceInput,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresViewDir, surfaceInput,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresPosition, surfaceInput,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (shaderGraphRequirements.requiresVertexColor)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
surfaceInput.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}
if (shaderGraphRequirements.requiresScreenPosition)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex)", ShaderGeneratorNames.ScreenPosition), false);
surfaceInput.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
}
foreach (var channel in shaderGraphRequirements.requiresMeshUVs.Distinct())
{
interpolators.AddShaderChunk(string.Format("half4 {0} : TEXCOORD{1};", channel.GetUVName(), interpolatorIndex == 0 ? "" : interpolatorIndex.ToString()), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel), false);
surfaceInput.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", channel.GetUVName()), false);
interpolatorIndex++;
}
ShaderGenerator.GenerateStandardTransforms(
GetInterpolatorStartIndex(),
interpolators,
vertexShader,
localPixelShader,
surfaceInputs,
externalGraphRequiements,
GetNodeSpecificRequirements());
GetLightweightDefinesAndRemap(defines, surfaceOutputRemap);
var templateLocation = ShaderGenerator.GetTemplatePath(GetTemplateName());

var resultShader = subShaderTemplate.Replace("${Defines}", defines.GetShaderString(3));
resultShader = resultShader.Replace("${Interpolators}", interpolators.GetShaderString(3));
resultShader = resultShader.Replace("${VertexShader}", vertexShader.GetShaderString(3));
resultShader = resultShader.Replace("${SurfaceInputs}", surfaceInput.GetShaderString(0));
resultShader = resultShader.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(0));
resultShader = resultShader.Replace("${LocalPixelShader}", localPixelShader.GetShaderString(3));
resultShader = resultShader.Replace("${SurfaceInputs}", surfaceInputs.GetShaderString(3));
resultShader = resultShader.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(3));
resultShader = resultShader.Replace("${Tags}", tagsVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${Blending}", blendingVisitor.GetShaderString(2));

5
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs


// preserve the old current value.
addingSlot.currentValue = foundSlot.currentValue;
}
public virtual ShaderGraphRequirements GetNodeSpecificRequirements()
{
return ShaderGraphRequirements.none;
}
}
}

5
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MasterNode.cs


}
public abstract string GetSubShader(ShaderGraphRequirements shaderGraphRequirements);
public virtual ShaderGraphRequirements GetNodeSpecificRequirements()
{
return ShaderGraphRequirements.none;
}
}
}

259
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs


get { return m_ShaderChunks.Count; }
}
public static void GenerateSpaceTranslationPixelShader(
NeededCoordinateSpace neededSpaces,
public static void GenerateStandardTransforms(
int interpolatorStartIndex,
ShaderGenerator interpolators,
ShaderGenerator vertexShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName,
bool isNormal = false)
ShaderGenerator surfaceInputs,
ShaderGraphRequirements externalGraphRequiements,
ShaderGraphRequirements modelRequiements)
if ((neededSpaces & NeededCoordinateSpace.Object) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", objectSpaceName), false);
}
// step 1:
// *generate needed interpolators
// *generate output from the vertex shader that writes into these interpolators
// *generate the pixel shader code that declares needed variables in the local scope
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
{
if (isNormal)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToWorldNormal({1});", worldSpaceName, objectSpaceName), false);
else
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToWorldDir({1});", worldSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToViewPos({1});", viewSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = mul(tangentSpaceTransform, {1})", tangentSpaceName, objectSpaceName), false);
}
}
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
{
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
var interpolators = new ShaderGenerator();
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
var combinedRequierments = externalGraphRequiements.Union(modelRequiements);
if (shaderGraphRequirements.requiresNormal > 0 || shaderGraphRequirements.requiresBitangent > 0)
if (combinedRequierments.requiresNormal > 0 || combinedRequierments.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : NORMAL;", ShaderGeneratorNames.ObjectSpaceNormal), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.normal;", ShaderGeneratorNames.ObjectSpaceNormal), false);

if (shaderGraphRequirements.requiresTangent > 0 || shaderGraphRequirements.requiresBitangent > 0)
if (combinedRequierments.requiresTangent > 0 || combinedRequierments.requiresBitangent > 0)
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
pixelShader.AddShaderChunk(string.Format("float3 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
ShaderGeneratorNames.ObjectSpaceTangent,
ShaderGeneratorNames.ObjectSpaceNormal), false);
ShaderGeneratorNames.ObjectSpaceNormal,
ShaderGeneratorNames.ObjectSpaceTangent), false);
int interpolatorIndex = 0;
if (shaderGraphRequirements.requiresViewDir > 0)
int interpolatorIndex = interpolatorStartIndex;
if (combinedRequierments.requiresViewDir > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ObjSpaceViewDir(v.vertex);", ShaderGeneratorNames.ObjectSpaceViewDirection), false);

if (shaderGraphRequirements.requiresPosition > 0)
if (combinedRequierments.requiresPosition > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpacePosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.vertex;", ShaderGeneratorNames.ObjectSpacePosition), false);

if (shaderGraphRequirements.NeedsTangentSpace())
if (combinedRequierments.NeedsTangentSpace())
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresNormal, pixelShader,
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresNormal, pixelShader,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal, Dimension.Three, true);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresTangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent, Dimension.Three);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresBitangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent, Dimension.Three);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresViewDir, pixelShader,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection, Dimension.Three);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresPosition, pixelShader,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition, Dimension.Three);
if (combinedRequierments.requiresVertexColor)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}
if (combinedRequierments.requiresScreenPosition)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex));", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
}
foreach (var channel in combinedRequierments.requiresMeshUVs.Distinct())
{
interpolators.AddShaderChunk(string.Format("half4 {0} : TEXCOORD{1};", channel.GetUVName(), interpolatorIndex == 0 ? "" : interpolatorIndex.ToString()), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", channel.GetUVName()), false);
interpolatorIndex++;
}
// step 2
// copy the locally defined values into the surface description
// structure using the requirements for ONLY the shader graph
// additional requirements have come from the lighting model
// and are not needed in the shader graph
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresNormal, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresTangent, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresTangent, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresBitangent, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresBitangent, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresViewDir, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresViewDir, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresPosition, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresPosition, surfaceInputs,
if (shaderGraphRequirements.requiresVertexColor)
if (externalGraphRequiements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", ShaderGeneratorNames.VertexColor), false);
if (externalGraphRequiements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", ShaderGeneratorNames.ScreenPosition), false);
foreach (var channel in combinedRequierments.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} ={0};", channel.GetUVName()), false);
}
public enum Dimension
{
One,
Two,
Three,
Four
}
private static string DimensionToString(Dimension d)
{
switch (d)
{
case Dimension.One:
return string.Empty;
case Dimension.Two:
return "2";
case Dimension.Three:
return "3";
case Dimension.Four:
return "4";
}
return "error";
}
public static void GenerateSpaceTranslationPixelShader(
NeededCoordinateSpace neededSpaces,
ShaderGenerator pixelShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName,
Dimension dimension,
bool isNormal = false)
{
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
if (isNormal)
pixelShader.AddShaderChunk(string.Format("float{0} {1} = UnityObjectToWorldNormal({2});", DimensionToString(dimension), worldSpaceName, objectSpaceName), false);
else
pixelShader.AddShaderChunk(string.Format("float{0} {1} = UnityObjectToWorldDir({2});", DimensionToString(dimension), worldSpaceName, objectSpaceName), false);
if (shaderGraphRequirements.requiresScreenPosition)
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};;", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex)", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
pixelShader.AddShaderChunk(string.Format("float{0} {1} = UnityObjectToViewPos({2});", DimensionToString(dimension), viewSpaceName, objectSpaceName), false);
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
var channel = (UVChannel) uvIndex;
if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
{
interpolators.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.meshUV{1};", channel.GetUVName(), uvIndex), false);
interpolatorIndex++;
}
pixelShader.AddShaderChunk(string.Format("float{0} {1} = mul(tangentSpaceTransform, {2})", DimensionToString(dimension), tangentSpaceName, objectSpaceName), false);
}
public static void GenerateCopyToSurfaceInputs(
NeededCoordinateSpace neededSpaces,
ShaderGenerator pixelShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName)
{
if ((neededSpaces & NeededCoordinateSpace.Object) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", objectSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", worldSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", viewSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0}", tangentSpaceName), false);
}
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
{
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
var interpolators = new ShaderGenerator();
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
ShaderGenerator.GenerateStandardTransforms(
0,
interpolators,
vertexShader,
pixelShader,
surfaceInputs,
shaderGraphRequirements,
ShaderGraphRequirements.none);
var outputs = new ShaderGenerator();
var outputSlot = node.GetOutputSlots<MaterialSlot>().FirstOrDefault();

else
outputs.AddShaderChunk("return 0;", true);
var res = subShaderTemplate.Replace("{0}", interpolators.GetShaderString(0));
res = res.Replace("{1}", vertexShader.GetShaderString(0));
res = res.Replace("{2}", pixelShader.GetShaderString(0));
res = res.Replace("{3}", outputs.GetShaderString(0));
var res = subShaderTemplate.Replace("${Interpolators}", interpolators.GetShaderString(0));
res = res.Replace("${VertexShader}", vertexShader.GetShaderString(0));
res = res.Replace("${LocalPixelShader}", pixelShader.GetShaderString(0));
res = res.Replace("${SurfaceInputs}", surfaceInputs.GetShaderString(0));
res = res.Replace("${SurfaceOutputRemap}", outputs.GetShaderString(0));
return res;
}

struct GraphVertexOutput
{
float4 position : POSITION;
{0}
${Interpolators}
};
GraphVertexOutput vert (GraphVertexInput v)

GraphVertexOutput o;
o.position = UnityObjectToClipPos(v.vertex);
{1}
${VertexShader}
SurfaceInputs surfaceInput;
{2}
${LocalPixelShader}
SurfaceInputs surfaceInput = (SurfaceInputs)0;;
${SurfaceInputs}
{3}
${SurfaceOutputRemap}
}
ENDCG
}

正在加载...
取消
保存