createTexture2D(
		unit,
		pixels = null,
		filter,
		repeat = "no-repeat",
		w = pixels.width,
		h = pixels.height,
		premultipliedAlpha = true,
		mipmap = true,
	) {
		const gl = this.gl;
		const isPOT = isPowerOfTwo(w) && isPowerOfTwo(h);
		const rs =
			repeat.search(/^repeat(-x)?$/) === 0 &&
			(isPOT || this.renderer.WebGLVersion > 1)
				? gl.REPEAT
				: gl.CLAMP_TO_EDGE;
		const rt =
			repeat.search(/^repeat(-y)?$/) === 0 &&
			(isPOT || this.renderer.WebGLVersion > 1)
				? gl.REPEAT
				: gl.CLAMP_TO_EDGE;

		const texture = gl.createTexture();

		this.bindTexture2D(texture, unit);

		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, rs);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, rt);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);

		gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultipliedAlpha);

		if (pixels === null || typeof pixels.byteLength !== "undefined") {
			// if pixels is undefined, or if it's Uint8Array/Float32Array TypedArray
			gl.texImage2D(
				gl.TEXTURE_2D,
				0,
				gl.RGBA,
				w,
				h,
				0,
				gl.RGBA,
				gl.UNSIGNED_BYTE,
				pixels,
				0,
			);
		} else if (
			typeof globalThis.OffscreenCanvas !== "undefined" &&
			pixels instanceof globalThis.OffscreenCanvas
		) {
			// convert to ImageBitmap first (else Safari 16.4 and higher will throw an TypeError exception)
			const imageBitmap = pixels.transferToImageBitmap();
			gl.texImage2D(
				gl.TEXTURE_2D,
				0,
				gl.RGBA,
				gl.RGBA,
				gl.UNSIGNED_BYTE,
				imageBitmap,
			);
			imageBitmap.close();
		} else {
			gl.texImage2D(
				gl.TEXTURE_2D,
				0,
				gl.RGBA,
				gl.RGBA,
				gl.UNSIGNED_BYTE,
				pixels,
			);
		}

		// generate the sprite mimap (used when scaling) if a PowerOfTwo texture
		if (isPOT && mipmap === true) {
			gl.generateMipmap(gl.TEXTURE_2D);
		}

		return texture;
	}
Create a WebGL texture from an image
@param {number} unit - Destination texture unit
@param {Image|HTMLCanvasElement|ImageData|Uint8Array[]|Float32Array[]} [pixels=null] - Source image
@param {number} filter - gl.LINEAR or gl.NEAREST
@param {string} [repeat="no-repeat"] - Image repeat behavior (see {@link ImageLayer#repeat})
@param {number} [w=pixels.width] - Source image width (Only use with UInt8Array[] or Float32Array[] source image)
@param {number} [h=pixels.height] - Source image height (Only use with UInt8Array[] or Float32Array[] source image)
@param {boolean} [premultipliedAlpha=true] - Multiplies the alpha channel into the other color channels
@param {boolean} [mipmap=true] - Whether mipmap levels should be generated for this texture
@returns {WebGLTexture} a WebGL texture