I am trying to create a rope-like thing, but have to generate the mesh part by part. Although the mesh is cut in parts, I want it to look smoothly. I have already kept the crosssection of each part well-joined, but failed to figure out how to smooth the seams in shader between every two parts. Could anyone please to help? Thank you.

Here are the codes to generate the 3d rope-like thing
`

extends Node3D

var radius := .12
var resolution := 7

var points = null
var fake_up_vectors = null
var tangents := []

func apply_curve(curve):
	
	$Path3D.set_curve(curve)

	# pre-set the curve bake interval, by default it is .2
	curve.set_bake_interval(.1) 
	
	# init points, fake_up_vectors and tangents
	points = curve.get_baked_points()
	fake_up_vectors = curve.get_baked_up_vectors()
	tangents = []
	
	
	for i in points.size():
		
		if i > 0 and i < points.size() - 1:
			# not endpoint
			tangents.push_back((points[i + 1] - points[i - 1]).normalized())

		else:
			# manipulate the up vector for the first and last point
			if i <= 0:
				if curve.get_point_out(0):
					tangents.push_back(curve.get_point_out(0).normalized())
				else:
					tangents.push_back((points[i + 1] - points[i]).normalized())
			else:
				if curve.get_point_in(curve.get_point_count() - 1):
					tangents.push_back((Vector3(0,0,0) - curve.get_point_in(curve.get_point_count() - 1)).normalized())
				else:
					tangents.push_back((points[i] - points[i - 1]).normalized())
		

		var plane = Plane(tangents[i])
		fake_up_vectors[i] = plane.project(Vector3(0,0,1)).normalized()


	extrude()

func extrude():
	var vertices := PackedVector3Array()
	var indices := PackedInt32Array()
	
	for point_index in points.size():

		var center = points[point_index]
		
		var tangent = tangents[point_index]
		var cross = Vector3(0,0,1).cross(tangent).normalized()
		var angle = Vector3(0,0,1).signed_angle_to(tangent, cross)
		var angle2 = .0
		
		vertices.push_back(center) # center of the circle
		var vertice_ind_ori = point_index * (resolution + 1) # index for the center
		
		for section in resolution:
			var degree = PI * 2 * section / resolution
			var x = radius * sin(degree)
			var y = radius * cos(degree)
			
			var coords = Vector3(x, y, 0).rotated(cross, angle)
			
			if section == 0: angle2 = coords.signed_angle_to(fake_up_vectors[point_index], tangent)
			
			coords = coords.rotated(tangent, angle2)
			
			vertices.push_back(coords + center)

			if point_index >= 1:
				# draw triangles
				# 1 3
				# 0 2
				var vertice_ind_0 = vertice_ind_ori + section + 1
				var vertice_ind_1 = vertice_ind_0 - (resolution + 1)
				var vertice_ind_2 = (vertice_ind_0 + 1) if (section < resolution - 1) else (vertice_ind_0 + 1 - resolution)
				var vertice_ind_3 = vertice_ind_2 - (resolution + 1)

				indices.append_array(PackedInt32Array([
					vertice_ind_0, vertice_ind_1, vertice_ind_3,
					vertice_ind_0, vertice_ind_3, vertice_ind_2
				]))
		
	var arrays = []
	arrays.resize(Mesh.ARRAY_MAX)
	arrays[Mesh.ARRAY_VERTEX] = vertices
	arrays[Mesh.ARRAY_INDEX] = indices
	
	var arr_mesh = ArrayMesh.new()
	arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
	
	var surface_tool = SurfaceTool.new()

	surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
	for v in vertices:
		surface_tool.add_vertex(v)
	for i in indices:
		surface_tool.add_index(i)

	surface_tool.generate_normals()
	arr_mesh = surface_tool.commit()
	
	$MeshInstance3D.mesh = arr_mesh

`

  • xyz replied to this.
  • Stooooone Make cross section normals at the start same as those at the end.

    xyz Thank you! it works. Now I assign normals manually and it looks neater than using surface tool.