浏览代码

First pass HDRP lit vertex anim

Works, issues to fix:
    screen position and view direction are not accesible in vertex shader
    unlit shader needs update
/main
Chris Tchou 7 年前
当前提交
f37d6cf2
共有 7 个文件被更改,包括 504 次插入142 次删除
  1. 73
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template
  2. 251
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRSubShader.cs
  3. 235
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs
  4. 19
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitSubShader.cs
  5. 4
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/VertMesh.hlsl
  6. 4
      com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs
  7. 60
      com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs

73
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template


// this modifies the normal calculation
// #define SURFACE_GRADIENT
// This shader support vertex modification (or not)
// TODO - move to PBR shader control
// #define HAVE_VERTEX_MODIFICATION
// If we use subsurface scattering, enable output split lighting (for forward pass)
#if defined(_MATID_SSS) && !defined(_SURFACE_TYPE_TRANSPARENT)
#define OUTPUT_SPLIT_LIGHTING

$VaryingsMeshToPS.texCoord3: #define VARYINGS_NEED_TEXCOORD3
$VaryingsMeshToPS.color: #define VARYINGS_NEED_COLOR
$VaryingsMeshToPS.cullFace: #define VARYINGS_NEED_CULLFACE
$features.modifyMesh: #define HAVE_MESH_MODIFICATION
//-------------------------------------------------------------------------------------
// End Defines
//-------------------------------------------------------------------------------------

// End graph generated code
//-------------------------------------------------------------------------------------
// TODO: Do we want to build include functionality for sharing these preprocessed functions across templates?
#ifdef HAVE_MESH_MODIFICATION
VertexDescriptionInputs AttributesMeshToVertexDescriptionInputs(AttributesMesh input)
{
VertexDescriptionInputs output;
ZERO_INITIALIZE(VertexDescriptionInputs, output);
$VertexDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = input.normalOS;
$VertexDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = TransformObjectToWorldNormal(input.normalOS);
$VertexDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = TransformWorldToViewDir(output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
$VertexDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = input.tangentOS;
$VertexDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = TransformObjectToWorldDir(input.tangentOS.xyz);
$VertexDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
$VertexDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
$VertexDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = normalize(cross(input.normalOS, input.tangentOS) * (input.tangentOS.w > 0.0f ? 1.0f : -1.0f) * GetOddNegativeScale());
$VertexDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = TransformObjectToWorldDir(output.ObjectSpaceBiTangent);
$VertexDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
$VertexDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
$VertexDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = input.positionOS;
$VertexDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = TransformObjectToWorld(input.positionOS);
$VertexDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = TransformWorldToView(output.WorldSpacePosition);
$VertexDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
// TODO: support view direction in vertex shader
// $VertexDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = normalize(viewWS);
// $VertexDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = mul((float3x3) unity_WorldToObject, output.WorldSpaceViewDirection);
// $VertexDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = mul((float3x3) UNITY_MATRIX_V, output.WorldSpaceViewDirection);
// $VertexDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
// $VertexDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
// TODO: positionSS is SV_Position, graph input expects screenPosition to be 0..1 across the active viewport (?)
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = 0.0f; // need to calculate projected screen position
$VertexDescriptionInputs.uv0: output.uv0 = float4(input.uv0, 0.0f, 0.0f);
$VertexDescriptionInputs.uv1: output.uv1 = float4(input.uv1, 0.0f, 0.0f);
$VertexDescriptionInputs.uv2: output.uv2 = float4(input.uv2, 0.0f, 0.0f);
$VertexDescriptionInputs.uv3: output.uv3 = float4(input.uv3, 0.0f, 0.0f);
$VertexDescriptionInputs.VertexColor: output.VertexColor = input.color;
return output;
}
AttributesMesh ApplyMeshModification(AttributesMesh input)
{
// build graph inputs
VertexDescriptionInputs vertexDescriptionInputs = AttributesMeshToVertexDescriptionInputs(input);
// evaluate vertex graph
VertexDescription vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
// copy graph output to the results
$VertexDescription.Position: input.positionOS = vertexDescription.Position;
return input;
}
#endif // HAVE_MESH_MODIFICATION
// TODO: Do we want to build include functionality for sharing these preprocessed functions across templates?
FragInputs BuildFragInputs(VaryingsMeshToPS input)
{
FragInputs output;

$SurfaceDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
// TODO: positionSS is SV_Position, graph input expects screenPosition to be 0..1 across the active viewport (?)
$SurfaceDescriptionInputs.screenPosition: output.screenPosition = input.positionSS;
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = input.positionSS;
$SurfaceDescriptionInputs.uv0: output.uv0 = float4(input.texCoord0, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv1: output.uv1 = float4(input.texCoord1, 0.0f, 0.0f);

$SurfaceDescriptionInputs.vertexColor: output.vertexColor = input.color;
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
return output;
}

//-------------------------------------------------------------------------------------
ENDHLSL
}
}

