CSS3中固体元素与透明元素的性能



渲染纯色和透明色时的性能差异是什么。当loadingscrolling都是网页时。假设它们都由GPU处理,差异会变得很小,但我仍然想知道。采取了哪些额外步骤来生成透明元素,透明元素对FPS的影响是否比常规元素更大?

从技术上讲,这不仅限于颜色,还包括solid elementstransparent elements

JSFiddle Demo选择的颜色为SO绿色:)

CSS

.example1{
background-color:#75845c;
color: #e1e818;
}
.example2{
background-color:#75845c;
color: rgba(255, 255, 0, 0.6);
}

HTML

<div class="example1">
I am a solid color
</div>
<br />
<div class="example2">
I am a transperant color
</div>

简短回答:取决于浏览器。现在,对于漫长的答案。。。

[作为背景,我是从一个一直将像素作为生活中一个令人尴尬的大问题进行混合、lerping和合成的人的角度来研究这一问题的,从早期DOS游戏中的视频内存到现在的低级UI套件和绘图库,再到光线跟踪器和GPU着色器。它的核心始终是图像处理。我的工作通常与网络非常脱节级别较低,但这似乎是一个更具概念性的问题。我从未实现过网络浏览器,但已经实现了许多通用网络浏览器所需的光栅化技术,并针对带有脚本和节点编程的插件架构,面临着浏览器实现者在面对所有可能性时必须解决的许多类似的设计和优化挑战和妥协。]

阿尔法混合很便宜

在最高概念级别,尤其是在这种情况下,alpha混合像素的成本非常低,因此您可能永远不应该担心这种成本(除非您每帧渲染数百万个粒子或类似的东西)。在覆盖内存中的目标像素之前,将像素alpha混合在一起只需要一些基本运算。

即使是基本的CPU实现也可以每秒突破数亿像素(其中涉及的每个像素都是阿尔法混合的),在图像处理和光栅化的背景下,快速阿尔法混合是一个经过充分研究的问题,其中从快速8位lerps和缩放到利用SIMD等最近的硬件趋势。当GPU介入时,算术运算会以极快的速度进行(而且速度已经快得惊人了)。

但Alpha混合可能需要不便宜的东西

但是,这只是一个孤立的案例,研究混合透明元素的成本。围绕这一点,有各种复杂的因素可能会使渲染透明元素成为热点。

首先,GPU扫描线光栅化的设计目的是做比简单地将图像混合在一起更复杂的事情。在每个片段的基础上,涉及顶点变换以及着色和照明。即使你不使用这些东西,而是使用扫描线光栅化将这些图像显示为纹理,硬件/光栅化管道也是为了做这些事情而设计的,而且无论如何都要支付大部分成本。因此,通过扫描线光栅化的alpha混合可能开始成为瓶颈,但这并不是因为alpha混合算法。这是因为阿尔法混合片段总是要支付全部渲染成本,并且不能被涉及z缓冲区的深度测试排除在外。

然而,在使用GPGPU而不是扫描线光栅化的情况下(例如:使用GPU对最初存储在系统内存中的图像进行一系列运算,而不涉及完整的GPU扫描线管道),这就不是问题了。然而,这已经成为一种猜测,如果许多浏览器选择使用GPU,他们可能会选择普通的GPU路线,而不是GPGPU,因为这是一种更广泛支持、更成熟的路径。

另一个出现的问题,但更多的是在3D环境中,是许多形式的阿尔法混合相对于它们提供的结果是特定顺序的。碎片呈现的顺序很重要。在3D环境中,如果我们有一百万个半透明多边形要渲染,现在我们必须按照深度排序的顺序渲染它们的片段,以确保一致、正确的结果。这种排序开销非常昂贵,即使使用像Dual Depth Peeling这样的非常优化的近似方法也是如此。

然而,在2D环境中,这种深度排序问题往往变得毫无意义。2D上下文通常可以通过开发人员请求绘制事物的顺序来产生所需的结果。2D元素通常也具有恒定的深度(其深度不会因片段而异),因此它不会与基于每个像素/片段渲染的其他元素的深度相交/重叠。

不太理想的世界

可能与这个普遍问题最相关的是,事情很少得到优化,甚至接近理想的概念水平。

对阿尔法混合的需求可能会在不太理想的实现中产生辅助需求。例如,在某些实现中,alpha混合的内容可能开始变得非常相关。

例如,如果在渲染的透明前景元素后面有一个静态背景,那么这种不太理想的实现可能需要比理想情况下更频繁地处理背景(以及更多地处理背景)。浏览器必须处理涉及客户端脚本和小程序的动态世界,其中图形可能会根据无限可能的条件发生变化。

引入透明元素可能会破坏他们关于静态与动态的假设,并可能需要对昂贵的背景元素进行额外的再处理(例如:每次滚动时)。至少我在这里看到了一些与性能相关的问题,这些问题似乎表明可能是这样的,引入一个非常简单的透明元素(绘制起来应该非常便宜)会对性能产生巨大的负面影响,很可能是由于对静态元素的重复、冗余处理,浏览器无法再对此做出坚定的假设。当然,这都是猜测。

在更简单的层面上,alpha混合多个层确实需要检查每个层的内存。如果你,比如说,在一个巨大的图像上进行阿尔法混合,即使是一个微小的透明元素,即使阿尔法混合过程只需要合成少量像素,它仍然必须将这个海量图像的部分内存(在这种情况下,它在扫描线之间没有很好的参考位置)从慢得多的内存区域一直移动到缓存层次结构中,并进入寄存器*。根据这种合成过程发生的频率以及浏览器缓冲以减少这种频率的程度,它可能会成为一个严重的瓶颈。

*为了简单起见,我将避免在没有缓存的情况下进行流加载/存储——不管怎样,通常都存在相同的内存趋势

如果你遇到过这样的情况,解决这个问题的一个非常普遍的方法是让复合材料中涉及的层更便宜。例如,史诗般的背景图像可以分解为缝合在一起的较小图像,只有特定的较小图像需要合成。这提高了缓存的局部性,即使通常会在逐个像素的基础上应用相同的工作量来将这两个元素组合在一起*。

*计算中常见的误解是,做同样数量的工作,甚至执行相同的指令,都会产生相同的成本。有一些动态的硬件和操作系统因素使许多指令具有可变的成本,最值得注意的是,硬件将内存从较大但较慢的内存类型移动到较快、较小的内存类型,并在软件开发人员的背后

滚动和加载

渲染纯色和透明颜色。当loadingscrolling都是一个网页时。

同样,alpha混合非常便宜。然而,透明元素可能会破坏一些潜在的优化,而不是理想实现的浏览器可以对不透明元素进行优化。这比加载更有可能显示在滚动中(因为加载只需要发生一次)。

结论

简而言之,在这个问题的背景下,阿尔法混合过程本身是非常便宜的。要想让它成为一个令人担忧的问题,通常需要将数百万像素混合,甚至开始显示为一个可能需要担心的事情。

然而,为了将像素混合在一起而涉及的辅助过程,尤其是在那些不太理想的现实实现中,可能开始变得昂贵。不幸的是,在不了解特定浏览器的实现的情况下,不可能对这些进行精确的细分,但以上几点应该涵盖了很多广泛的可能性。

最新更新