15. Html5的局:WebGL的纹理格式的转换

简介: #紧接上文 WebKit为了统一WebGL的书写规范,对OpenGL的标准进行四书五入,推出了平台无关的API标准,同时为了简化底层硬件的差异,又新增了一些纹理格式的支持,由内核提供高性能的图像转换,扩展了OpenGL得标准。 那么,WebGL在底层做了些什么呢?复杂吗?可以自己实现吗? #纹理格式转换计算量大 这是WebGL为前端同学提供的福利,上层开发可以更加专注业务书写,充分挖掘

紧接上文

WebKit为了统一WebGL的书写规范,对OpenGL的标准进行四书五入,推出了平台无关的API标准,同时为了简化底层硬件的差异,又新增了一些纹理格式的支持,由内核提供高性能的图像转换,扩展了OpenGL得标准。
那么,WebGL在底层做了些什么呢?复杂吗?可以自己实现吗?

纹理格式转换计算量大

这是WebGL为前端同学提供的福利,上层开发可以更加专注业务书写,充分挖掘C/C++语言的能力。

UNPACK_FLIP_Y_WEBGL

重新生成一张内存图片,将纹理像素上下颠倒的复制到新图片。
screenshot
图片在内存的大小,与图片格式没有直接关系,主要取决于尺寸。以1024x1024的png为例,有R、G、B、A四个通道,每个像素占4字节,总内存:1024 x 1024 x 4 = 4M空间。
新图片上传到GPU后自动释放,不会影响到老图片的生命周期。
UNPACK_FLIP_Y_WEBGL的取值:true/false

UNPACK_PREMULTIPLY_ALPHA_WEBGL

对图片纹理的每个像素的R、G、B通道,乘以A的值后,并替换原先的值。
我们以一张白色图片,0.5的透明度为例。
每个像素的存储格式为:
screenshot
R、G、B、A分别为unsigned char类型,俗称uint8_t,预算过程中自动进行浮点数转换,舍去末尾的精度:
R = R * A / 255.0f;
G = G * A / 255.0f;
B = B * A / 255.0f;
A = A;

每个像素都要算一次,1024 x 1024 大小的图片,计算量为1024 x 1024 x 10 约10M次。对于C/C++来说也比较耗时,如果放到JS中处理,后果不堪设想。
这也许是WebGL设计的初衷。

UNPACK_ALIGNMENT

上面我们提到的图片格式为RGBA,转换起来虽然计算量打,但算法比较直观。换成其他格式就不是这么直观了,比如:RGB、RGB565等等,不仅需要按byte进行转换,每个uint8_t都需要掰开使用。
以RGB为例,每个像素占用3个字节,考虑到GPU只能接受2的整数倍的尺寸。所以CPU需要为前端同学做格式转换。
这里我们定义Stride,并计算相应的像素对齐后的尺寸。

stride = (imageWidth * bytesPerPixel + unpackAlignment - 1) / unpackAlignment;

如果unpackAlignment = 1,那么新的图片尺寸是不变的,否则,新的图片尺寸就需要CPU处理做像素对齐,我们这里讨论特殊情况,就是 stride != width的时候。

从RGB到RGB

FireFox的做法比较简单,申请新的图片空间:

GLvoid* pixels = malloc(stride * height);

将每个像素从GL_RGB转换成GL_RGBA,保存中间pixel变量,再赋值到新的图片中:

······
GLubyte texel[4];
convert_rgb_rgba(image[i][j], texel];
conver_rgba_rgb(texel, pixels[i][j]);
······

问题来了,既然gl.texImage2D函数的internalFormat与format的格式必须是保持一致的,为什么不把函数直接写为:

memcpy(image, pixels, width * height);

理由就是为了做兼容,对比WebKit代码,我们可以找到FireFox这样做的原因。

WebKit做法复杂,但耐人寻味

申请新的图片内存空间:

GLuint bytesPerPiexl = formatSize(internalFormat, type);
GLvoid* pixels = malloc(width*height * bytesPerPiexl);

我们会发现,WebKit并不会按照stride来申请空间,也不会参考unpackAlignment,它使用了internalFormat和type来确定OpenGL中的纹理格式和空间结构。
这两个参数可以确定每个像素的bytes,参考14. Html5的局:WebGL的纹理格式提到的常见纹理格式。

