I tried to use DrawMeshInstancedIndirect to draw some grass onto my procedual terrain, but these grass disappears when I rotate the camera

I’ve tweaked the occlusion culling setting of the main camera, but that doesn’t work.
The C# code I used:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;

public class GrassRenderer : MonoSingleton<GrassRenderer>
{
    public Material grassMaterial;
    public ComputeShader grassComputeShader;

    private float boundSize = 30;
    private uint maxInstanceCount = 1000;

    private GraphicsBuffer argsBuffer;
    private ComputeBuffer outputGrassBuffer;
    private ComputeBuffer inputGrassBuffer;
    private static readonly int InstanceBuffer = Shader.PropertyToID("instance_buffer");
    private uint threadGroupSizeX;
    private Bounds bounds;
        
    struct GrassPrecomputeData
    {
        Vector3 position;
        
        public static int SizeOf => sizeof(float) * 3;
    }

    struct GrassInstanceData
    {
        Vector3 position;
        float height;
        float width;
        float darkness;
        float angle_dir;
        float bend;
    }

    protected override void Awake()
    {
        base.Awake();
        bounds = new Bounds(Vector3.zero, Vector3.one * boundSize);
    }

    private void Start()
    {
        InitBuffer();
    }

    private void OnDestroy()
    {
        DisposeBuffer();
    }

    private void InitBuffer()
    {
        argsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 5, sizeof(int));
        inputGrassBuffer = new ComputeBuffer((int)maxInstanceCount, GrassPrecomputeData.SizeOf,ComputeBufferType.Structured);
        outputGrassBuffer = new ComputeBuffer((int)maxInstanceCount, Marshal.SizeOf(typeof(GrassInstanceData)),ComputeBufferType.Structured);
        grassComputeShader.SetBuffer(0, "input_grass_buffer", inputGrassBuffer);
        grassComputeShader.SetBuffer(0, "output_grass_buffer", outputGrassBuffer);
        grassMaterial.SetBuffer(InstanceBuffer, outputGrassBuffer);
        grassComputeShader.GetKernelThreadGroupSizes(0, out uint x, out _, out _);
        threadGroupSizeX = x;
    }

    private void DisposeBuffer()
    {
        argsBuffer.Dispose();
        argsBuffer = null;
        outputGrassBuffer.Dispose();
        outputGrassBuffer = null;
        inputGrassBuffer.Dispose();
        inputGrassBuffer = null;
    }

    public uint InstanceCount
    {
        get => maxInstanceCount;
        set => maxInstanceCount = value;
    }

    public void DrawGrass(Vector3[] positions)
    {
        int currentInstanceCount;
        if (positions.Length > maxInstanceCount)
        {
            positions = new ArraySegment<Vector3>(positions, 0, (int)maxInstanceCount).ToArray();
            currentInstanceCount = (int)maxInstanceCount;
        }
        else
        {
            currentInstanceCount = positions.Length;
        }
        if(currentInstanceCount<=0)
        {
            return;
        }
       
        inputGrassBuffer.SetData(positions);
        grassComputeShader.SetInt("grass_count", currentInstanceCount);
        
        grassComputeShader.Dispatch(0, Mathf.CeilToInt(currentInstanceCount / (float)threadGroupSizeX), 1, 1);
        
        argsBuffer.SetData(new uint[] { GrassMeshData.GrassMesh.GetIndexCount(0), (uint)currentInstanceCount, 0, 0, 0 });
        Graphics.DrawMeshInstancedIndirect(GrassMeshData.GrassMesh,
            0,
            grassMaterial,
            bounds,
            argsBuffer);
    }
}

The urp shader:

Shader "Custom/Grass"
{
    Properties
    {
        _BaseColor ("Example Colour", Color) = (0, 0.66, 0.73, 1)
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }

        HLSLINCLUDE
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        
        CBUFFER_START(UnityPerMaterial)
            float4 _BaseColor;
        CBUFFER_END

        struct InstanceData
        {
            float3 position;
            float height;
            float width;
            float darkness;
            float angle_dir;
            float bend;
        };

        
        UNITY_INSTANCING_BUFFER_START(instance_buffer)
        StructuredBuffer<InstanceData> instance_buffer;
        UNITY_INSTANCING_BUFFER_END(instance_buffer)
        
        ENDHLSL

        Pass
        {
            Name "ForwardLit"
            Tags { "LightMode"="UniversalForward" }
            
            Cull Off
            
            HLSLPROGRAM
            #pragma vertex UnlitPassVertex
            #pragma fragment UnlitPassFragment
            #pragma instancing_options procedural:setup

            // Structs
            struct a2v
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
                float4 color : COLOR;
                
            };

            struct v2f
            {
                float4 positionCS : SV_POSITION;
            };

            // Vertex Shader
            v2f UnlitPassVertex(a2v IN, uint id : SV_InstanceID)
            {
               
                v2f OUT;
                const VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);
                const float3 position = instance_buffer[id].position + positionInputs.positionWS;
                OUT.positionCS = TransformWorldToHClip(position);
                return OUT;
            }

            // Fragment Shader
            half4 UnlitPassFragment(v2f IN) : SV_Target
            {
                return _BaseColor;
            }
            ENDHLSL
        }
    }
}

The compute shader which does nothing:

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

#include "../Noise/FastSnoise.hlsl"
#include "../Includes/QuaternionEssential.hlsl"

struct GrassInput
{
    float3 position;
};

struct GrassOutput
{
    float3 position;
    float height;
    float width;
    float darkness;
    float angle_dir;
    float bend;
};

int grass_count;
// float time;
// float wind_direction_angle;
// float wind_strength;
// float swing_speed;
// float swing_strength;

StructuredBuffer<GrassInput> input_grass_buffer;
RWStructuredBuffer<GrassOutput> output_grass_buffer;

[numthreads(64,1,1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    if (id.x >= grass_count)
    {
        return;
    }

    const float3 position = input_grass_buffer[id.x].position;

    // // Random swing
    // const float3 swing = swing_strength * float3(
    //     0.5 * (f_snoise(swing_speed * (position * 0.1 + time)) - 0.5),
    //     0.5 * (f_snoise(swing_speed * (position * 0.1 + time + 100)) - 0.5),
    //     0.5 * (f_snoise(swing_speed * (position * 0.1 + time + 200)) - 0.5)
    // );
    //
    //
    // const float3 wind_direction = float3(cos(wind_direction_angle), 0, sin(wind_direction_angle));
    // const float3 wind = wind_direction * wind_strength;
    GrassOutput output;
    output.position = position;
    output.height = 1.0;
    output.width = 1;
    output.darkness = 0.5;
    output.angle_dir = 0;
    output.bend = 0;
    output_grass_buffer[id.x] = output;
}