Canvas Texture Seams/Artifact Lines at Repeat Border

Even better news! Given gkjohnson’s ^ feedback regarding NearestFilter (and I agree with you about SMAA, that should not be needed for the solution), and given my improved understanding of UV coordinates, I got it working without either of those!


Before I delve into it, I will note that the UV coordinates described in this article (about Three JS!) - and also in some StackExchange posts - detailed the UV coordinates being oriented like this:

//Corners in UV coordinates:
//   (0, 1)   Back  (1, 1)
//          0-----1
//    Left / Top / Right
//        3-----2
//(0, 0)  Front  (1, 0)
//Note: ^ This ^ appears to be incorrect for Three JS, see below.

(bottom left being (0, 0) and top right being (1, 1)), where the coordinate system is of course like this:

//Directions:
//  -Z    /\+Y
//-X  +X  ||
//  +Z    \/-Y

But in order to get it working, I had to use this:

//Corners in UV coordinates:
//   (0, 0)   Back  (1, 0)
//          0-----1
//    Left / Top / Right
//        3-----2
//(0, 1)  Front  (1, 1)

(top left being (0, 0) and bottom right being (1, 1)). The only way I figured this out was by alert()ing what the working code was doing.

Once I had this diagram in my comments, it was easy to figure out how to manually specify the UV coordinates (note that I don’t have to do the XYZ component sorting here because the normals would all be like (X: 0, Y: 1, Z: 0), Y would get sorted to the end, and X and Z would be utilized):

//First face is corners (0, 3, 1).
this.topGeometry.faceVertexUvs[0].push([
    new THREE.Vector2(0.0, 0.0),
    new THREE.Vector2(0.0, 1.0),
    new THREE.Vector2(1.0, 0.0)
]);
//Second face is corners (2, 1, 3).
this.topGeometry.faceVertexUvs[0].push([
    new THREE.Vector2(1.0, 1.0),
    new THREE.Vector2(1.0, 0.0),
    new THREE.Vector2(0.0, 1.0)
]);

(I do this for each pair of Face3 triangles, with the corners indicated in the comments above.)

This works beautifully! Even without SMAA or any customization settings for the CanvasTexture!


(Defaults: mapping: THREE.UVMapping (of course), wrapS and wrapT: THREE.ClampToEdgeWrapping, magFilter: THREE.LinearFilter, minFilter: THREE.LinearMipmapLinearFilter)

So you are correct, gkjohnson. Thanks again.


Since it is now possible, I’ll update the JSFiddle to show the working code now: https://jsfiddle.net/7052h469
(Skip past the code at the top, the main code to see is the GrassMaterials array creation and the GameMap class. Uncomment line 94 to see the actual canvases.)

It looks like this: