Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

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:
    6
    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:
    6
    Btw I use alpha cutout in the shader since its not clear
     
  3. Invertex

    Invertex

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

    BotsOP

    Joined:
    Jun 9, 2020
    Posts:
    6
    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:
    6
    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:
    6
    Oh I have 2 different buffers because one is the animated vertex pos and nor and the other is just the static uv information