我们将直接用JavaScript创建数据;并且用对应的数据点来直接创建对应的纹理;
    用JavaScript为纹理创建数据是比较直接的,默认情况下WebGL只支持少量数据类型的纹理

    格式 数据类型 通道数 单像素字节数
    RGBA UNSIGNED_BYTE 4 4
    RGB UNSIGNED_BYTE 3 3
    RGBA UNSIGNED_SHORT_4_4_4_4 4 2
    RGBA UNSIGNED_SHORT_5_5_5_1 4 2
    RGB UNSIGNED_SHORT_5_6_5 3 2
    LUMINANCE_ALPHA UNSIGNED_BYTE 2 2
    LUMINANCE UNSIGNED_BYTE 1 1
    ALPHA UNSIGNED_BYTE 1 1

    让我们创建一个 3×2 像素的 LUMINANCE (亮度/黑白)纹理,由于它是 LUMINANCE 纹理,所以每个像素只有一个值,在 R, G, B通道是相同的。

    1. // 填充立方体纹理坐标的缓冲
    2. function setTexcoords(gl) {
    3. gl.bufferData(
    4. gl.ARRAY_BUFFER,
    5. new Float32Array([
    6. // 正面
    7. 0, 0,
    8. 0, 1,
    9. 1, 0,
    10. 1, 0,
    11. 0, 1,
    12. 1, 1,
    13. ...
    14. // 创建一个纹理
    15. var texture = gl.createTexture();
    16. gl.bindTexture(gl.TEXTURE_2D, texture);
    17. // 用 1x1 的蓝色像素填充纹理
    18. // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
    19. // new Uint8Array([0, 0, 255, 255]));
    20. // 用 3x2 的像素填充纹理
    21. const level = 0;
    22. const internalFormat = gl.LUMINANCE;
    23. const width = 3;
    24. const height = 2;
    25. const border = 0;
    26. const format = gl.LUMINANCE;
    27. const type = gl.UNSIGNED_BYTE;
    28. const data = new Uint8Array([
    29. 128, 64, 128,
    30. 0, 192, 0,
    31. ]);
    32. gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, width, height, border,
    33. format, type, data);
    34. // 设置筛选器,我们不需要使用贴图所以就不用筛选器了
    35. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    36. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    37. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    38. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    39. // 异步加载图像 【不需要】
    40. ...

    我们会得到对应的结果 纹理贴图数据模式
    image.png
    并没有对应的黑白的纹理都贴图的出现;控制台的错误信息打印;

    1. WebGL: INVALID_OPERATION: texImage2D: ArrayBufferView not big enough for request

    结果是WebGL中有一种首次创建OpenGL后的模糊设定, 计算机有时在数据为某些特定大小时速度会快一些, 例如一次拷贝2,4 或 8 个字节比一次拷贝 1 个字节要快, WebGL默认使用 4 字节长度,所以它期望每一行数据是多个 4 字节数据(最后一行除外)
    我们之前的数据每行只有 3 个字节,总共为 6 字节, 但是 WebGL 试图在第一行获取 4 个字节,第二行获取 3 个字节, 总共 7 个字节,所以会出现这样的报错。
    我们可以告诉WebGL一次处理 1 个字节

    1. const alignment = 1;
    2. gl.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);

    有效参数为 1,2,4 和 8.
    我觉得你可能无法计算出对齐数据和非对齐数据的速度区别, 所以希望默认值是 1 而不是 4, 这样这个问题就不会困扰新手, 但是为了适配OpenGL,所以要保留相同的默认设置,这样移植应用就不用改变行数, 然后可以为新的应用在需要的地方设置属性为 1。
    有了这个设置后就能正常运行了 新的纹理连接
    image.png
    有时纹理上的像素叫 texels,像素是图片元素的简写,Texel 是纹理元素的简写。
    我知道我可能会收到一些图形学大师的牢骚,但是我所说的 “texel” 是一种行话。 我通常在使用纹理的元素时不假思索的使用了“像素”这个词。