浏览代码

Fixes for vertex animation velocity buffer, screen position

And some refactoring
/main
Chris Tchou 7 年前
当前提交
d3bcb929
共有 9 个文件被更改,包括 90 次插入81 次删除
  1. 25
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template
  2. 67
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRSubShader.cs
  3. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs
  4. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template
  5. 51
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitSubShader.cs
  6. 12
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassVelocity.hlsl
  7. 4
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs
  8. 4
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs
  9. 4
      com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs

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


//#pragma enable_d3d11_debug_symbols
//-------------------------------------------------------------------------------------
// Variant Definitions
// Variant Definitions (active field translations to HDRP defines)
${VariantDefines}
$AlphaTest: #define _ALPHATEST_ON 1
$Material.SubsurfaceScattering: #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1
$Material.Transmission: #define _MATERIAL_FEATURE_TRANSMISSION 1
$Material.Anisotropy: #define _MATERIAL_FEATURE_ANISOTROPY 1
$Material.ClearCoat: #define _MATERIAL_FEATURE_CLEAR_COAT 1
$Material.Iridescence: #define _MATERIAL_FEATURE_IRIDESCENCE 1
$Material.SpecularColor: #define _MATERIAL_FEATURE_SPECULAR_COLOR 1
$SurfaceType.Transparent: #define _SURFACE_TYPE_TRANSPARENT 1
$BlendMode.Alpha: #define _BLENDMODE_ALPHA 1
$BlendMode.Add: #define _BLENDMODE_ADD 1
//-------------------------------------------------------------------------------------
// End Variant
//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
// End Defines
//-------------------------------------------------------------------------------------
#include "ShaderGraphLibrary/Functions.hlsl"
#include "HDRP/ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "HDRP/Debug/DebugDisplay.hlsl"

$VertexDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = TransformWorldToHClip(output.WorldSpacePosition);
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(output.WorldSpacePosition), _ProjectionParams.x);
$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);

$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: float4 clipPos = ComputeScreenPos(TransformWorldToHClip(input.positionWS), _ProjectionParams.x);
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = clipPos; // float4(clipPos.x * _ScreenSize.x, clipPos.y * _ScreenSize.y, clipPos.zw); // wtf?
$SurfaceDescriptionInputs.uv0: output.uv0 = float4(input.texCoord0, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv1: output.uv1 = float4(input.texCoord1, 0.0f, 0.0f);

// Perform alpha test very early to save performance (a killed pixel will not sample textures)
// TODO: split graph evaluation to grab just alpha dependencies first? tricky..
#ifdef _ALPHATEST_ON
DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
#endif
$AlphaTest: DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData);

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


},
};
private static string GetVariantDefines(PBRMasterNode masterNode)
private static HashSet<string> GetActiveFieldsFromMasterNode(INode iMasterNode, Pass pass)
ShaderGenerator defines = new ShaderGenerator();
HashSet<string> activeFields = new HashSet<string>();
// TODO:
// _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
// _MATERIAL_FEATURE_TRANSMISSION
// _MATERIAL_FEATURE_ANISOTROPY
// _MATERIAL_FEATURE_CLEAR_COAT
// _MATERIAL_FEATURE_IRIDESCENCE
PBRMasterNode masterNode = iMasterNode as PBRMasterNode;
if (masterNode == null)
{
return activeFields;
}
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
switch (masterNode.model)
{

defines.AddShaderChunk("#define _MATERIAL_FEATURE_SPECULAR_COLOR 1", true);
activeFields.Add("Material.SpecularColor");
break;
default:
// TODO: error!

// #pragma shader_feature _ALPHATEST_ON
defines.AddShaderChunk("#define _ALPHATEST_ON 1", true);
activeFields.Add("AlphaTest");
}
// if (kTesselationMode != TessellationMode.None)