251
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRSubShader.cs


PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};
Pass m_PassGBufferWithPrepass = new Pass()

PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};
Pass m_PassMETA = new Pass()

"AttributesMesh.uv1",
"AttributesMesh.color",
"AttributesMesh.uv2", // SHADERPASS_LIGHT_TRANSPORT always uses uv2
// "FragInputs.worldToTangent",
// "FragInputs.positionWS",
},
PixelShaderSlots = new List<int>()
{

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
// VertexShaderSlots = new List<int>()
// {
// PBRMasterNode.PositionSlotId
// }
};
Pass m_PassShadowCaster = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

{
"FragInputs.positionWS",
},
PixelShaderSlots = new List<int>()
{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
StencilOverride = new List<string>()
{
"// If velocity pass (motion vectors) is enabled we tag the stencil so it don't perform CameraMotionVelocity",

" Comp Always",
" Pass Replace",
"}"
}
},
PixelShaderSlots = new List<int>()
{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassDistortion = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassTransparentDepthPrepass = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassTransparentBackface = new Pass()

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassForward = new Pass()

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassTransparentDepthPostpass = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
private static string GetVariantDefines(PBRMasterNode masterNode)

// #pragma shader_feature _HEIGHTMAP
// #pragma shader_feature _TANGENTMAP
// #pragma shader_feature _ANISOTROPYMAP
// #pragma shader_feature _DETAIL_MAP // MOVE to a node
// #pragma shader_feature _SUBSURFACE_RADIUS_MAP
// #pragma shader_feature _THICKNESSMAP
// #pragma shader_feature _SPECULARCOLORMAP

return false;
}
// grab all of the active nodes
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var graphRequirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.Fragment);
var pixelRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false);
var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);
// Function Registry tracks functions to remove duplicates, it wraps a string builder that stores the combined function string
// TODO: this can be a shared function for all HDRP master nodes -- From here through GraphUtil.GenerateSurfaceDescription(..)
// TODO: this can be a shared function -- From here through GraphUtil.GenerateSurfaceDescription(..)
var activeSlots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
{
MaterialSlot slot = masterNode.FindSlot<MaterialSlot>(id);
if (slot != null)
{
activeSlots.Add(slot);
}
}
var pixelSlots = HDSubShaderUtilities.FindSlotsOnMasterNode(pass.PixelShaderSlots, masterNode);
var vertexSlots = HDSubShaderUtilities.FindSlotsOnMasterNode(pass.VertexShaderSlots, masterNode);
// properties used by either pixel and vertex shader
PropertyCollector sharedProperties = new PropertyCollector();
string graphInputStructName = "SurfaceDescriptionInputs";
string graphOutputStructName = "SurfaceDescription";
string graphEvalFunctionName = "SurfaceDescriptionFunction";
ShaderStringBuilder graphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder graphOutputs = new ShaderStringBuilder();
PropertyCollector graphProperties = new PropertyCollector();
string pixelGraphInputStructName = "SurfaceDescriptionInputs";
string pixelGraphOutputStructName = "SurfaceDescription";
string pixelGraphEvalFunctionName = "SurfaceDescriptionFunction";
ShaderStringBuilder pixelGraphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder pixelGraphOutputs = new ShaderStringBuilder();
HashSet<string> activeFields = new HashSet<string>();
// build initial requirements
HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, pixelRequirements);
HashSet<string> activeFields = new HashSet<string>();
GraphUtil.GenerateSurfaceDescriptionStruct(graphOutputs, activeSlots, true);
//GraphUtil.GenerateSurfaceDescriptionStruct(graphOutputs, activeSlots, true, graphOutputStructName, activeFields);
GraphUtil.GenerateSurfaceDescriptionStruct(pixelGraphOutputs, pixelSlots, true, pixelGraphOutputStructName, activeFields);
activeNodeList,
pixelNodes,
graphEvalFunction,
pixelGraphEvalFunction,
graphProperties,
graphRequirements, // TODO : REMOVE UNUSED
sharedProperties,
pixelRequirements, // TODO : REMOVE UNUSED
graphEvalFunctionName,
graphOutputStructName,
pixelGraphEvalFunctionName,
pixelGraphOutputStructName,
activeSlots,
graphInputStructName);
pixelSlots,
pixelGraphInputStructName);
string vertexGraphInputStructName = "VertexDescriptionInputs";
string vertexGraphOutputStructName = "VertexDescription";
string vertexGraphEvalFunctionName = "VertexDescriptionFunction";
ShaderStringBuilder vertexGraphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder vertexGraphOutputs = new ShaderStringBuilder();
// check for vertex animation -- enables HAVE_VERTEX_MODIFICATION
bool vertexActive = false;
if (masterNode.IsSlotConnected(PBRMasterNode.PositionSlotId))
{
vertexActive = true;
activeFields.Add("features.modifyMesh");
HDRPShaderStructs.AddActiveFieldsFromVertexGraphRequirements(activeFields, vertexRequirements);
// -------------------------------------
// Generate Output structure for Vertex Description function
GraphUtil.GenerateVertexDescriptionStruct(vertexGraphOutputs, vertexSlots, vertexGraphOutputStructName, activeFields);
// -------------------------------------
// Generate Vertex Description function
GraphUtil.GenerateVertexDescriptionFunction(
masterNode.owner as AbstractMaterialGraph,
vertexGraphEvalFunction,
functionRegistry,
sharedProperties,
mode,
vertexNodes,
vertexSlots,
vertexGraphInputStructName,
vertexGraphEvalFunctionName,
vertexGraphOutputStructName);
}
var blendCode = new ShaderStringBuilder();
var cullCode = new ShaderStringBuilder();

}
}
if (pass.PixelShaderSlots != null)
{
foreach (var slotId in pass.PixelShaderSlots)
{
var slot = masterNode.FindSlot<MaterialSlot>(slotId);
if (slot != null)
{
var rawSlotName = slot.RawDisplayName().ToString();
var descriptionVar = string.Format("{0}.{1}", graphOutputStructName, rawSlotName);
activeFields.Add(descriptionVar);
}
}
}
HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
// apply dependencies to the active fields, and build interpolators (TODO: split this function)
var graphInputs = new ShaderGenerator();
graphInputs,
graphRequirements,
pass.RequiredFields,
CoordinateSpace.World,
activeFields);
// debug output all active fields

