I've been making a procedurally generated 3d world and ran into an issue with seams at the edges of chunks. The seams look like this:

I looked for information online and people said it had to do with different normals at the edge on the two meshes. So I made the mesh slightly bigger, calculated the normals, and then deleted the extra vertices. I was expecting this to fix the issue, but the edges still have visible seams (even though the normals at the edge vertices are equal). Anyone know how I can fix this?
My code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeshGenerator : MonoBehaviour
{
private Mesh mesh;
private Vector3[] vertices;
private int[] triangles;
private Vector2[] UVs;
//public Color[] colors;
private Gradient gradient;
public Vector3[] normals;
private int xSize = 200;
private int zSize = 200;
private float xDim = 10;
private float zDim = 10;
private GameObject player;
private int deleteDistance = 5;
// Start is called before the first frame update
void Start()
{
player = GameObject.Find("Player");
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
xDim = GameObject.Find("TerrainGen").GetComponent<TerrainGen>().xDim;
zDim = GameObject.Find("TerrainGen").GetComponent<TerrainGen>().zDim;
xSize = GameObject.Find("TerrainGen").GetComponent<TerrainGen>().xSize;
zSize = GameObject.Find("TerrainGen").GetComponent<TerrainGen>().zSize;
CreateShape();
UpdateMesh();
normals = mesh.normals;
normals = CalculateNormals();
RemoveEdges();
UpdateMesh();
mesh.normals = normals; // normals have been changed in RemoveEdges()
StartCoroutine(deleteMeshes());
}
// Update is called once per frame
void Update()
{
}
float fbm(float a, float b, int octaves, float amp, float freq)
{
float result = 0;
float ampmod = amp;
float freqmod = freq;
for(int i = 0; i < octaves; i++)
{
result += ampmod * (Mathf.PerlinNoise(Mathf.Abs(Mathf.Pow(10,3)+a*freqmod), Mathf.Abs(Mathf.Pow(10, 3) + b *freqmod)) - 0.5f);
ampmod = ampmod / 2;
freqmod = freqmod * 2;
}
//calculate max and min
float ampcalc = amp;
float sum = 0;
for(int i = 0; i < octaves; i++)
{
sum += 0.5f * ampcalc;
ampcalc = ampcalc / 2f;
}
MeshRenderer rend = GetComponent<MeshRenderer>();
rend.material.SetFloat("_Low", -1*sum);
rend.material.SetFloat("_High", sum);
return result;
}
void CreateShape()
{
//Creates a mesh slightly bigger than needed
vertices = new Vector3[(xSize + 1 + 2) * (zSize + 1 + 2)];
int i = 0;
for(int z = 0; z <= zSize + 2; z++)
{
for(int x = 0; x <= xSize + 2; x++)
{
vertices[i] = new Vector3(x / (xSize/xDim), 0, z / (zSize/zDim));
vertices[i].y = 3 * fbm((transform.position.x + vertices[i].x) * 0.0373f, (transform.position.z + vertices[i].z) * 0.0373f, 7, 3f, 2f);
i++;
}
}
triangles = new int[6 * (xSize+2) * (zSize+2)];
int trindex = 0;
int vertadd = 0;
for(int z = 0; z < zSize+2; z++)
{
for (int x = 0; x < xSize+2; x++)
{
triangles[0 + trindex] = vertadd + 0;
triangles[1 + trindex] = vertadd + xSize + 2 + 1;
triangles[2 + trindex] = vertadd + 1;
triangles[3 + trindex] = vertadd + xSize + 2 + 1;
triangles[4 + trindex] = vertadd + xSize + 2 + 2;
triangles[5 + trindex] = vertadd + 1;
trindex += 6;
vertadd++;
}
vertadd++;
}
UVs = new Vector2[vertices.Length];
for (int j = 0; j < UVs.Length; j++)
{
UVs[j] = new Vector2(vertices[j].x / (xSize+2), vertices[j].z / (zSize+2));
}
}
void RemoveEdges()
{
Vector3[] newVerts = new Vector3[(xSize + 1) * (zSize + 1)];
Vector3[] newNormals = new Vector3[(xSize + 1) * (zSize + 1)];
for (int z = 1; z < zSize + 2; z++)
{
for(int x = 1; x < xSize + 2; x++)
{
newVerts[(z - 1) * (zSize + 1) + (x - 1)] = vertices[(zSize + 3) * z + x];
newNormals[(z - 1) * (zSize + 1) + (x - 1)] = normals[(zSize + 3) * z + x];
}
}
int[] newTriangles = new int[6 * (xSize) * (zSize)];
int trindex = 0;
int vertadd = 0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
newTriangles[0 + trindex] = vertadd + 0;
newTriangles[1 + trindex] = vertadd + xSize + 1;
newTriangles[2 + trindex] = vertadd + 1;
newTriangles[3 + trindex] = vertadd + xSize + 1;
newTriangles[4 + trindex] = vertadd + xSize + 2;
newTriangles[5 + trindex] = vertadd + 1;
trindex += 6;
vertadd++;
}
vertadd++;
}
Vector2[] newUVs = new Vector2[newVerts.Length];
for (int j = 0; j < newUVs.Length; j++)
{
newUVs[j] = new Vector2(newVerts[j].x / (xSize + 2), newVerts[j].z / (zSize + 2));
}
vertices = newVerts;
triangles = newTriangles;
normals = newNormals;
UVs = newUVs;
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = UVs;
}
IEnumerator deleteMeshes()
{
while (true)
{
if(Mathf.Abs((transform.position.x + xDim/2 - player.transform.position.x)/xDim) >= (deleteDistance) || Mathf.Abs((transform.position.z + zDim/2 - player.transform.position.z) / zDim) >= (deleteDistance))
{
GameObject.Destroy(this.gameObject);
}
yield return new WaitForSeconds(1);
}
}
}