《The book of shaders》学习总结 (15)图像处理

196次阅读
没有评论

图像处理

贴图

《The

图形卡(GPU)具有特殊的图像存储类型。通常在CPU上,图像存储为字节数组,而GPU存储的图像sampler2D更像是浮点向量表(或矩阵)。更有趣的是,此向量表的值是连续的。这意味着像素之间的值被内插在较低的水平上。

为了使用此功能,我们首先需要图像从CPU上传到GPU,然后将id纹理传递到右侧uniform。所有这些都在着色器之外发生。

加载纹理并将其链接到有效对象后,uniform sampler2D您可以vec2使用texture2D()函数返回特定vec4变量格式的颜色,该函数在特定坐标(变量格式)上要求特定颜色值.

vec4 texture2D(sampler2D texture, vec2 coordinates)  

检查以下代码,将Hokusai's Wave(1830)加载为以下代码,uniform sampler2D u_tex0并在广告牌内调用其每个像素:

如果您注意,将注意到纹理的坐标已标准化!有什么惊喜吗?纹理坐标与我们看到的其他事物一致,并且它们的坐标在0.0到1.0之间,与我们一直在使用的规范化空间坐标完全匹配。

既然您已经了解了如何正确加载纹理,那么现在可以尝试通过尝试尝试发现我们可以使用的纹理:

  • 将先前的纹理缩放一半。
  • 将先前的纹理旋转90度。
  • 将鼠标位置钩到坐标上以将其移动。

为什么您应该对纹理感到兴奋?首先,让我们忘掉可悲的255个值;将图像转换为时,uniform sampler2D您将拥有0.0到1.0之间的所有值(取决于您将设置precision为)。这就是为什么着色器可以产生非常漂亮的后处理效果的原因。

其次,这vec2()意味着您甚至可以在像素之间获得值。正如我们之前所说,纹理是连续的。这意味着,如果正确设置纹理,则可以要求图像周围所有值,并且各个像素之间的值将平滑变化而不会发生跳变!

最后,您可以将图像设置为在边缘重复,因此,如果给定的值大于或小于规范化的0.0和1.0,则这些值将重新开始。

所有这些功能使您的图像更像是无限的氨纶织物。您可以拉伸和缩小纹理,而无需注意它们最初组成的字节网格或其结尾。为了体验这一点,请看下面的代码,其中我们使用已经完成的噪波函数使纹理变形。

纹理分辨率

上面的示例可以很好地处理平方图像,两边都相等并且匹配我们的平方广告牌。但是对于非平方图像,事情可能会有些棘手,不幸的是,数百年来的绘画艺术和摄影发现非平方比例的图像对眼睛而言更为令人愉悦。

《The

我们如何解决这个问题?好吧,我们需要知道图像的原始比例,才能知道如何正确拉伸纹理以具有原始的宽高比。为此,将纹理的宽度和高度作为传递给着色器uniform,在我们的示例框架中,该纹理的宽度和高度作为传递,其uniform vec2名称与纹理的名称相同,后跟proposition Resolution。在着色器上获得此信息后,我们可以通过将纹理分辨率的width进行除以得到宽高比height。最后,通过将该比例乘以坐标,y我们将缩小该轴以匹配原始比例。

取消注释以下代码的第21行,即可看到实际效果。

  • 我们需要做什么来使该图像居中?

数码装饰

《The

您可能会认为这不必要地复杂...而且您可能是对的。同样,这种使用图像的方式也为不同的黑客和创意技巧留出了足够的空间。试想一下,您是室内装潢商,并且通过在结构上拉伸和折叠织物可以创建更好的新图案和技术。

《The

如此高超的工艺水平可以追溯到有史以来的第一批光学实验。例如,在游戏中,精灵动画非常普遍,因此不可避免地会让人联想到现象学,zootrope和praxinoscope。

这看似简单,但修改纹理坐标的可能性是巨大的。例如:

现在轮到您了:

  • 您能利用我们学到的知识制作万花筒吗?

  • 在Oculus或Google硬纸板之前,立体摄影是一件大事。您可以编写一个简单的着色器来重新使用这些漂亮的图像吗?

  • 您还可以使用纹理重新创建其他哪些光学玩具?

在下一章中,我们将学习如何使用着色器进行某些图像处理。您会注意到,着色器的复杂性最终是有道理的,因为它在很大程度上是设计用于执行此类过程的。我们将开始做一些图像操作!