Search Unity

Question Weird clipping on shell texture material URP

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

  1. BotsOP

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    9
    Im trying to create a shell texture material on an animated mesh in urp
    but im having some weird clip problems as you can see here
    clip.gif

    I followed this stream to get the basics down:

    Used this blog to understand more of the theory:
    https://xbdev.net/directx3dx/specialX/Fur/
    And neds tutorial on urp shaders


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



    Compute shader code
    I have removed the non animated code to save a bit of space
    Code (hlsl):
    1.  
    2. // Each #kernel tells which function to compile; you can have many kernels
    3. //#pragma kernel ShellTextureGeo
    4. #pragma kernel ShellTextureGeoAnim
    5.  
    6. struct InputVertex
    7. {
    8.     float3 position;
    9.     float3 normal;
    10.     float2 uv;
    11. };
    12.  
    13. struct InputTriangle
    14. {
    15.     InputVertex vertex0;
    16.     InputVertex vertex1;
    17.     InputVertex vertex2;
    18.  
    19.     // InputTriangle(InputVertex _Vertex0, InputVertex _Vertex1, InputVertex _Vertex2)
    20.     // {
    21.     //     vertex0 = _Vertex0;
    22.     //     vertex1 = _Vertex1;
    23.     //     vertex2 = _Vertex2;
    24.     // }
    25. };
    26.  
    27. struct DrawVertex
    28. {
    29.     float3 position;
    30.     float3 normal;
    31.     float2 uv;
    32.     float4 color;
    33. };
    34.  
    35. struct DrawTriangle
    36. {
    37.     DrawVertex drawVertices[3];
    38. };
    39.  
    40. struct IndirectArgs
    41. {
    42.     uint numVerticesPerInstance;
    43.     uint numInstances;
    44.     uint startVertexIndex;
    45.     uint startInstanceIndex;
    46. };
    47.  
    48. StructuredBuffer<InputTriangle> _InputTrianglesBuffer;
    49. AppendStructuredBuffer<DrawTriangle> _DrawTrianglesBuffer;
    50. RWStructuredBuffer<IndirectArgs> _IndirectArgsBuffer;
    51.  
    52. RWByteAddressBuffer _InputVertexBuffer;
    53. RWByteAddressBuffer _InputIndexBuffer;
    54. RWByteAddressBuffer _InputUVBuffer;
    55.  
    56. int _TriangleCount;
    57. float4x4 _LocalToWorld;
    58. float4x4 _Offset;
    59. int _Layers;
    60. float _HeightOffset;
    61. float _UVScale;
    62.  
    63. DrawVertex GetVertex(float3 position, float3 normal, float2 uv, float4 color)
    64. {
    65.     DrawVertex output = (DrawVertex) 0;
    66.     float3 pos = mul(_Offset, float4(position, 1.0));
    67.     output.position = mul(_LocalToWorld, float4(pos, 1.0)).xyz;
    68.     output.normal = mul(_LocalToWorld, float4(normal, 0.0)).xyz;
    69.     output.uv = uv;
    70.     output.color = color;
    71.     return output;
    72. }
    73.  
    74. [numthreads(64,1,1)]
    75. void ShellTextureGeoAnim (uint3 id : SV_DispatchThreadID)
    76. {
    77.     if((int)id.x >= _TriangleCount)
    78.     {
    79.         return;
    80.     }
    81.  
    82.     int index1 = _InputIndexBuffer.Load((id.x * 3) * 4);
    83.     int index2 = _InputIndexBuffer.Load((id.x * 3 + 1) * 4);
    84.     int index3 = _InputIndexBuffer.Load((id.x * 3 + 2) * 4);
    85.  
    86.     InputVertex vertex0;
    87.     vertex0.position = asfloat(_InputVertexBuffer.Load3(index1 * 40));
    88.     vertex0.normal = asfloat(_InputVertexBuffer.Load3(index1 * 40 + 12));
    89.     vertex0.uv = asfloat(_InputVertexBuffer.Load2(index1 * 8)) * _UVScale;
    90.  
    91.     InputVertex vertex1;
    92.     vertex1.position = asfloat(_InputVertexBuffer.Load3(index2 * 40));
    93.     vertex1.normal = asfloat(_InputVertexBuffer.Load3(index2 * 40 + 12));
    94.     vertex1.uv = asfloat(_InputVertexBuffer.Load2(index2 * 8)) * _UVScale;
    95.  
    96.     InputVertex vertex2;
    97.     vertex2.position = asfloat(_InputVertexBuffer.Load3(index3 * 40));
    98.     vertex2.normal = asfloat(_InputVertexBuffer.Load3(index3 * 40 + 12));
    99.     vertex2.uv = asfloat(_InputVertexBuffer.Load2(index3 * 8)) * _UVScale;
    100.    
    101.     InputTriangle inputTriangle;
    102.     inputTriangle.vertex0 = vertex0;
    103.     inputTriangle.vertex1 = vertex1;
    104.     inputTriangle.vertex2 = vertex2;
    105.    
    106.     DrawTriangle tri = (DrawTriangle) 0;
    107.  
    108.     for (int i = 0; i < _Layers; i++)
    109.     {
    110.         DrawVertex drawVertices[3];
    111.        
    112.         float factor = (float)(i + 1) / (float) _Layers;
    113.        
    114.         float3 position = inputTriangle.vertex0.position + inputTriangle.vertex0.normal * _HeightOffset * factor;
    115.         drawVertices[0] = GetVertex(position, inputTriangle.vertex0.normal, inputTriangle.vertex0.uv, float4(factor, 0, 0, 1.0));
    116.        
    117.         position = inputTriangle.vertex1.position + inputTriangle.vertex1.normal * _HeightOffset * factor;
    118.         drawVertices[1] = GetVertex(position, inputTriangle.vertex1.normal, inputTriangle.vertex1.uv, float4(factor, 0, 0, 1.0));
    119.        
    120.         position = inputTriangle.vertex2.position + inputTriangle.vertex2.normal * _HeightOffset * factor;
    121.         drawVertices[2] = GetVertex(position, inputTriangle.vertex2.normal, inputTriangle.vertex2.uv, float4(factor, 0, 0, 1.0));
    122.        
    123.        
    124.         tri.drawVertices[0] = drawVertices[0];
    125.         tri.drawVertices[1] = drawVertices[1];
    126.         tri.drawVertices[2] = drawVertices[2];
    127.         _DrawTrianglesBuffer.Append(tri);
    128.     }
    129.    
    130.     InterlockedAdd(_IndirectArgsBuffer[0].numVerticesPerInstance, 3 * _Layers);
    131. }
    132.  


    Here is my material shader code
    Code (hlsl):
    1. Shader "Custom/ShellTexturingLit" {
    2.     Properties{
    3.         [Header(Surface options)]
    4.         [MainTexture] _ColorMap("Color", 2D) = "white" {}
    5.         [MainColor] _ColorTint("Tint", Color) = (1, 1, 1, 1)
    6.         _Smoothness("Smoothness", Float) = 0
    7.        
    8.         [HideInInspector] _SourceBlend("Source blend", float) = 0
    9.         [HideInInspector] _DestBlend("Destination blend", float) = 0
    10.         [HideInInspector] _Zwrite("Zwrite", float) = 0
    11.        
    12.         [HideInInspector] _SurfaceType("Surface type", float) = 0
    13.     }
    14.     SubShader {
    15.         Tags {"RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque"}
    16.  
    17.         Pass {
    18.             Name "ForwardLit"
    19.             Tags{"LightMode" = "UniversalForward" }
    20.             // "UniversalForward" tells Unity this is the main lighting pass of this shader
    21.            
    22.             Cull off
    23.             blend [_SourceBlend] [_DestBlend]
    24.             Zwrite [_Zwrite]
    25.  
    26.             HLSLPROGRAM
    27.  
    28.             #define _SPECULAR_COLOR
    29.  
    30.             // Shader variant keywords
    31.             // Unity automatically discards unused variants created using "shader_feature" from your final game build,
    32.             // however it keeps all variants created using "multi_compile"
    33.             // For this reason, multi_compile is good for global keywords or keywords that can change at runtime
    34.             // while shader_feature is good for keywords set per material which will not change at runtime
    35.  
    36.             // Global URP keywords
    37. #if UNITY_VERSION >= 202120
    38.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
    39. #else
    40.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
    41.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
    42. #endif
    43.             #pragma multi_compile_fragment _ _SHADOWS_SOFT
    44.  
    45.             #pragma vertex Vertex
    46.             #pragma fragment Fragment
    47.             #pragma target 5.0
    48.  
    49.             #include "ShellTexturingLitPass.hlsl"
    50.             ENDHLSL
    51.         }
    52.  
    53.         Pass {
    54.             Name "ShadowCaster"
    55.             Tags{"LightMode" = "ShadowCaster"}
    56.  
    57.             ColorMask 0 // No color output, only depth
    58.            
    59.  
    60.             HLSLPROGRAM
    61.             #pragma vertex Vertex
    62.             #pragma fragment Fragment
    63.  
    64.             #pragma shader_feature_local _ALPHA_CUTOUT
    65.            
    66.             #include "ShellTexturingShadowCastPass.hlsl"
    67.             ENDHLSL
    68.         }
    69.     }
    70.    
    71.     CustomEditor "LitCustomInspector"
    72. }
    Code (hlsl):
    1. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    2.  
    3. // Textures
    4. TEXTURE2D(_ColorMap); SAMPLER(sampler_ColorMap);
    5.  
    6. float4 _ColorMap_ST; // This is automatically set by Unity. Used in TRANSFORM_TEX to apply UV tiling
    7. float4 _ColorTint;
    8. float _Smoothness;
    9.  
    10. struct Attributes {
    11.     uint id : SV_VertexID;
    12. };
    13.  
    14. struct Interpolators {
    15.     float4 positionCS : SV_POSITION;
    16.     float2 uv : TEXCOORD0;
    17.     float3 positionWS : TEXCOORD1;
    18.     float3 normalWS : TEXCOORD2;
    19.     float4 color : COLOR;
    20. };
    21.  
    22. struct DrawVertex
    23. {
    24.     float3 position;
    25.     float3 normal;
    26.     float2 uv;
    27.     float4 color;
    28. };
    29.  
    30. struct DrawTriangle
    31. {
    32.     DrawVertex drawVertices[3];
    33. };
    34.  
    35. StructuredBuffer<DrawTriangle> _DrawTrianglesBuffer;
    36.  
    37. Interpolators Vertex(Attributes input) {
    38.     Interpolators output;
    39.  
    40.     DrawTriangle tri = _DrawTrianglesBuffer[input.id / 3];
    41.     DrawVertex v = tri.drawVertices[input.id  % 3];
    42.    
    43.     VertexPositionInputs posnInputs = GetVertexPositionInputs(v.position);
    44.     VertexNormalInputs normInputs = GetVertexNormalInputs(v.normal);
    45.    
    46.     output.positionCS = posnInputs.positionCS;
    47.     output.uv = v.uv;
    48.     output.normalWS = normInputs.normalWS;
    49.     output.positionWS = posnInputs.positionWS;
    50.     output.color = v.color;
    51.  
    52.     return output;
    53. }
    54.  
    55. float4 Fragment(Interpolators input) : SV_TARGET{
    56.     float2 uv = input.uv;
    57.     float tex = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, uv).x;
    58.     clip(tex - input.color.x);
    59.  
    60.     InputData lightingInput = (InputData)0;
    61.     lightingInput.positionWS = input.positionWS;
    62.     lightingInput.normalWS = normalize(input.normalWS);
    63.     lightingInput.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
    64.     lightingInput.shadowCoord = TransformWorldToShadowCoord(input.positionWS);
    65.    
    66.     SurfaceData surfaceInput = (SurfaceData)0;
    67.     surfaceInput.albedo = _ColorTint.rgb;
    68.     surfaceInput.alpha = 1;
    69.     surfaceInput.specular = 1;
    70.     surfaceInput.smoothness = _Smoothness;
    71.  
    72. #if UNITY_VERSION >= 202120
    73.     return UniversalFragmentBlinnPhong(lightingInput, surfaceInput);
    74. #else
    75.     return UniversalFragmentBlinnPhong(lightingInput, surfaceInput.albedo, float4(surfaceInput.specular, 1), surfaceInput.smoothness, surfaceInput.emission, surfaceInput.alpha);
    76. #endif
    77. }
    Code (hlsl):
    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. }
     
  2. BotsOP

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    9
    Btw I use alpha cutout in the shader since its not clear
     
  3. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,549
    It might be the shadow depth/normal bias on your Light's settings. Try lowering them.
     
  4. BotsOP

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    9
    It does improve it a tiny bit but its still clipping if I move a bit further away
     
  5. BotsOP

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    9
    Found the bug had nothing to do with any weird settings but just a mistake on my part. When setting the uvs I was reading from the vertex buffer instead of the uv buffer. Dont even know why I have 2 different buffer both containing vertex data.
     
  6. BotsOP

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    9
    Oh I have 2 different buffers because one is the animated vertex pos and nor and the other is just the static uv information