// #pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR // MOVE to a node
// #pragma shader_feature _NORMALMAP_TANGENT_SPACE
// #pragma shader_feature _ _REQUIRE_UV2 _REQUIRE_UV3
//
// #pragma shader_feature _NORMALMAP
if (masterNode.IsSlotConnected(PBRMasterNode.NormalSlotId))
{
defines.AddShaderChunk("#define _NORMALMAP 1", true);
}
// #pragma shader_feature _MASKMAP
// #pragma shader_feature _BENTNORMALMAP

if (masterNode.surfaceType != SurfaceType.Opaque)
{
// transparent-only defines
defines.AddShaderChunk("#define _SURFACE_TYPE_TRANSPARENT 1", true);
activeFields.Add("SurfaceType.Transparent");
defines.AddShaderChunk("#define _BLENDMODE_ALPHA 1", true);
activeFields.Add("BlendMode.Alpha");
defines.AddShaderChunk("#define _BLENDMODE_ADD 1", true);
activeFields.Add("BlendMode.Add");
}
// else if (masterNode.alphaMode == PBRMasterNode.AlphaMode.PremultiplyAlpha) // TODO
// {

// opaque-only defines
}
// MaterialId are used as shader feature to allow compiler to optimize properly
// Note _MATID_STANDARD is not define as there is always the default case "_". We assign default as _MATID_STANDARD, so we never test _MATID_STANDARD
// #pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR _MATID_CLEARCOAT
return defines.GetShaderString(2);
return activeFields;
private static bool GenerateShaderPassLit(PBRMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
private static bool GenerateShaderPassLit(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
{
var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDEditorUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);
if (!File.Exists(templateLocation))

sourceAssetDependencyPaths.Add(templateLocation);
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelNodes = ListPool<INode>.Get();

ShaderStringBuilder pixelGraphOutputs = new ShaderStringBuilder();
// dependency tracker -- set of active fields
HashSet<string> activeFields = new HashSet<string>();
HashSet<string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass);
// build initial requirements
HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, pixelRequirements);

var colorMaskCode = new ShaderStringBuilder();
HDSubShaderUtilities.BuildRenderStatesFromPassAndMaterialOptions(pass, materialOptions, blendCode, cullCode, zTestCode, zWriteCode, stencilCode, colorMaskCode);
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
// apply dependencies to the active fields, and build interpolators (TODO: split this function)

namedFragments.Add("${Stencil}", stencilCode.ToString());
namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
namedFragments.Add("${LOD}", materialOptions.lod.ToString());
namedFragments.Add("${VariantDefines}", GetVariantDefines(masterNode));
// process the template to generate the shader code for this pass TODO: could make this a shared function
string[] templateLines = File.ReadAllLines(templateLocation);

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


new Dependency("SurfaceDescriptionInputs.TangentSpaceViewDirection", "SurfaceDescriptionInputs.WorldSpaceBiTangent"),
new Dependency("SurfaceDescriptionInputs.TangentSpaceViewDirection", "SurfaceDescriptionInputs.WorldSpaceNormal"),
new Dependency("SurfaceDescriptionInputs.ScreenPosition", "FragInputs.positionSS"),
new Dependency("SurfaceDescriptionInputs.ScreenPosition", "SurfaceDescriptionInputs.WorldSpacePosition"),
new Dependency("SurfaceDescriptionInputs.uv0", "FragInputs.texCoord0"),
new Dependency("SurfaceDescriptionInputs.uv1", "FragInputs.texCoord1"),
new Dependency("SurfaceDescriptionInputs.uv2", "FragInputs.texCoord2"),

2
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template


$VertexDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = TransformWorldToHClip(output.WorldSpacePosition);
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = TransformWorldToHClip(output.WorldSpacePosition) * 0.5 + 0.5;
$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);

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


},
};
private static string GetVariantDefines(UnlitMasterNode masterNode)
private static HashSet<string> GetActiveFieldsFromMasterNode(INode iMasterNode, Pass pass)
ShaderGenerator defines = new ShaderGenerator();
HashSet<string> activeFields = new HashSet<string>();
// #pragma shader_feature _ALPHATEST_ON
UnlitMasterNode masterNode = iMasterNode as UnlitMasterNode;
if (masterNode == null)
{
return null;
}
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
defines.AddShaderChunk("#define _ALPHATEST_ON 1", true);
activeFields.Add("AlphaTest");
}
// if (kTesselationMode != TessellationMode.None)