到了转换这一步,WebKit采用函数模板为路由的方式转发到对应的转换API:

template<srcForamt, dstFormat, SrcType, DstType>
void convert(····) {
      switch(srcForamt) {
            case GL_RGB: {
                   switch(dstFormat) {
                         case GL_RGB: {
                                unpack_RGB_pack_RGB(image, pixels);
                                break;
                         }
                         case GL_RGBA: {
                                 unpack_RGB_pack_RGBA(image, pixiels);
                                 break;
                         }
                         ....
                   }
                   break;
            }
            .......
     }
}

这里WebKit做了大量的路由功能,提高了转换效率,但是代码复杂度很高。比如:
我们已知的常用纹理的Format为:

GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA

WebKit还支持了很多其他的Format:

GL_RGB16F, GL_RGBA16F...
GL_RGB32F, GL_RGBA32F...

下一篇

这篇内容太多了,我们放到下一篇继续讲,纹理格式转换。

目录
相关文章
|
9月前
|
Java 网络安全 数据安全/隐私保护
javaMai+Springl实现给QQ邮箱发邮件(带附件,html格式)
javaMai+Springl实现给QQ邮箱发邮件(带附件,html格式)
|
4月前
|
前端开发
html 格式
【10月更文挑战第14天】html 格式
71 4
|
4月前
|
编解码 前端开发 UED
HTML多媒体格式支持与优化
在HTML中,多媒体格式的支持与优化至关重要。使用`&lt;audio&gt;`、`&lt;video&gt;`和`&lt;img&gt;`标签可分别嵌入音频、视频和图像。支持的格式包括MP3、OGG、JPEG等。为优化体验,应压缩文件、采用响应式设计、使用懒加载,并考虑转码及CDN托管。此外,添加字幕和描述文件可提高辅助功能。遵循这些最佳实践,能显著提升多媒体内容的加载速度与用户满意度。
|
3月前
|
移动开发 编解码 UED
除了 `<audio>` 和 `<video>` 标签,HTML5 还支持哪些多媒体格式?
【10月更文挑战第19天】HTML5对多种多媒体格式的支持,为网页开发者提供了丰富的选择,能够更好地满足不同类型多媒体内容在网页中的展示和交互需求,提升了网页的用户体验和多媒体应用的多样性。
|
4月前
|
JSON 数据格式
LangChain-20 Document Loader 文件加载 加载MD DOCX EXCEL PPT PDF HTML JSON 等多种文件格式 后续可通过FAISS向量化 增强检索
LangChain-20 Document Loader 文件加载 加载MD DOCX EXCEL PPT PDF HTML JSON 等多种文件格式 后续可通过FAISS向量化 增强检索
236 2
|
4月前
|
机器学习/深度学习 JSON JavaScript
LangChain-21 Text Splitters 内容切分器 支持多种格式 HTML JSON md Code(JS/Py/TS/etc) 进行切分并输出 方便将数据进行结构化后检索
LangChain-21 Text Splitters 内容切分器 支持多种格式 HTML JSON md Code(JS/Py/TS/etc) 进行切分并输出 方便将数据进行结构化后检索
76 0
|
5月前
|
SQL 安全 数据库
用html+javascript打造公文一键排版系统2:显示源码/显示预览、清除格式
用html+javascript打造公文一键排版系统2:显示源码/显示预览、清除格式
|
6月前
|
移动开发 HTML5
HTML5文档基本格式
【8月更文挑战第28天】HTML5文档基本格式。
55 4
|
7月前
|
自然语言处理 开发者 Python
Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的 HTML 内容。Markdown 的语法简洁明了、学习容易,而且功能比纯文本更强。
Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的 HTML 内容。Markdown 的语法简洁明了、学习容易,而且功能比纯文本更强。
|
7月前
|
Unix Linux Shell
Sphinx是一个Python文档生成工具,它可以解析reStructuredText或Markdown格式的源代码注释,并生成多种输出格式,如HTML、LaTeX、PDF、ePub等。
Sphinx是一个Python文档生成工具,它可以解析reStructuredText或Markdown格式的源代码注释,并生成多种输出格式,如HTML、LaTeX、PDF、ePub等。