WebGL:如何在javascript和着色器之间进行交互,以及如何使用多个着色器

时间:2016-04-06 13:30:30

标签: webgl

我在WebGL上看过演示

  1. 颜色矩形表面
  2. 将纹理附加到矩形
  3. 绘制线框
  4. 有半透明纹理
  5. 我不明白的是如何将这些效果组合到一个程序中,以及如何与对象进行交互以改变它们的外观。

    假设我想创建一个包含上述所有内容的场景,并且能够更改任何矩形的颜色,或者更改纹理。

    我正在尝试理解代码的组织。以下是一些简短的相关问题:

    1. 我可以创建一个带有相应颜色缓冲区的顶点缓冲区。我可以有一些带纹理的矩形,有些没有吗?
    2. 如果没有,我必须为所有具有颜色的对象创建一个顶点缓冲区,并为纹理创建另一个顶点缓冲区。我可以为矢量中的每个矩形附加不同的纹理吗?
    3. 对于某些带有颜色的矩形和其他带有纹理的矩形,它需要两个不同的着色器程序。我看到的所有演示只有一个,但显然更复杂的程序有多个。如何在着色器之间切换?

    4. 如何开启和关闭线框?它可以与纹理结合吗?换句话说,是否可以编写一个可以使用标志打开和关闭线框等功能的着色器,还是可以对两个不同的着色器进行两次不同的调用?

    5. 我见过的所有演示都使用带三角形的索引缓冲区。 WebGL中是否不再支持四边形?显然有些东西需要三角形,但如果我有一堆矩形,那么不必创建三角形索引就好了。

    6. 对于上述三种情况,如果我想更改点,颜色,纹理或透明度,我理解glSubBuffer将允许用新数据替换当前缓冲区中的数据。

      让一个对象维护这些类型的对象并更新颜色和纹理是否合理,还是这不是一个好的设计?

1 个答案:

答案 0 :(得分:0)

您提出的问题不仅仅是关于WebGL,还涉及OpenGL和3D。

最常用的交互方式是在开始时设置属性,在开始和运行时设置制服。

一般,回答您的所有问题是"使用引擎"。

想象一下,就像你有javascript,基于CPU的lang,然后你有WebGL,这就像JS的东西库,允许与GPU的低级通信(记住,低级别),然后你有着色器,这是GPU您必须提供的程序,但它仅适用于特定数据。

做任何更简单的事情"简单"需要一个工具,它允许您直接跳过使用WebGL(并且通常也直接编写着色器)。我们称之为引擎的工具。引擎通常将一些能力绑定在一起并跳过其他能力(例如2D和3D引擎之间的差异)。引擎函数以特定顺序调用某些WebGL预设函数,因此您不得再次触摸WebGL API 。引擎还提供非常复杂的逻辑,仅基于几个简单的引擎api调用来构建单对或几对着色器。原因是在整个程序中,交换shader program成本很高。

您的问题

  

我可以创建一个带有相应颜色缓冲区的顶点缓冲区。我可以吗   有一些纹理的矩形和一些没有?如果没有,我必须   为具有颜色的所有对象创建一个顶点缓冲区,为另一个创建一个   纹理。我可以为a中的每个矩形附加不同的纹理   矢量?

让我们有一个缓冲区,我们调用顶点缓冲区。我们将各种数据放在顶点缓冲区中。数据不会像个人一样,而是作为集合。集合中的每个唯一数据,我们称之为属性。该属性对顶点着色器或片段着色器代码决定的顶点具有任何意义。

如果我们为三角形填充了数据缓冲区,则可以设置例如属性,该属性说明特定顶点是否应该纹理三角形并在着色器中执行纹理逻辑。无论如何,我认为每个顶点的属性数据大小必须相等(因此纹理三角形的大小与非纹理相同)。

  

对于某些带有颜色的矩形和带有纹理的其他矩形的情况,   它需要两个不同的着色器程序。我看到的所有演示都有   只有一个,但显然更复杂的程序有多个。怎么做   你在着色器之间切换?

不是这样,即使非常复杂的程序也可能只有一对着色器(一个WebGL程序)。但是仍然可以在运行中更改程序:

https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 WebGL API函数useProgram

  

如何开启和关闭线框?它可以与纹理结合吗?在   换句话说,是否可以编写可以转换功能的着色器   像线框打开和关闭标志,或它需要两个不同   调用两个不同的着色器?

WebGL API允许以线框模式绘制。这是shader program独立选项。您可以在每次绘制调用时切换它。无论如何,也可以编写将作为线框绘制并使用标志控制它的着色器(标志可能是两者,统一或基于属性)。

  

我见过的所有演示都使用带三角形的索引缓冲区。是四边形   WebGL不再支持?对某些事情显然是三角形   将需要,但如果我有一堆矩形,那将是很好的   不必创建三角形索引。

WebGL仅支持四边形和三角形。我想这是因为没有四边形,着色器更简单。

  

对于上述三种情况,如果我想改变点数,   颜色,纹理或透明度,我是正确的   了解glSubBuffer将允许替换当前的数据   带有新数据的缓冲区。

我想说很少在运行时更新缓冲区数据。它减慢了很多程序。 glSubBuffer不在WebGL中(不同的名称???)。无论如何不要使用它;)

  

让一个对象维护这些类型是否合理   对象和更新颜色和纹理,或者这不是一个好的设计?

是的,它被称为Scene graph并且被广泛使用,并且可能还与其他技术结合使用,例如显示列表