// #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

if (masterNode.surfaceType != SurfaceType.Opaque)
{
// transparent-only defines
defines.AddShaderChunk("#define _SURFACE_TYPE_TRANSPARENT 1", true);
activeFields.Add("SurfaceType.Transparent");
defines.AddShaderChunk("#define _BLENDMODE_ALPHA 1", true);
activeFields.Add("BlendMode.Alpha");
defines.AddShaderChunk("#define _BLENDMODE_ADD 1", true);
activeFields.Add("BlendMode.Add");
}
// else if (masterNode.alphaMode == PBRMasterNode.AlphaMode.PremultiplyAlpha) // TODO
// {

// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON
return defines.GetShaderString(2);
return activeFields;
private static bool GenerateShaderPassUnlit(UnlitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
private static bool GenerateShaderPassUnlit(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
{
var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDEditorUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);
if (!File.Exists(templateLocation))

sourceAssetDependencyPaths.Add(templateLocation);
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelNodes = ListPool<INode>.Get();

ShaderStringBuilder pixelGraphOutputs = new ShaderStringBuilder();
// dependency tracker -- set of active fields
HashSet<string> activeFields = new HashSet<string>();
HashSet<string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass);
// build initial requirements
HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, pixelRequirements);

var colorMaskCode = new ShaderStringBuilder();
HDSubShaderUtilities.BuildRenderStatesFromPassAndMaterialOptions(pass, materialOptions, blendCode, cullCode, zTestCode, zWriteCode, stencilCode, colorMaskCode);
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
// apply dependencies to the active fields, and build interpolators (TODO: split this function)

namedFragments.Add("${Stencil}", stencilCode.ToString());
namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
namedFragments.Add("${LOD}", materialOptions.lod.ToString());
namedFragments.Add("${VariantDefines}", GetVariantDefines(masterNode));
// process the template to generate the shader code for this pass TODO: could make this a shared function
string[] templateLines = File.ReadAllLines(templateLocation);

12
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassVelocity.hlsl


else
{
bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target
//Need to apply any vertex animation to the previous worldspace position, if we want it to show up in the velocity buffer
// Need to apply any vertex animation to the previous worldspace position, if we want it to show up in the velocity buffer
#if defined(HAVE_MESH_MODIFICATION)
AttributesMesh previousMesh = inputMesh;
if (hasDeformation)
previousMesh.positionOS = inputPass.previousPositionOS;
previousMesh = ApplyMeshModification(previousMesh);
float3 previousPositionWS = mul(unity_MatrixPreviousM, float4(previousMesh.positionOS, 1.0)).xyz;
#else
#endif
#ifdef ATTRIBUTES_NEED_NORMAL
float3 normalWS = TransformPreviousObjectToWorldNormal(inputMesh.normalOS);
#else

4
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs


// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();

// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
// -------------------------------------

4
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs


// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();

// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
// -------------------------------------

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


FunctionRegistry functionRegistry,
PropertyCollector shaderProperties,
GenerationMode mode,
List<AbstractMaterialNode> nodes,
List<INode> nodes,
List<MaterialSlot> slots,
string graphInputStructName = "VertexDescriptionInputs",
string functionName = "PopulateVertexData",

{
ShaderGenerator sg = new ShaderGenerator();
builder.AppendLine("{0} description = ({0})0;", graphOutputStructName);
foreach (var node in nodes)
foreach (var node in nodes.OfType<AbstractMaterialNode>())
{
var generatesFunction = node as IGeneratesFunction;
if (generatesFunction != null)

正在加载...
取消
保存