Creating a mesh with four or more vertices and wrapping a texture on it. But I can't seem to get the texture to wrap correctly/how I want it onto the mesh.
Seems like its doesn't take into account more than 3 vertices in the uv/texture calculation.

In opengl I would have created a GL_QUAD or a GL_POLYGON to create this, but godot only provides triangles as primitives.

Image 1: How it looks when creating a trapezoid
Image 2: About how I want it to look
Image 3: Context about what I try to use it for



  • Tomcat replied to this.
  • Your mesh is fine. The artifact you see is due the nature of linear interpolation of uvs over triangle surfaces. It happens in 3d editing apps too. To remedy it, you can either add more subdivisions or use some form of projective mapping in a custom shader.

    Kato But I can't seem to get the texture to wrap correctly/how I want it onto the mesh.

    As far as I know, Godot still can't handle UV properly. It's recommended to do the texture sweep of models in an external editor (Blender, for example).

    Thanks for the quick answer.
    That is unfortunate. The models can't really be prepared externally as they are dynamic by nature. But I'll try to think of a different solution.

    Kato I am assigning correct UV to each vertex, but it is not being rendered correctly

    show the code? Also are you using meshdatatool or surfacetool? Or arraymesh?

    • Kato replied to this.

      Megalomaniak

      Attached the godot project:

      test.zip
      9MB
      var surface_array = []
      	surface_array.resize(Mesh.ARRAY_MAX)
      	var vertices = PackedVector3Array()
      	var uvcoords = PackedVector2Array()
      	var indices = PackedInt32Array()
      	
      	vertices.push_back(Vector3(-0.2, 1, 0))
      	vertices.push_back(Vector3(0.2, 1, 0))
      	vertices.push_back(Vector3(1,-1,0))
      	vertices.push_back(Vector3(-1,-1,0))
      	
      	uvcoords.push_back(Vector2(0,0))
      	uvcoords.push_back(Vector2(1,0))
      	uvcoords.push_back(Vector2(1,1))
      	uvcoords.push_back(Vector2(0,1))
      	
      	indices.push_back(0)
      	indices.push_back(1)
      	indices.push_back(2)
      	
      	indices.push_back(0)
      	indices.push_back(2)
      	indices.push_back(3)
      	
      	surface_array[Mesh.ARRAY_VERTEX] = vertices
      	surface_array[Mesh.ARRAY_TEX_UV] = uvcoords
      	surface_array[Mesh.ARRAY_INDEX] = indices
      	
      	var mesh = ArrayMesh.new()
      	#mesh.blend_shape_mode = Mesh.BLEND_SHAPE_MODE_NORMALIZED
      	mesh.blend_shape_mode = Mesh.BLEND_SHAPE_MODE_RELATIVE
      	mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)
      	$mesh_instance.mesh = mesh

      Megalomaniak

      I have tried using meshdatatool, surfacetool, arraymesh and ImmediateMesh.
      They all produce the same result.

      Your mesh is fine. The artifact you see is due the nature of linear interpolation of uvs over triangle surfaces. It happens in 3d editing apps too. To remedy it, you can either add more subdivisions or use some form of projective mapping in a custom shader.

      • Kato replied to this.

        xyz
        Okay, thanks.
        I'll look into that.

        @xyz Shouldn't it be perspective correct though? I don't recall seeing this problem except with software renderers back in the day.

        • xyz replied to this.

          cybereality
          This is not perspective correction issue. Perspective correct mapping is built into GPU rasterization so we don't need to worry about it. But this issue will happen even with orthographic camera projections.

          The problem is that texture cannot be distributed evenly throughout the trapezoid (as we might naively expect) because we're not actually mapping a quad. We're mapping two triangles of different physical size, each occupying the same amount of area in uv space. The result is difference in texture appearance on triangles. The mapping is in fact mathematically correct. This becomes obvious if we draw triangle outlines and compare them in 3d space vs. uv space.

          Oh right, I get it. It doesn't happen with artist created meshes because the UV is not going from 0 to 1 (it's a trapezoid in the UV map).

          But with simple shapes you can trivially create the UVs by hand, for example using trig functions.

          • xyz replied to this.

            cybereality But with simple shapes you can trivially create the UVs by hand, for example using trig functions.

            Yeah, you can do some form of projective/procedural mapping. For best results is should be done per pixel in the fragment shader. The type of projection depends on the geometry and the effect you're after. Looking at previous screenshots from the OP, they're making spheres. Their trapezoid example was just a singled out non-rectangular face from a geo sphere. Spherical projection could be a good option in this case.