* Render the mesh at its current state (transforms, projection, tint) to an offscreen canvas. * The returned canvas can be used with `renderer.drawImage()`, as a `Sprite` image source, * or converted to an ImageBitmap via `createImageBitmap()`. * @returns {HTMLCanvasElement} an offscreen canva
()
| 907 | * renderer.drawImage(mesh.toCanvas(), 100, 100); |
| 908 | */ |
| 909 | toCanvas() { |
| 910 | const w = this.width; |
| 911 | const h = this.height; |
| 912 | |
| 913 | // project vertices into local space (no pos offset, no Z) |
| 914 | this._projectVertices(0, 0, false); |
| 915 | |
| 916 | // render to offscreen canvas using affine texture mapping |
| 917 | const canvas = document.createElement("canvas"); |
| 918 | canvas.width = w; |
| 919 | canvas.height = h; |
| 920 | const ctx = canvas.getContext("2d"); |
| 921 | |
| 922 | const image = this.texture.getTexture(); |
| 923 | const imgW = image.width; |
| 924 | const imgH = image.height; |
| 925 | const uvs = this.uvs; |
| 926 | const indices = this.indices; |
| 927 | const vertices = this.vertices; |
| 928 | const cullBack = this.cullBackFaces === true; |
| 929 | |
| 930 | // build visible triangles sorted back-to-front |
| 931 | const tris = []; |
| 932 | for (let j = 0; j < indices.length; j += 3) { |
| 933 | const i0 = indices[j]; |
| 934 | const i1 = indices[j + 1]; |
| 935 | const i2 = indices[j + 2]; |
| 936 | const x0 = vertices[i0 * 3]; |
| 937 | const y0 = vertices[i0 * 3 + 1]; |
| 938 | const x1 = vertices[i1 * 3]; |
| 939 | const y1 = vertices[i1 * 3 + 1]; |
| 940 | const x2 = vertices[i2 * 3]; |
| 941 | const y2 = vertices[i2 * 3 + 1]; |
| 942 | |
| 943 | if (cullBack) { |
| 944 | const cross = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0); |
| 945 | if (cross > 0) { |
| 946 | continue; |
| 947 | } |
| 948 | } |
| 949 | |
| 950 | tris.push(i0, i1, i2); |
| 951 | } |
| 952 | |
| 953 | // draw each triangle |
| 954 | for (let t = 0; t < tris.length; t += 3) { |
| 955 | const i0 = tris[t]; |
| 956 | const i1 = tris[t + 1]; |
| 957 | const i2 = tris[t + 2]; |
| 958 | const x0 = vertices[i0 * 3]; |
| 959 | const y0 = vertices[i0 * 3 + 1]; |
| 960 | const x1 = vertices[i1 * 3]; |
| 961 | const y1 = vertices[i1 * 3 + 1]; |
| 962 | const x2 = vertices[i2 * 3]; |
| 963 | const y2 = vertices[i2 * 3 + 1]; |
| 964 | |
| 965 | const u0 = uvs[i0 * 2] * imgW; |
| 966 | const v0 = uvs[i0 * 2 + 1] * imgH; |
no test coverage detected