interpolatorDefines.AddShaderChunk("// " + f);
}
}
// build graph inputs structures
ShaderGenerator pixelGraphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.SurfaceDescriptionInputs), activeFields, pixelGraphInputs);
ShaderGenerator vertexGraphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.VertexDescriptionInputs), activeFields, vertexGraphInputs);
ShaderGenerator defines = new ShaderGenerator();
{

// build graph code
var graph = new ShaderGenerator();
graph.AddShaderChunk("// Graph Inputs");
graph.Indent();
graph.AddGenerator(graphInputs);
graph.Deindent();
graph.AddShaderChunk("// Graph Outputs");
graph.Indent();
graph.AddShaderChunk(graphOutputs.ToString());
//graph.AddGenerator(graphOutputs);
graph.Deindent();
graph.AddShaderChunk("// Graph Properties (uniform inputs)");
graph.AddShaderChunk(graphProperties.GetPropertiesDeclaration(1));
graph.AddShaderChunk("// Graph Node Functions");
graph.AddShaderChunk(graphNodeFunctions.ToString());
graph.AddShaderChunk("// Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(graphEvalFunction.ToString());
//graph.AddGenerator(graphEvalFunction);
graph.Deindent();
{
graph.AddShaderChunk("// Shared Graph Properties (uniform inputs)");
graph.AddShaderChunk(sharedProperties.GetPropertiesDeclaration(1));
graph.AddShaderChunk("// Shared Graph Node Functions");
graph.AddShaderChunk(graphNodeFunctions.ToString());
if (vertexActive)
{
graph.AddShaderChunk("// Vertex Graph Inputs");
graph.Indent();
graph.AddGenerator(vertexGraphInputs);
graph.Deindent();
graph.AddShaderChunk("// Vertex Graph Outputs");
graph.Indent();
graph.AddShaderChunk(vertexGraphOutputs.ToString());
graph.Deindent();
graph.AddShaderChunk("// Vertex Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(vertexGraphEvalFunction.ToString());
graph.Deindent();
}
graph.AddShaderChunk("// Pixel Graph Inputs");
graph.Indent();
graph.AddGenerator(pixelGraphInputs);
graph.Deindent();
graph.AddShaderChunk("// Pixel Graph Outputs");
graph.Indent();
graph.AddShaderChunk(pixelGraphOutputs.ToString());
graph.Deindent();
graph.AddShaderChunk("// Pixel Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(pixelGraphEvalFunction.ToString());
graph.Deindent();
}
// build the hash table of all named fragments TODO: could make this Dictionary<string, ShaderGenerator / string> ?
Dictionary<string, string> namedFragments = new Dictionary<string, string>();

235
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs


struct AttributesMesh
{
[Semantic("POSITION")] Vector3 positionOS;
[Semantic("NORMAL")][Optional] Vector3 normalOS;
[Semantic("TANGENT")][Optional] Vector4 tangentOS; // Stores bi-tangent sign in w
[Semantic("TEXCOORD0")][Optional] Vector2 uv0;
[Semantic("TEXCOORD1")][Optional] Vector2 uv1;
[Semantic("TEXCOORD2")][Optional] Vector2 uv2;
[Semantic("TEXCOORD3")][Optional] Vector2 uv3;
[Semantic("COLOR")][Optional] Vector4 color;
[Semantic("NORMAL")][Optional] Vector3 normalOS;
[Semantic("TANGENT")][Optional] Vector4 tangentOS; // Stores bi-tangent sign in w
[Semantic("TEXCOORD0")][Optional] Vector2 uv0;
[Semantic("TEXCOORD1")][Optional] Vector2 uv1;
[Semantic("TEXCOORD2")][Optional] Vector2 uv2;
[Semantic("TEXCOORD3")][Optional] Vector2 uv3;
[Semantic("COLOR")][Optional] Vector4 color;
};
struct VaryingsMeshToPS

};
};
struct SurfaceDescriptionInputs
// this describes the input to the pixel shader graph eval
public struct SurfaceDescriptionInputs
{
[Optional] Vector3 ObjectSpaceNormal;
[Optional] Vector3 ViewSpaceNormal;

[Optional] Vector3 WorldSpacePosition;
[Optional] Vector3 TangentSpacePosition;
[Optional] Vector4 screenPosition;
[Optional] Vector4 ScreenPosition;
[Optional] Vector4 vertexColor;
[Optional] Vector4 VertexColor;
public static Dependency[] dependencies = new Dependency[]
{

new Dependency("SurfaceDescriptionInputs.TangentSpaceViewDirection", "SurfaceDescriptionInputs.WorldSpaceBiTangent"),
new Dependency("SurfaceDescriptionInputs.TangentSpaceViewDirection", "SurfaceDescriptionInputs.WorldSpaceNormal"),
new Dependency("SurfaceDescriptionInputs.screenPosition", "FragInputs.positionSS"),
new Dependency("SurfaceDescriptionInputs.ScreenPosition", "FragInputs.positionSS"),
new Dependency("SurfaceDescriptionInputs.vertexColor", "FragInputs.color"),
new Dependency("SurfaceDescriptionInputs.VertexColor", "FragInputs.color"),
static void AddActiveFieldsFromGraphRequirements(HashSet<string> activeFields, ShaderGraphRequirements requirements)
// this describes the input to the pixel shader graph eval
public struct VertexDescriptionInputs
{
[Optional] Vector3 ObjectSpaceNormal;
[Optional] Vector3 ViewSpaceNormal;
[Optional] Vector3 WorldSpaceNormal;
[Optional] Vector3 TangentSpaceNormal;
[Optional] Vector3 ObjectSpaceTangent;
[Optional] Vector3 ViewSpaceTangent;
[Optional] Vector3 WorldSpaceTangent;
[Optional] Vector3 TangentSpaceTangent;
[Optional] Vector3 ObjectSpaceBiTangent;
[Optional] Vector3 ViewSpaceBiTangent;
[Optional] Vector3 WorldSpaceBiTangent;
[Optional] Vector3 TangentSpaceBiTangent;
[Optional] Vector3 ObjectSpaceViewDirection;
[Optional] Vector3 ViewSpaceViewDirection;
[Optional] Vector3 WorldSpaceViewDirection;
[Optional] Vector3 TangentSpaceViewDirection;
[Optional] Vector3 ObjectSpacePosition;
[Optional] Vector3 ViewSpacePosition;
[Optional] Vector3 WorldSpacePosition;
[Optional] Vector3 TangentSpacePosition;
[Optional] Vector4 ScreenPosition;
[Optional] Vector4 uv0;
[Optional] Vector4 uv1;
[Optional] Vector4 uv2;
[Optional] Vector4 uv3;
[Optional] Vector4 VertexColor;
public static Dependency[] dependencies = new Dependency[]
{ // TODO: NOCHECKIN: these dependencies are not correct for vertex pass
new Dependency("VertexDescriptionInputs.ObjectSpaceNormal", "AttributesMesh.normalOS"),
new Dependency("VertexDescriptionInputs.WorldSpaceNormal", "AttributesMesh.normalOS"),
new Dependency("VertexDescriptionInputs.ViewSpaceNormal", "VertexDescriptionInputs.WorldSpaceNormal"),
new Dependency("VertexDescriptionInputs.ObjectSpaceTangent", "AttributesMesh.tangentOS"),
new Dependency("VertexDescriptionInputs.WorldSpaceTangent", "AttributesMesh.tangentOS"),
new Dependency("VertexDescriptionInputs.ViewSpaceTangent", "VertexDescriptionInputs.WorldSpaceTangent"),
new Dependency("VertexDescriptionInputs.ObjectSpaceBiTangent", "AttributesMesh.normalOS"),
new Dependency("VertexDescriptionInputs.ObjectSpaceBiTangent", "AttributesMesh.tangentOS"),
new Dependency("VertexDescriptionInputs.WorldSpaceBiTangent", "VertexDescriptionInputs.ObjectSpaceBiTangent"),
new Dependency("VertexDescriptionInputs.ViewSpaceBiTangent", "VertexDescriptionInputs.WorldSpaceBiTangent"),
new Dependency("VertexDescriptionInputs.ObjectSpacePosition", "AttributesMesh.positionOS"),
new Dependency("VertexDescriptionInputs.WorldSpacePosition", "AttributesMesh.positionOS"),
new Dependency("VertexDescriptionInputs.ViewSpacePosition", "VertexDescriptionInputs.WorldSpacePosition"),
// TODO : view direction accessible in vertex shader
// new Dependency("VertexDescriptionInputs.WorldSpaceViewDirection", "FragInputs.positionWS"), // we build WorldSpaceViewDirection using FragInputs.positionWS in GetWorldSpaceNormalizeViewDir()
// new Dependency("VertexDescriptionInputs.ObjectSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceViewDirection"),
// new Dependency("VertexDescriptionInputs.ViewSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceViewDirection"),
// new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceViewDirection"),
// new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceTangent"),
// new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceBiTangent"),
// new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceNormal"),
// TODO : screen position accessible in vertex shader
// new Dependency("VertexDescriptionInputs.ScreenPosition", "VertexDescriptionInputs.WorldSpacePosition"),
new Dependency("VertexDescriptionInputs.uv0", "AttributesMesh.uv0"),
new Dependency("VertexDescriptionInputs.uv1", "AttributesMesh.uv1"),
new Dependency("VertexDescriptionInputs.uv2", "AttributesMesh.uv2"),
new Dependency("VertexDescriptionInputs.uv3", "AttributesMesh.uv3"),
new Dependency("VertexDescriptionInputs.VertexColor", "AttributesMesh.color"),
};
};
// TODO: move this out of HDRPShaderStructs
static public void AddActiveFieldsFromVertexGraphRequirements(HashSet<string> activeFields, ShaderGraphRequirements requirements)
{
if (requirements.requiresScreenPosition)
{
activeFields.Add("VertexDescriptionInputs.ScreenPosition");
}
if (requirements.requiresVertexColor)
{
activeFields.Add("VertexDescriptionInputs.VertexColor");
}
if (requirements.requiresNormal != 0)
{
if ((requirements.requiresNormal & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceNormal");
if ((requirements.requiresNormal & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceNormal");
if ((requirements.requiresNormal & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceNormal");
if ((requirements.requiresNormal & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceNormal");
}
if (requirements.requiresTangent != 0)
{
if ((requirements.requiresTangent & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceTangent");
if ((requirements.requiresTangent & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceTangent");
if ((requirements.requiresTangent & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceTangent");
if ((requirements.requiresTangent & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceTangent");
}
if (requirements.requiresBitangent != 0)
{
if ((requirements.requiresBitangent & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceBiTangent");
if ((requirements.requiresBitangent & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceBiTangent");
if ((requirements.requiresBitangent & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceBiTangent");
if ((requirements.requiresBitangent & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceBiTangent");
}
if (requirements.requiresViewDir != 0)
{
if ((requirements.requiresViewDir & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceViewDirection");
if ((requirements.requiresViewDir & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceViewDirection");
if ((requirements.requiresViewDir & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceViewDirection");
if ((requirements.requiresViewDir & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceViewDirection");
}
if (requirements.requiresPosition != 0)
{
if ((requirements.requiresPosition & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpacePosition");
if ((requirements.requiresPosition & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpacePosition");
if ((requirements.requiresPosition & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpacePosition");
if ((requirements.requiresPosition & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpacePosition");
}
foreach (var channel in requirements.requiresMeshUVs.Distinct())
{
activeFields.Add("VertexDescriptionInputs." + channel.GetUVName());
}
}
// TODO: move this out of HDRPShaderStructs
static public void AddActiveFieldsFromPixelGraphRequirements(HashSet<string> activeFields, ShaderGraphRequirements requirements)
activeFields.Add("SurfaceDescriptionInputs.screenPosition");
activeFields.Add("SurfaceDescriptionInputs.ScreenPosition");
activeFields.Add("SurfaceDescriptionInputs.vertexColor");
activeFields.Add("SurfaceDescriptionInputs.VertexColor");
}
if (requirements.requiresNormal != 0)

}
}
// TODO : split this function into buildActiveFields and buildHLSLTypeDeclaration functions
public static void Generate(
ShaderGenerator codeResult,
ShaderGenerator graphInputsResult,
ShaderGraphRequirements graphRequirements,
public static void AddRequiredFields(
CoordinateSpace preferedCoordinateSpace,
if (preferedCoordinateSpace == CoordinateSpace.Tangent)
preferedCoordinateSpace = CoordinateSpace.World;
// build initial requirements
AddActiveFieldsFromGraphRequirements(activeFields, graphRequirements);
if (passRequiredFields != null)
{
foreach (var requiredField in passRequiredFields)

}
}
public static void Generate(
ShaderGenerator codeResult,
HashSet<string> activeFields)
{
// propagate requirements using dependencies
{
ShaderSpliceUtil.ApplyDependencies(

FragInputs.dependencies,
VaryingsMeshToPS.standardDependencies,
SurfaceDescriptionInputs.dependencies,
VertexDescriptionInputs.dependencies
});
}

ShaderSpliceUtil.BuildType(typeof(VaryingsMeshToDS), activeFields, codeResult);
ShaderSpliceUtil.BuildPackedType(typeof(VaryingsMeshToPS), activeFields, codeResult);
ShaderSpliceUtil.BuildPackedType(typeof(VaryingsMeshToDS), activeFields, codeResult);
ShaderSpliceUtil.BuildType(typeof(SurfaceDescriptionInputs), activeFields, graphInputsResult);
}
};

public static class HDSubShaderUtilities
{
public static List<MaterialSlot> FindSlotsOnMasterNode(IEnumerable<int> slots, PBRMasterNode masterNode)
{
var activeSlots = new List<MaterialSlot>();
if (slots != null)
{
foreach (var id in slots)
{
MaterialSlot slot = masterNode.FindSlot<MaterialSlot>(id);
if (slot != null)
{
activeSlots.Add(slot);
}
}
}
return activeSlots;
}
public static void BuildRenderStatesFromPassAndMaterialOptions(
Pass pass,
SurfaceMaterialOptions materialOptions,

19
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitSubShader.cs


NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
// graph requirements describe what the graph itself requires
var graphRequirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.All, true, true);
var graphRequirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.All, false); // TODO: capability.all ?? fragment only?
ShaderStringBuilder graphNodeFunctions = new ShaderStringBuilder();
graphNodeFunctions.IncreaseIndent();

// TODO: this can be a shared function -- From here through GraphUtil.GenerateSurfaceDescription(..)
// var pixelSlots = HDSubShaderUtilities.FindSlotsOnMasterNode(pass.PixelShaderSlots, masterNode); // TODO: need to have a generic interface for masterNode.FindSlot<> ?
var activeSlots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
{

}
}
// build initial requirements
HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, graphRequirements);
HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
var graphInputs = new ShaderGenerator();
graphInputs,
graphRequirements,
pass.RequiredFields,
CoordinateSpace.World,
// build graph inputs structures
var graphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.SurfaceDescriptionInputs), activeFields, graphInputs);
// debug output all active fields
var interpolatorDefines = new ShaderGenerator();

4
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/VertMesh.hlsl


// TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16)
VaryingsMeshType VertMesh(AttributesMesh input)
{
#if defined(HAVE_MESH_MODIFICATION)
input = ApplyMeshModification(input);
#endif
VaryingsMeshType output;
UNITY_SETUP_INSTANCE_ID(input);

4
com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs


return newReqs;
}
public static ShaderGraphRequirements FromNodes<T>(List<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true, bool HDRPBehavior = false)
public static ShaderGraphRequirements FromNodes<T>(List<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true)
where T : class, INode
{
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal(stageCapability));

| requiresNormal;
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace && !HDRPBehavior)
if (needsTangentSpace)
{
requiresBitangent |= NeededCoordinateSpace.World;
requiresNormal |= NeededCoordinateSpace.World;

60
com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs


return results;
}
public static void GenerateSurfaceDescriptionStruct(ShaderStringBuilder surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster)
public static void GenerateSurfaceDescriptionStruct(ShaderStringBuilder surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster, string structName = "SurfaceDescription", HashSet<string> activeFields = null)
surfaceDescriptionStruct.AppendLine("struct SurfaceDescription");
surfaceDescriptionStruct.AppendLine("struct {0}", structName);
{
string hlslName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName);
NodeUtils.GetHLSLSafeName(slot.shaderOutputName));
//surfaceDescriptionStruct.Deindent();
hlslName);
if (activeFields != null)
{
activeFields.Add(structName + "." + hlslName);
}
}
if (activeFields != null)
{
activeFields.Add(structName + ".PreviewOutput");
}
}
}
}

var usedSlots = slots ?? masterNode.GetInputSlots<MaterialSlot>();
foreach (var input in usedSlots)
{
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
if (input != null)
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), masterNode.GetSlotValue(input.id, mode));
}
else
{
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode));
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
{
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), masterNode.GetSlotValue(input.id, mode));
}
else
{
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode));
}
}
}
}

}
const string k_VertexDescriptionStructName = "VertexDescription";
public static void GenerateVertexDescriptionStruct(ShaderStringBuilder builder, List<MaterialSlot> slots)
public static void GenerateVertexDescriptionStruct(ShaderStringBuilder builder, List<MaterialSlot> slots, string structName = k_VertexDescriptionStructName, HashSet<string> activeFields = null)
builder.AppendLine("struct {0}", k_VertexDescriptionStructName);
builder.AppendLine("struct {0}", structName);
builder.AppendLine("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), NodeUtils.GetHLSLSafeName(slot.shaderOutputName));
{
string hlslName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName);
builder.AppendLine("{0} {1};",
NodeUtils.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType),
hlslName);
if (activeFields != null)
{
activeFields.Add(structName + "." + hlslName);
}
}
}
}

GenerationMode mode,
List<AbstractMaterialNode> nodes,
List<MaterialSlot> slots,
string graphInputStructName = "VertexDescriptionInputs")
string graphInputStructName = "VertexDescriptionInputs",
string functionName = "PopulateVertexData",
string graphOutputStructName = k_VertexDescriptionStructName)
{
if (graph == null)
return;

graph.CollectShaderProperties(shaderProperties, mode);
builder.AppendLine("{0} PopulateVertexData(VertexDescriptionInputs IN)", k_VertexDescriptionStructName);
builder.AppendLine("{0} {1}({2} IN)", graphOutputStructName, functionName, graphInputStructName);
builder.AppendLine("{0} description = ({0})0;", k_VertexDescriptionStructName);
builder.AppendLine("{0} description = ({0})0;", graphOutputStructName);
foreach (var node in nodes)
{
var generatesFunction = node as IGeneratesFunction;

正在加载...
取消
保存