我们将直接用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通道是相同的。
// 填充立方体纹理坐标的缓冲function setTexcoords(gl) {gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([// 正面0, 0,0, 1,1, 0,1, 0,0, 1,1, 1,...// 创建一个纹理var texture = gl.createTexture();gl.bindTexture(gl.TEXTURE_2D, texture);// 用 1x1 的蓝色像素填充纹理// gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,// new Uint8Array([0, 0, 255, 255]));// 用 3x2 的像素填充纹理const level = 0;const internalFormat = gl.LUMINANCE;const width = 3;const height = 2;const border = 0;const format = gl.LUMINANCE;const type = gl.UNSIGNED_BYTE;const data = new Uint8Array([128, 64, 128,0, 192, 0,]);gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, width, height, border,format, type, data);// 设置筛选器,我们不需要使用贴图所以就不用筛选器了gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);// 异步加载图像 【不需要】...
我们会得到对应的结果 纹理贴图数据模式
并没有对应的黑白的纹理都贴图的出现;控制台的错误信息打印;
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 个字节
const alignment = 1;gl.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
有效参数为 1,2,4 和 8.
我觉得你可能无法计算出对齐数据和非对齐数据的速度区别, 所以希望默认值是 1 而不是 4, 这样这个问题就不会困扰新手, 但是为了适配OpenGL,所以要保留相同的默认设置,这样移植应用就不用改变行数, 然后可以为新的应用在需要的地方设置属性为 1。
有了这个设置后就能正常运行了 新的纹理连接
有时纹理上的像素叫 texels,像素是图片元素的简写,Texel 是纹理元素的简写。
我知道我可能会收到一些图形学大师的牢骚,但是我所说的 “texel” 是一种行话。 我通常在使用纹理的元素时不假思索的使用了“像素”这个词。
