$splice(PassPragmas) // TODO: Keywords (shader_feature) incompatible with compute $splice(GraphKeywords) #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 }