本系列根据国外一个图形小哥的讲解为本,整合互联网的一些资料,结合自己的一些理解。
什么是缓冲区?
缓冲区是保存某些数据的临时存储空间。
为什么我们需要缓冲区?原因很简单,当数据量很大时,因为计算机无法同时处理整个数据,因此在处理当前数据集时需要额外的空间来存储其余数据。
在计算机图形学中,缓冲区有多种定义方式。
- 分辨率:宽度(n) x 高度(m)
- 深度(或精度):k
- 位数/像素
例如,如果我们想要每个像素使用 RGB 通道,则一个通道需要 8 位,总共 24 位(3 x 8 位)。
OpenGL 中的缓冲区
在openGL中,有颜色缓冲区、深度缓冲区、模板缓冲区等。
颜色缓冲区用于显示:
- 前后
- 辅助(存储处理中的图像并对其应用一些操作)
- 立体显影(用于头戴式显示器。它们为眼睛的每一侧都有两个独立的显示。)
深度缓冲区用于遮挡。它只保存 z 值,即灰度表示。
模板缓冲区类似于使用蒙版进行绘画。你把一个有孔的模具放在纸上,然后你在纸上喷漆,结果将是一张与孔所在位置相对应的黑色纸张。模板缓冲区为绘制区域存储 1 位值,为其他区域存储 0 位值。
写入缓冲区
从概念上讲,我们可以将所有内存视为一个大型的二维像素数组。我们读取和写入矩形像素块,帧缓冲区是该内存的一部分。
位写入模式
source源和destination目标以按位方式组合,有 16 种可能。
缓冲区选择
OpenGL 可以从任何缓冲区(前、后、深度)读取。但要注意,帧缓冲区中像素的格式与处理器内存中的像素格式不同,而且这两种类型的内存驻留在不同的地方————这会导致打包和拆包、读取速度慢的问题。
我们使用“glReadPixels”函数读取缓冲区。
例如,读取图像缓冲区将是:
缓冲区写入的应用场景
混合与合成
将绿幕替换成自定义背景。
不透明度和透明度(alpha 混合)
不透明的表面不允许光线通过,透明表面允许所有光线通过。那么半透明呢?它将会通过“一些”光线。
我们可以将半透明度表示为“1-不透明度”或“1-alpha”。
写入模型
我们使用 RGBA 颜色的分量来存储不透明度。在渲染过程中,我们可以扩展我们的写入模型以使用 RGBA 值。
混合方程
让我们为每个 RGBA 分量定义源和目标的混合因子。
- source = [s_r, s_g, s_b, s_alpha]
- destination = [d_r, d_g, d_b, d_alpha]
以下是源颜色和目标颜色:
- source factor = [b_r, b_g, b_b, b_alpha]
- destination factor = [c_r, c_g, c_b, c_alpha]
混合为
c = source*source_factor target*destinaion_factor ,其中 c
将是新的目标因子。
渲染顺序依赖
当我们渲染一个对象时,以正确的顺序渲染非常重要。
因为多边形是按照沿着管道传递的顺序渲染的,所以我们需要首先从相机渲染进一步的多边形以获得正确的遮挡效果(稍后更接近的面)。
让我们考虑一下一个物体同时具有不透明和半透明表面的情况。
- 不透明的面阻挡其后面的所有多边形,它会影响深度缓冲区。
- 半透明面不应影响深度缓冲区。
为了正确渲染这个对象,我们需要首先对多边形进行排序以消除顺序依赖性。
组合图像
我们有时候会在视频中看到淡入淡出(crossfade)的效果,以使场景顺利过渡到下一个场景。我们也可以在这里使用 alpha 混合! Crossfade的过程相当于线性插值。
当t为0.6时,
然而,在许多情况下,加法不足以混合图像,在电影制作中,他们需要额外的技术:
- 前景和背景分开拍摄。
- 当他们拍摄前景时,他们会用 Choramkey 背景来拍摄。
我们如何以数字方式做到这一点?
二值图像掩模
与模板缓冲区一样,使用掩模,我们可以将前景与背景分开。
但是我们可以在这里能看到一些锯齿。
解决此问题的一种方法是根据前景和背景之间的边界插入颜色。
对于边界上的每个像素,我们可以确定前景与背景的面积比。
另一种方法称为“alpha合成”,它存储覆盖的像素部分(称为 alpha)。
另一个混合的例子
雾效果
我们也可以使用混合功能来模拟雾效果!
- C`:新的目标因子
- f : 雾因子
- Cs :源颜色
- (1-f):目标因子
- Cf : 雾颜色
混合等式:C` = f * Cs + (1-f) Cf