Search Unity

Question SkinnedRenderer.GetPreviousVertexBuffer not working in shell texturing example

Discussion in 'Shaders' started by BotsOP, Oct 14, 2022.

  1. BotsOP

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    9
    Im trying to use the previous vertex buffer to get the velocity per vertex.
    But no matter what I try whenever I try to pass the previous vertex position it doesnt render anything.
    I have read the previous vertex buffer back to the cpu, stored it in a new texcoord then read it back and read the drawTriangles buffer and all of them seem correct none of them return NaN but actual numbers. I have tried passing extra paremeters through the drawTriangles buffer and packing it in different variables but nothing works. I have been banging my head against this bug the enitre day now and Im stumped.

    Left is my shell texturing where I want to get the previous vertex position to. And right is a quick test to see if previous vertex buffer works without the shell texturing. Which appears to work. Im using unity urp 2021.3.10f.
    no_sway.gif

    here is my c# code
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Runtime.InteropServices;
    5. using UnityEngine;
    6. using UnityEngine.Rendering;
    7. using UnityEngine.UI;
    8.  
    9. [RequireComponent(typeof(SkinnedMeshRenderer))]
    10. public class ShellTexturingAnimated : MonoBehaviour
    11. {
    12.     [Serializable, StructLayout(LayoutKind.Sequential)]
    13.     public struct InputVertex
    14.     {
    15.         public Vector3 position;
    16.         public Vector3 normal;
    17.         public Vector2 uv;
    18.     }
    19.  
    20.     [Serializable, StructLayout(LayoutKind.Sequential)]
    21.     public struct InputTriangle
    22.     {
    23.         public InputVertex vertex0;
    24.         public InputVertex vertex1;
    25.         public InputVertex vertex2;
    26.     }
    27.  
    28.     [SerializeField] private ComputeShader shellTextureCS;
    29.     [SerializeField] private Material renderingMaterial;
    30.     [SerializeField] private Transform originalOffset;
    31.     [SerializeField] private Transform parentOffset;
    32.     [SerializeField] private Transform transformOffset;
    33.     [Min(1)]
    34.     [SerializeField] private int layers = 1;
    35.     [SerializeField] private float heightOffset = 0;
    36.     [SerializeField] private Vector2 uvScale = new(1, 1);
    37.  
    38.     private int kernelID;
    39.     private int threadGroupSize;
    40.  
    41.     private int[] indirectArgs = new[] { 0, 1, 0, 0 };
    42.  
    43.     private List<InputTriangle> inputTriangles;
    44.     private ComputeBuffer drawTrianglesBuffer;
    45.     private ComputeBuffer indirectArgsBuffer;
    46.  
    47.     private GraphicsBuffer inputVertexBuffer;
    48.     private GraphicsBuffer inputPreviousVertexBuffer;
    49.     private GraphicsBuffer inputUVBuffer;
    50.     private GraphicsBuffer inputIndexBuffer;
    51.    
    52.     private const int DRAWTRIANGLES_STRIDE = (3 * (3 + 3 + 2 + 4)) * sizeof(float);
    53.     private const int INDIRECTARGS_STRIDE = 4 * sizeof(int);
    54.  
    55.     private Mesh mesh;
    56.     private SkinnedMeshRenderer skinnedMeshRenderer;
    57.     private int triangleCount;
    58.     private bool initialized = false;
    59.     private Vector3 startParenOffset;
    60.  
    61.     private void OnEnable()
    62.     {
    63.         mesh = GetComponent<SkinnedMeshRenderer>().sharedMesh;
    64.         skinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
    65.         triangleCount = mesh.triangles.Length / 3;
    66.         startParenOffset = parentOffset.position;
    67.        
    68.         SetupBuffers();
    69.        
    70.     }
    71.  
    72.     private void OnDisable()
    73.     {
    74.         ReleaseBuffers();
    75.     }
    76.  
    77.     private void OnValidate()
    78.     {
    79.         SetupData();
    80.         GenerateGeometry();
    81.     }
    82.  
    83.     private void SetupData()
    84.     {
    85.         if (mesh == null)
    86.         {
    87.             return;
    88.         }
    89.  
    90.         skinnedMeshRenderer.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
    91.         mesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
    92.         mesh.indexBufferTarget |= GraphicsBuffer.Target.Raw;
    93.        
    94.         mesh.SetVertexBufferParams(mesh.vertexCount,
    95.             new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, dimension:3,stream:0),
    96.             new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, dimension:3,stream:0),
    97.             new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, dimension:4,stream:0),
    98.             new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, dimension:2,stream:1),
    99.             new VertexAttributeDescriptor(VertexAttribute.BlendWeight, VertexAttributeFormat.Float32, dimension:4,stream:2),
    100.             new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt32, dimension:4,stream:2)
    101.         );
    102.  
    103.         drawTrianglesBuffer.SetCounterValue(0);
    104.         indirectArgsBuffer.SetData(indirectArgs);
    105.  
    106.         initialized = true;
    107.     }
    108.  
    109.     private void GenerateGeometry()
    110.     {
    111.         if (mesh == null || shellTextureCS == null || renderingMaterial == null)
    112.         {
    113.             return;
    114.         }
    115.  
    116.         inputVertexBuffer ??= skinnedMeshRenderer.GetVertexBuffer();
    117.         inputPreviousVertexBuffer ??= skinnedMeshRenderer.GetPreviousVertexBuffer();
    118.         inputUVBuffer ??= mesh.GetVertexBuffer(1);
    119.         inputIndexBuffer ??= mesh.GetIndexBuffer();
    120.  
    121.         kernelID = shellTextureCS.FindKernel("ShellTextureGeoAnim");
    122.         shellTextureCS.GetKernelThreadGroupSizes(kernelID, out uint threadGroupSizeX, out _, out _);
    123.         threadGroupSize = Mathf.CeilToInt((float)triangleCount / threadGroupSizeX);
    124.        
    125.         shellTextureCS.SetBuffer(kernelID, "_DrawTrianglesBuffer", drawTrianglesBuffer);
    126.         shellTextureCS.SetBuffer(kernelID, "_IndirectArgsBuffer", indirectArgsBuffer);
    127.         shellTextureCS.SetBuffer(kernelID, "_InputVertexBuffer", inputVertexBuffer);
    128.         shellTextureCS.SetBuffer(kernelID, "_InputPreviousVertexBuffer", inputPreviousVertexBuffer);
    129.         shellTextureCS.SetBuffer(kernelID, "_InputUVBuffer", inputUVBuffer);
    130.         shellTextureCS.SetBuffer(kernelID, "_InputIndexBuffer", inputIndexBuffer);
    131.        
    132.         shellTextureCS.SetMatrix("_LocalToWorld", transform.localToWorldMatrix);
    133.         shellTextureCS.SetMatrix("_Offset", transformOffset.localToWorldMatrix);
    134.         shellTextureCS.SetInt("_TriangleCount", triangleCount);
    135.         shellTextureCS.SetInt("_Layers", layers);
    136.         shellTextureCS.SetFloat("_HeightOffset", heightOffset);
    137.         shellTextureCS.SetVector("_UVScale", uvScale);
    138.        
    139.         renderingMaterial.SetBuffer("_DrawTrianglesBuffer", drawTrianglesBuffer);
    140.        
    141.         shellTextureCS.Dispatch(kernelID, threadGroupSize, 1, 1);
    142.     }
    143.  
    144.     private void Update()
    145.     {
    146.         if (!initialized)
    147.         {
    148.             if (Time.time > 1)
    149.             {
    150.                 SetupData();
    151.                 GenerateGeometry();
    152.             }
    153.             return;
    154.         }
    155.  
    156.         transformOffset.position = originalOffset.position - startParenOffset;
    157.         transformOffset.rotation = originalOffset.rotation;
    158.         transformOffset.localScale = originalOffset.localScale;
    159.        
    160.         indirectArgsBuffer.SetData(indirectArgs);
    161.         shellTextureCS.SetMatrix("_Offset", transformOffset.localToWorldMatrix);
    162.         shellTextureCS.Dispatch(kernelID, threadGroupSize, 1, 1);
    163.  
    164.         Graphics.DrawProceduralIndirect(
    165.             renderingMaterial,
    166.             skinnedMeshRenderer.bounds,
    167.             MeshTopology.Triangles,
    168.             indirectArgsBuffer,
    169.             0,
    170.             null,
    171.             null,
    172.             ShadowCastingMode.On,
    173.             true,
    174.             gameObject.layer
    175.         );
    176.        
    177.         drawTrianglesBuffer.SetCounterValue(0);
    178.     }
    179.    
    180.     private void SetupBuffers()
    181.     {
    182.         drawTrianglesBuffer = new ComputeBuffer(triangleCount * layers, DRAWTRIANGLES_STRIDE, ComputeBufferType.Append);
    183.         indirectArgsBuffer = new ComputeBuffer(1, INDIRECTARGS_STRIDE, ComputeBufferType.IndirectArguments);
    184.     }
    185.    
    186.     private void ReleaseBuffers()
    187.     {
    188.         ReleaseBuffer(drawTrianglesBuffer);
    189.         ReleaseBuffer(indirectArgsBuffer);
    190.         ReleaseBuffer(inputVertexBuffer);
    191.         ReleaseBuffer(inputUVBuffer);
    192.         ReleaseBuffer(inputIndexBuffer);
    193.     }
    194.    
    195.     private void ReleaseBuffer(ComputeBuffer buffer)
    196.     {
    197.         if (buffer != null)
    198.         {
    199.             buffer.Release();
    200.             buffer = null;
    201.         }
    202.     }
    203.    
    204.     private void ReleaseBuffer(GraphicsBuffer buffer)
    205.     {
    206.         if (buffer != null)
    207.         {
    208.             buffer.Release();
    209.             buffer = null;
    210.         }
    211.     }
    212. }


    Here is my compute shader code
    Code (CSharp):
    1. // Each #kernel tells which function to compile; you can have many kernels
    2. #pragma kernel ShellTextureGeo
    3. #pragma kernel ShellTextureGeoAnim
    4.  
    5. struct InputVertex
    6. {
    7.     float3 position;
    8.     float3 normal;
    9.     float2 uv;
    10. };
    11.  
    12. struct InputTriangle
    13. {
    14.     InputVertex vertex0;
    15.     InputVertex vertex1;
    16.     InputVertex vertex2;
    17. };
    18.  
    19. struct DrawVertex
    20. {
    21.     float3 position;
    22.     float3 normal;
    23.     float2 uv;
    24.     float4 color;
    25. };
    26.  
    27. struct DrawTriangle
    28. {
    29.     DrawVertex drawVertices[3];
    30. };
    31.  
    32. struct IndirectArgs
    33. {
    34.     uint numVerticesPerInstance;
    35.     uint numInstances;
    36.     uint startVertexIndex;
    37.     uint startInstanceIndex;
    38. };
    39.  
    40. StructuredBuffer<InputTriangle> _InputTrianglesBuffer;
    41. AppendStructuredBuffer<DrawTriangle> _DrawTrianglesBuffer;
    42. RWStructuredBuffer<IndirectArgs> _IndirectArgsBuffer;
    43.  
    44. RWByteAddressBuffer _InputVertexBuffer;
    45. RWByteAddressBuffer _InputPreviousVertexBuffer;
    46. RWByteAddressBuffer _InputIndexBuffer;
    47. RWByteAddressBuffer _InputUVBuffer;
    48.  
    49. int _TriangleCount;
    50. float4x4 _LocalToWorld;
    51. float4x4 _Offset;
    52. int _Layers;
    53. float _HeightOffset;
    54. float4 _UVScale;
    55.  
    56. DrawVertex GetVertex(float3 position, float3 normal, float2 uv, float4 color)
    57. {
    58.     DrawVertex output = (DrawVertex) 0;
    59.     float3 pos = mul(_Offset, float4(position, 1.0));
    60.     output.position = mul(_LocalToWorld, float4(pos, 1.0)).xyz;
    61.    
    62.     // float3 prevPos = mul(_Offset, float4(color.yzw, 1.0));
    63.     // output.color.yzw = mul(_LocalToWorld, float4(prevPos, 1.0)).xyz;
    64.    
    65.     output.color.yzw = color.yzw;
    66.     output.normal = mul(_LocalToWorld, float4(normal, 0.0)).xyz;
    67.     output.uv = uv;
    68.     output.color.x = color.x;
    69.     return output;
    70. }
    71.  
    72. [numthreads(64,1,1)]
    73. void ShellTextureGeo (uint3 id : SV_DispatchThreadID)
    74. {
    75.     if((int)id.x >= _TriangleCount)
    76.     {
    77.         return;
    78.     }
    79.    
    80.    
    81.     InputTriangle inputTriangle = _InputTrianglesBuffer[id.x];
    82.    
    83.     DrawTriangle tri = (DrawTriangle) 0;
    84.    
    85.     for (int i = 0; i < _Layers; i++)
    86.     {
    87.         DrawVertex drawVertices[3];
    88.        
    89.         float factor = (float)(i + 1) / (float) _Layers;
    90.        
    91.         float3 position = inputTriangle.vertex0.position +
    92.             inputTriangle.vertex0.normal * _HeightOffset * factor;
    93.         drawVertices[0] = GetVertex(position, inputTriangle.vertex0.normal,
    94.             inputTriangle.vertex0.uv, float4(factor, 0, 0, 1.0));
    95.        
    96.         position = inputTriangle.vertex1.position +
    97.             inputTriangle.vertex1.normal * _HeightOffset * factor;
    98.         drawVertices[1] = GetVertex(position, inputTriangle.vertex1.normal,
    99.             inputTriangle.vertex1.uv, float4(factor, 0, 0, 1.0));
    100.        
    101.         position = inputTriangle.vertex2.position +
    102.             inputTriangle.vertex2.normal * _HeightOffset * factor;
    103.         drawVertices[2] = GetVertex(position, inputTriangle.vertex2.normal,
    104.             inputTriangle.vertex2.uv, float4(factor, 0, 0, 1.0));
    105.        
    106.        
    107.         tri.drawVertices[0] = drawVertices[0];
    108.         tri.drawVertices[1] = drawVertices[1];
    109.         tri.drawVertices[2] = drawVertices[2];
    110.         _DrawTrianglesBuffer.Append(tri);
    111.     }
    112.    
    113.     InterlockedAdd(_IndirectArgsBuffer[0].numVerticesPerInstance, 3 * _Layers);
    114. }
    115.  
    116. [numthreads(64,1,1)]
    117. void ShellTextureGeoAnim (uint3 id : SV_DispatchThreadID)
    118. {
    119.     if((int)id.x >= _TriangleCount)
    120.     {
    121.         return;
    122.     }
    123.  
    124.     int index1 = _InputIndexBuffer.Load((id.x * 3) * 4);
    125.     int index2 = _InputIndexBuffer.Load((id.x * 3 + 1) * 4);
    126.     int index3 = _InputIndexBuffer.Load((id.x * 3 + 2) * 4);
    127.  
    128.     InputVertex vertex0;
    129.     vertex0.position = asfloat(_InputVertexBuffer.Load3(index1 * 40));
    130.     vertex0.normal = asfloat(_InputVertexBuffer.Load3(index1 * 40 + 12));
    131.     vertex0.uv = asfloat(_InputUVBuffer.Load2(index1 * 8)) * _UVScale.xy;
    132.  
    133.     InputVertex vertex1;
    134.     vertex1.position = asfloat(_InputVertexBuffer.Load3(index2 * 40));
    135.     vertex1.normal = asfloat(_InputVertexBuffer.Load3(index2 * 40 + 12));
    136.     vertex1.uv = asfloat(_InputUVBuffer.Load2(index2 * 8)) * _UVScale.xy;
    137.  
    138.     InputVertex vertex2;
    139.     vertex2.position = asfloat(_InputVertexBuffer.Load3(index3 * 40));
    140.     vertex2.normal = asfloat(_InputVertexBuffer.Load3(index3 * 40 + 12));
    141.     vertex2.uv = asfloat(_InputUVBuffer.Load2(index3 * 8)) * _UVScale.xy;
    142.  
    143.     float3 vel = float3(0,0,0);
    144.     float3 vel1 = float3(0,0,0);
    145.     float3 vel2 = float3(0,0,0);
    146.  
    147.     //Just loading these values in and assigning them to the drawVertices buffer makes it not render when Im not even using these values anywhere else
    148.     vel = asfloat(_InputPreviousVertexBuffer.Load3(index1 * 40));
    149.     vel1 = asfloat(_InputPreviousVertexBuffer.Load3(index2 * 40));
    150.     vel2 = asfloat(_InputPreviousVertexBuffer.Load3(index3 * 40));
    151.    
    152.     InputTriangle inputTriangle;
    153.     inputTriangle.vertex0 = vertex0;
    154.     inputTriangle.vertex1 = vertex1;
    155.     inputTriangle.vertex2 = vertex2;
    156.    
    157.     DrawTriangle tri = (DrawTriangle) 0;
    158.  
    159.     for (int i = 0; i < _Layers; i++)
    160.     {
    161.         DrawVertex drawVertices[3];
    162.        
    163.         float factor = (float)(i + 1) / (float) _Layers;
    164.        
    165.         float3 position = inputTriangle.vertex0.position + inputTriangle.vertex0.normal * _HeightOffset * factor;
    166.         drawVertices[0] = GetVertex(position, inputTriangle.vertex0.normal, inputTriangle.vertex0.uv, float4(factor, vel));
    167.        
    168.         position = inputTriangle.vertex1.position + inputTriangle.vertex1.normal * _HeightOffset * factor;
    169.         drawVertices[1] = GetVertex(position, inputTriangle.vertex1.normal, inputTriangle.vertex1.uv, float4(factor, vel1));
    170.        
    171.         position = inputTriangle.vertex2.position + inputTriangle.vertex2.normal * _HeightOffset * factor;
    172.         drawVertices[2] = GetVertex(position, inputTriangle.vertex2.normal, inputTriangle.vertex2.uv, float4(factor, vel2));
    173.        
    174.         tri.drawVertices[0] = drawVertices[0];
    175.         tri.drawVertices[1] = drawVertices[1];
    176.         tri.drawVertices[2] = drawVertices[2];
    177.         _DrawTrianglesBuffer.Append(tri);
    178.     }
    179.    
    180.     InterlockedAdd(_IndirectArgsBuffer[0].numVerticesPerInstance, 3 * _Layers);
    181. }
    182.  


    here is my urp shader code
    Code (CSharp):
    1. Shader "Custom/ShellTexturingLit" {
    2.     Properties{
    3.         [Header(Surface options)]
    4.         [MainTexture] _ColorMap("Color", 2D) = "white" {}
    5.         [MainTexture] _NoiseMap("Noise map", 2D) = "white" {}
    6.         [MainColor] _ColorTint("Tint", Color) = (1, 1, 1, 1)
    7.         _Smoothness("Smoothness", Float) = 0
    8.        
    9.         [HideInInspector] _SourceBlend("Source blend", float) = 0
    10.         [HideInInspector] _DestBlend("Destination blend", float) = 0
    11.         [HideInInspector] _Zwrite("Zwrite", float) = 0
    12.        
    13.         [HideInInspector] _SurfaceType("Surface type", float) = 0
    14.     }
    15.     SubShader {
    16.         Tags {"RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque"}
    17.  
    18.         Pass {
    19.             Name "ForwardLit"
    20.             Tags{"LightMode" = "UniversalForward" }
    21.             // "UniversalForward" tells Unity this is the main lighting pass of this shader
    22.            
    23.             Cull off
    24.             blend [_SourceBlend] [_DestBlend]
    25.             Zwrite [_Zwrite]
    26.  
    27.             HLSLPROGRAM
    28.  
    29.             #define _SPECULAR_COLOR
    30.  
    31.             // Shader variant keywords
    32.             // Unity automatically discards unused variants created using "shader_feature" from your final game build,
    33.             // however it keeps all variants created using "multi_compile"
    34.             // For this reason, multi_compile is good for global keywords or keywords that can change at runtime
    35.             // while shader_feature is good for keywords set per material which will not change at runtime
    36.  
    37.             // Global URP keywords
    38. #if UNITY_VERSION >= 202120
    39.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
    40. #else
    41.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
    42.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
    43. #endif
    44.             #pragma multi_compile_fragment _ _SHADOWS_SOFT
    45.  
    46.             #pragma vertex Vertex
    47.             #pragma fragment Fragment
    48.             #pragma target 5.0
    49.  
    50.             #include "ShellTexturingLitPass.hlsl"
    51.             ENDHLSL
    52.         }
    53.  
    54.         Pass {
    55.             Name "ShadowCaster"
    56.             Tags{"LightMode" = "ShadowCaster"}
    57.  
    58.             ColorMask 0 // No color output, only depth
    59.            
    60.  
    61.             HLSLPROGRAM
    62.             #pragma vertex Vertex
    63.             #pragma fragment Fragment
    64.  
    65.             #pragma shader_feature_local _ALPHA_CUTOUT
    66.            
    67.             #include "ShellTexturingShadowCastPass.hlsl"
    68.             ENDHLSL
    69.         }
    70.     }
    71.    
    72.     CustomEditor "LitCustomInspector"
    73. }
    Code (CSharp):
    1. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    2.  
    3. // Textures
    4. TEXTURE2D(_ColorMap); SAMPLER(sampler_ColorMap);
    5. TEXTURE2D(_NoiseMap); SAMPLER(sampler_NoiseMap);
    6.  
    7. float4 _ColorMap_ST; // This is automatically set by Unity. Used in TRANSFORM_TEX to apply UV tiling
    8. float4 _ColorTint;
    9. float _Smoothness;
    10.  
    11. struct Attributes {
    12.     uint id : SV_VertexID;
    13. };
    14.  
    15. struct Interpolators {
    16.     float4 positionCS : SV_POSITION;
    17.     float2 uv : TEXCOORD0;
    18.     float3 positionWS : TEXCOORD1;
    19.     float3 normalWS : TEXCOORD2;
    20.     float4 color : COLOR;
    21. };
    22.  
    23. struct DrawVertex
    24. {
    25.     float3 position;
    26.     float3 normal;
    27.     float2 uv;
    28.     float4 color;
    29. };
    30.  
    31. struct DrawTriangle
    32. {
    33.     DrawVertex drawVertices[3];
    34. };
    35.  
    36. StructuredBuffer<DrawTriangle> _DrawTrianglesBuffer;
    37.  
    38. half3 CalculateDiffuse(Light light, InputData inputData, SurfaceData surfaceData)
    39. {
    40.     half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
    41.     half3 lightColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
    42.  
    43.     lightColor *= surfaceData.albedo;
    44.  
    45.     #if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
    46.     half smoothness = exp2(10 * surfaceData.smoothness + 1);
    47.  
    48.     //lightColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness);
    49.     #endif
    50.  
    51.     return lightColor;
    52. }
    53.  
    54. half4 UniversalFragment(InputData inputData, SurfaceData surfaceData)
    55. {
    56.     #if defined(DEBUG_DISPLAY)
    57.     half4 debugColor;
    58.  
    59.     if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
    60.     {
    61.         return debugColor;
    62.     }
    63.     #endif
    64.  
    65.     uint meshRenderingLayers = GetMeshRenderingLightLayer();
    66.     half4 shadowMask = CalculateShadowMask(inputData);
    67.     AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
    68.     Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
    69.  
    70.     MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor);
    71.  
    72.     inputData.bakedGI *= surfaceData.albedo;
    73.  
    74.     LightingData lightingData = CreateLightingData(inputData, surfaceData);
    75.     if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
    76.     {
    77.         lightingData.mainLightColor += CalculateDiffuse(mainLight, inputData, surfaceData);
    78.     }
    79.  
    80.     #if defined(_ADDITIONAL_LIGHTS)
    81.     uint pixelLightCount = GetAdditionalLightsCount();
    82.  
    83.     #if USE_CLUSTERED_LIGHTING
    84.     for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
    85.     {
    86.         Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
    87.         if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
    88.         {
    89.             lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData);
    90.         }
    91.     }
    92.     #endif
    93.  
    94.     LIGHT_LOOP_BEGIN(pixelLightCount)
    95.         Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
    96.         if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
    97.         {
    98.             lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData);
    99.         }
    100.     LIGHT_LOOP_END
    101.     #endif
    102.  
    103.     #if defined(_ADDITIONAL_LIGHTS_VERTEX)
    104.     lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
    105.     #endif
    106.  
    107.     return CalculateFinalColor(lightingData, surfaceData.alpha);
    108. }
    109.  
    110.  
    111. Interpolators Vertex(Attributes input) {
    112.     Interpolators output;
    113.  
    114.     DrawTriangle tri = _DrawTrianglesBuffer[input.id / 3];
    115.     DrawVertex v = tri.drawVertices[input.id  % 3];
    116.    
    117.     VertexPositionInputs posnInputs = GetVertexPositionInputs(v.position);
    118.     VertexNormalInputs normInputs = GetVertexNormalInputs(v.normal);
    119.    
    120.     output.positionCS = posnInputs.positionCS;
    121.     output.uv = v.uv;
    122.     output.normalWS = normInputs.normalWS;
    123.     output.positionWS = posnInputs.positionWS;
    124.     output.color = v.color;
    125.  
    126.     return output;
    127. }
    128.  
    129. float4 Fragment(Interpolators input) : SV_TARGET{
    130.     float2 uv = input.uv;
    131.     float4 color = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, uv);
    132.     float tex = SAMPLE_TEXTURE2D(_NoiseMap, sampler_NoiseMap, uv).x;
    133.     clip(tex - input.color.x);
    134.  
    135.     InputData lightingInput = (InputData)0;
    136.     lightingInput.positionWS = input.positionWS;
    137.     lightingInput.normalWS = normalize(input.normalWS);
    138.     lightingInput.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
    139.     lightingInput.shadowCoord = TransformWorldToShadowCoord(input.positionWS);
    140.    
    141.     SurfaceData surfaceInput = (SurfaceData)0;
    142.     surfaceInput.albedo = _ColorTint * input.color.x;
    143.     surfaceInput.albedo = input.color.yzw;
    144.     surfaceInput.alpha = 1;
    145.     surfaceInput.specular = 1;
    146.     surfaceInput.smoothness = _Smoothness;
    147.  
    148. #if UNITY_VERSION >= 202120
    149.     return UniversalFragment(lightingInput, surfaceInput);
    150. #else
    151.     return UniversalFragmentBlinnPhong(lightingInput, surfaceInput.albedo, float4(surfaceInput.specular, 1), surfaceInput.smoothness, surfaceInput.emission, surfaceInput.alpha);
    152. #endif
    153. }
    Code (CSharp):
    1. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    2.  
    3. struct Attributes {
    4.     uint id : SV_VertexID;
    5. };
    6.  
    7. struct Interpolators {
    8.     float4 positionCS : SV_POSITION;
    9.     float2 uv : TEXCOORD0;
    10.     float4 color : COLOR;
    11. };
    12.  
    13. struct DrawVertex
    14. {
    15.     float3 position;
    16.     float3 normal;
    17.     float2 uv;
    18.     float4 color;
    19. };
    20.  
    21. struct DrawTriangle
    22. {
    23.     DrawVertex drawVertices[3];
    24. };
    25.  
    26. StructuredBuffer<DrawTriangle> _DrawTrianglesBuffer;
    27.  
    28. float3 _LightDirection;
    29.  
    30. float4 GetShadowCasterPositionCS(float3 positionWS, float3 normalWS) {
    31.     float3 lightDirectionWS = _LightDirection;
    32.     float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
    33.    
    34.     // We have to make sure that the shadow bias didn't push the shadow out of
    35.     // the camera's view area. This is slightly different depending on the graphics API
    36.     #if UNITY_REVERSED_Z
    37.     positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE);
    38.     #else
    39.     positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE);
    40.     #endif
    41.     return positionCS;
    42. }
    43.  
    44. Interpolators Vertex(Attributes input) {
    45.     Interpolators output;
    46.  
    47.     DrawTriangle tri = _DrawTrianglesBuffer[input.id / 3];
    48.     DrawVertex v = tri.drawVertices[input.id  % 3];
    49.  
    50.     output.uv = v.uv;
    51.     output.color = v.color;
    52.  
    53.     VertexPositionInputs posnInputs = GetVertexPositionInputs(v.position);
    54.     VertexNormalInputs normInputs = GetVertexNormalInputs(v.normal);
    55.  
    56.     output.positionCS = GetShadowCasterPositionCS(posnInputs.positionWS, normInputs.normalWS);
    57.     return output;
    58. }
    59.  
    60. TEXTURE2D(_ColorMap); SAMPLER(sampler_ColorMap);
    61.  
    62.  
    63. float4 Fragment(Interpolators input) : SV_TARGET {
    64.     float tex = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, input.uv).x;
    65.     clip(tex - input.color.x);
    66.     return 0;
    67. }