You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

336 lines
13 KiB

$splice(PassPragmas)
// TODO: Keywords (shader_feature) incompatible with compute
$splice(GraphKeywords)
// Disabled the 'PROCEDURAL_INSTANCING_ON' keyword on the compute vertex-setup kernel, since it's only meant for vs/ps
// stages, and it can cause compilation issues when applied to a compute kernel.
#undef PROCEDURAL_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl" // Required by Tessellation.hlsl
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl" // Required to be include before we include properties as it define DECLARE_STACK_CB
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS
// Always include Shader Graph version
// Always include last to avoid double macros
#include "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl" // Need to be here for Gradient struct definition
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/LineRendering/Core/LineRenderingCommon.hlsl"
// --------------------------------------------------
// Defines
#define _WRITE_TRANSPARENT_MOTION_VECTOR
// Attribute
$AttributesMesh.normalOS: #define ATTRIBUTES_NEED_NORMAL
$AttributesMesh.tangentOS: #define ATTRIBUTES_NEED_TANGENT
$AttributesMesh.uv0: #define ATTRIBUTES_NEED_TEXCOORD0
$AttributesMesh.uv1: #define ATTRIBUTES_NEED_TEXCOORD1
$AttributesMesh.uv2: #define ATTRIBUTES_NEED_TEXCOORD2
$AttributesMesh.uv3: #define ATTRIBUTES_NEED_TEXCOORD3
$AttributesMesh.color: #define ATTRIBUTES_NEED_COLOR
$AttributesMesh.vertexID: #define ATTRIBUTES_NEED_VERTEXID
$AttributesMesh.instanceID: #define ATTRIBUTES_NEED_INSTANCEID
$VaryingsMeshToPS.positionRWS: #define VARYINGS_NEED_POSITION_WS
$VaryingsMeshToPS.positionPredisplacementRWS: #define VARYINGS_NEED_POSITIONPREDISPLACEMENT_WS
$VaryingsMeshToPS.normalWS: #define VARYINGS_NEED_TANGENT_TO_WORLD
$VaryingsMeshToPS.texCoord0: #define VARYINGS_NEED_TEXCOORD0
$VaryingsMeshToPS.texCoord1: #define VARYINGS_NEED_TEXCOORD1
$VaryingsMeshToPS.texCoord2: #define VARYINGS_NEED_TEXCOORD2
$VaryingsMeshToPS.texCoord3: #define VARYINGS_NEED_TEXCOORD3
$VaryingsMeshToPS.color: #define VARYINGS_NEED_COLOR
$VaryingsMeshToPS.elementToWorld0: #define VARYINGS_NEED_ELEMENT_TO_WORLD
$VaryingsMeshToPS.worldToElement0: #define VARYINGS_NEED_WORLD_TO_ELEMENT
$features.graphVertex: #define HAVE_MESH_MODIFICATION
$SurfaceDescriptionInputs.FaceSign: // Define when IsFontFaceNode is included in ShaderGraph
$SurfaceDescriptionInputs.FaceSign: #define VARYINGS_NEED_CULLFACE
$VertexDescription.CustomVelocity: #define _ADD_CUSTOM_VELOCITY
$splice(GraphDefines)
#ifndef SHADER_UNLIT
// We need isFrontFace when using double sided - it is not required for unlit as in case of unlit double sided only drive the cullmode
// VARYINGS_NEED_CULLFACE can be define by VaryingsMeshToPS.FaceSign input if a IsFrontFace Node is included in the shader graph.
#if defined(_DOUBLESIDED_ON) && !defined(VARYINGS_NEED_CULLFACE)
#define VARYINGS_NEED_CULLFACE
#endif
#endif
// -- Graph Properties
$splice(GraphProperties)
// Includes
$splice(PreGraphIncludes)
$splice(GraphIncludes)
// --------------------------------------------------
// Structs and Packing
$splice(PassStructs)
$splice(InterpolatorPack)
// --------------------------------------------------
// Graph
// Graph Functions
$splice(GraphFunctions)
// Graph Vertex
$splice(GraphVertex)
// --------------------------------------------------
// Build Graph Inputs
$features.graphVertex: $include("Vertex.template.hlsl")
// --------------------------------------------------
// Main
// Required to compile since we have to include the pass.
void GetSurfaceAndBuiltinData(FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData RAY_TRACING_OPTIONAL_PARAMETERS)
{
ZERO_INITIALIZE(SurfaceData, surfaceData);
ZERO_INITIALIZE(BuiltinData, builtinData);
}
$splice(PostGraphIncludes)
// --------------------------------------------------
// Kernel
#define DECLARE_ATTRIBUTE_BUFFER(attr) \
ByteAddressBuffer _VertexBuffer##attr; \
int _VertexBuffer##attr##Stride; \
int _VertexBuffer##attr##Offset;
DECLARE_ATTRIBUTE_BUFFER(Position)
DECLARE_ATTRIBUTE_BUFFER(Normal)
DECLARE_ATTRIBUTE_BUFFER(Tangent)
DECLARE_ATTRIBUTE_BUFFER(Color)
DECLARE_ATTRIBUTE_BUFFER(TexCoord0)
DECLARE_ATTRIBUTE_BUFFER(TexCoord1)
DECLARE_ATTRIBUTE_BUFFER(TexCoord2)
DECLARE_ATTRIBUTE_BUFFER(TexCoord3)
DECLARE_ATTRIBUTE_BUFFER(TexCoord4)
DECLARE_ATTRIBUTE_BUFFER(TexCoord5)
DECLARE_ATTRIBUTE_BUFFER(TexCoord6)
DECLARE_ATTRIBUTE_BUFFER(TexCoord7)
DECLARE_ATTRIBUTE_BUFFER(BlendWeight)
DECLARE_ATTRIBUTE_BUFFER(BlendIndices)
#define LOAD_ATTRIBUTE_FLOAT(attr, i)\
asfloat(_VertexBuffer##attr.Load((_VertexBuffer##attr##Stride * i) + _VertexBuffer##attr##Offset))
#define LOAD_ATTRIBUTE_FLOAT3(attr, i)\
asfloat(_VertexBuffer##attr.Load3((_VertexBuffer##attr##Stride * i) + _VertexBuffer##attr##Offset))
#define LOAD_ATTRIBUTE_FLOAT4(attr, i)\
asfloat(_VertexBuffer##attr.Load4((_VertexBuffer##attr##Stride * i) + _VertexBuffer##attr##Offset))
#define LOAD_ATTRIBUTE_UINT(attr, i)\
(_VertexBuffer##attr.Load((_VertexBuffer##attr##Stride * i) + _VertexBuffer##attr##Offset))
#define LOAD_ATTRIBUTE_UINT3(attr, i)\
(_VertexBuffer##attr.Load3((_VertexBuffer##attr##Stride * i) + _VertexBuffer##attr##Offset))
#define LOAD_ATTRIBUTE_UINT4(attr, i)\
(_VertexBuffer##attr.Load4((_VertexBuffer##attr##Stride * i) + _VertexBuffer##attr##Offset)
RWByteAddressBuffer _Vertex0RecordBuffer;
RWByteAddressBuffer _Vertex1RecordBuffer;
RWByteAddressBuffer _Vertex2RecordBuffer;
RWByteAddressBuffer _Vertex3RecordBuffer;
RWByteAddressBuffer _CounterBuffer;
void BuildStrandBasis(uint i, float3 positionOS, out float3 normalOS, out float4 tangentOS)
{
float3 vertexBitangentOS = normalize(LOAD_ATTRIBUTE_FLOAT4(Tangent, i).xyz);
tangentOS = float4(normalize(cross(vertexBitangentOS, GetWorldSpaceNormalizeViewDir(positionOS))), 0);
normalOS = cross(tangentOS.xyz, vertexBitangentOS);
}
float2 ClipSpaceToScreenSpace(float4 positionCS)
{
return _ScreenParams.xy * (0.5 + 0.5 * (positionCS.xy / positionCS.w));
}
// Bound by the rasterizer.
float _LOD;
// Light-weight VertMesh since we need to process a dilated world space position to compute screen-space width.
VaryingsMeshType SimpleVertMesh(AttributesMesh input, out float screenSpaceWidth)
{
VaryingsMeshType output;
// Deduce the actual instance ID of the current instance (it is then stored in unity_InstanceID)
UNITY_SETUP_INSTANCE_ID(input);
// Transfer the unprocessed instance ID to the next stage
UNITY_TRANSFER_INSTANCE_ID(input, output);
#ifdef HAVE_MESH_MODIFICATION
input = ApplyMeshModification(input, _TimeParameters.xyz);
#endif
float3 positionRWS = TransformObjectToWorld(input.positionOS);
#ifdef ATTRIBUTES_NEED_NORMAL
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
#else
float3 normalWS = float3(0.0, 0.0, 0.0);
#endif
#ifdef ATTRIBUTES_NEED_TANGENT
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
#endif
#ifdef VARYINGS_NEED_POSITION_WS
output.positionRWS = positionRWS;
#endif
#ifdef VARYINGS_NEED_POSITIONPREDISPLACEMENT_WS
output.positionPredisplacementRWS = positionRWS;
#endif
output.positionCS = TransformWorldToHClip(positionRWS);
#ifdef VARYINGS_NEED_TANGENT_TO_WORLD
output.normalWS = normalWS;
output.tangentWS = tangentWS;
#endif
#if !defined(SHADER_API_METAL) && defined(SHADERPASS) && (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG)
if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VERTEX_DENSITY)
IncrementVertexDensityCounter(output.positionCS);
#endif
#if defined(VARYINGS_NEED_TEXCOORD0) || defined(VARYINGS_DS_NEED_TEXCOORD0)
output.texCoord0 = input.uv0;
#endif
#if defined(VARYINGS_NEED_TEXCOORD1) || defined(VARYINGS_DS_NEED_TEXCOORD1)
output.texCoord1 = input.uv1;
#endif
#if defined(VARYINGS_NEED_TEXCOORD2) || defined(VARYINGS_DS_NEED_TEXCOORD2)
output.texCoord2 = input.uv2;
#endif
#if defined(VARYINGS_NEED_TEXCOORD3) || defined(VARYINGS_DS_NEED_TEXCOORD3)
output.texCoord3 = input.uv3;
#endif
#if defined(VARYINGS_NEED_COLOR) || defined(VARYINGS_DS_NEED_COLOR)
output.color = input.color;
#endif
// Compute screen-space width.
{
// Lazily re-evaluate the graph. Will the compiler optimize this?
VertexDescription vertexDescription = GetVertexDescription(input, _TimeParameters.xyz);
// Extract the world space up direction from the view matrix.
const float3 cameraUpWS = UNITY_MATRIX_V._21_22_23;
// Produce a dilated world space position using the vertice's specified width (in cm).
float3 dilatedPositionWS = positionRWS + (METERS_PER_CENTIMETER * vertexDescription.Width) * cameraUpWS;
// Clip -> Screen Space
const float2 positionSS0 = ClipSpaceToScreenSpace(output.positionCS);
const float2 positionSS1 = ClipSpaceToScreenSpace(TransformWorldToHClip(dilatedPositionWS));
// Compute the length of the derivative between position SS and postion + width SS
screenSpaceWidth = distance(positionSS0, positionSS1);
}
return output;
}
int _VertexOffset;
[numthreads(128, 1, 1)]
void VertexSetup (uint3 dispatchThreadID : SV_DispatchThreadID)
{
const uint i = dispatchThreadID.x;
if (i >= (uint)_VertexCount)
return;
// Construct the input vertex.
AttributesMesh inputMesh;
ZERO_INITIALIZE(AttributesMesh, inputMesh);
inputMesh.positionOS = LOAD_ATTRIBUTE_FLOAT3(Position, i);
#if defined(ATTRIBUTES_NEED_NORMAL) || defined(ATTRIBUTES_NEED_TANGENT)
BuildStrandBasis(i, inputMesh.positionOS, inputMesh.normalOS, inputMesh.tangentOS);
#endif
#ifdef ATTRIBUTES_NEED_TEXCOORD0
const uint unnormalizedPackedID = LOAD_ATTRIBUTE_UINT(TexCoord0, i);
inputMesh.uv0 = float4
(
((unnormalizedPackedID >> 0) & 0xFF) / 255.0,
((unnormalizedPackedID >> 8) & 0xFF) / 255.0,
((unnormalizedPackedID >> 16) & 0xFF) / 255.0,
((unnormalizedPackedID >> 24) & 0xFF) / 255.0
);
#endif
#if UNITY_ANY_INSTANCING_ENABLED
// See: [NOTE-HQ-LINES-SINGLE-PASS-STEREO]
inputMesh.instanceID = _ViewIndex;
#endif
AttributesPass inputPass;
ZERO_INITIALIZE(AttributesPass, inputPass);
VaryingsType output;
ZERO_INITIALIZE(VaryingsType, output);
float screenSpaceWidth;
output.vmesh = SimpleVertMesh(inputMesh, screenSpaceWidth);
output = MotionVectorVS_Internal(output, inputMesh, inputPass);
VertexRecord vertexRecord;
ZERO_INITIALIZE(VertexRecord, vertexRecord);
{
vertexRecord.positionCS = output.vpass.positionCS;
// Have to manually provide a previous position that will result in a zero length movec for force disable.
if (unity_MotionVectorsParams.y == 0)
vertexRecord.previousPositionCS = output.vpass.positionCS;
else
vertexRecord.previousPositionCS = output.vpass.previousPositionCS;
#ifdef VARYINGS_NEED_TEXCOORD0
vertexRecord.texCoord0 = unnormalizedPackedID;
#endif
#ifdef VARYINGS_NEED_TANGENT_TO_WORLD
vertexRecord.normalWS = output.vmesh.normalWS;
vertexRecord.tangentWS = output.vmesh.tangentWS.xyz;
#endif
}
const uint offset = _VertexOffset + i;
_Vertex0RecordBuffer.Store4(offset << 4, asuint(vertexRecord.positionCS));
// Perspective divide the previous position here since we dont need it for clipping and it frees up space for the line width attribute.
const float3 previousPosition = vertexRecord.previousPositionCS.xyz * rcp(vertexRecord.previousPositionCS.w);
_Vertex1RecordBuffer.Store4(offset << 4, asuint(float4(previousPosition, screenSpaceWidth)));
#ifdef VARYINGS_NEED_TANGENT_TO_WORLD
const uint2 encodedN = asuint(PackNormalOctQuadEncode(vertexRecord.normalWS));
const uint2 encodedT = asuint(PackNormalOctQuadEncode(vertexRecord.tangentWS));
_Vertex2RecordBuffer.Store4(offset << 4, uint4(encodedN, encodedT));
#endif
#if defined(VARYINGS_NEED_TEXCOORD0)
_Vertex3RecordBuffer.Store2(8 * offset, uint2(vertexRecord.texCoord0, 0));
#endif
}