【问题标题】:Drawing multiple elements in Webgl在 Webgl 中绘制多个元素
【发布时间】:2021-12-21 23:38:43
【问题描述】:

我在 youtube 上看过很多关于此的视频,并且我访问过这些网站:

这些来源中的大多数都是相似的,但我无法理解它的要点。

我使用 webgl 已经 4 个月了,我制作了三角形、矩形、球体、立方体,还编写了一些很酷的片段着色器。

但是显示多个对象对我来说是一个很大的障碍。

我不知道从哪里开始,也不知道应该如何更改现有代码。

我应该创建更多缓冲区或创建更多顶点数组或创建更多程序吗?

我该怎么办?

我目前正在尝试为一个项目制作多个球体。这些球体将充当围绕原子核运行的电子。基本上我正在尝试制作原子的 3d 模型。

我知道像 three.js 和 babylon.js 这样的库在这里可以很好用,但我真的很想在没有任何外部库的情况下这样做。

【问题讨论】:

    标签: javascript 3d webgl vertices webgl2


    【解决方案1】:

    有很多方法可以解决这个问题。

    缓冲区定义几何体,着色器程序定义几何体如何进入屏幕。如何将它们组合在一起以获得您想要的东西取决于您。

    简短的版本是,当您调用gl.draw*() 函数时,绑定的着色器程序将使用您告诉它使用的缓冲区和制服执行。您可以根据需要使用不同的缓冲区、着色器或着色器输入多次执行此操作,以完成该帧。


    假设你有一个立方体,一个球体。它们具有相同的颜色和样式(意味着它们使用相同的着色器)。假设着色器将顶点位置设为attribute vec3 aVert,将颜色设为uniform vec4 uColor

    您可能会为每个对象创建一个缓冲区,其中包含该形状的顶点数据。然后渲染:

    1. 绑定着色器
    2. 将着色器上的 uColor 统一设置为 [1,0,0,1](红色)
    3. 立方体:
      1. 绑定多维数据集缓冲区
      2. 将缓冲区数据设置为aVert属性
      3. 致电gl.drawArrays(gl.TRIANGLES, 0, vertexCount)
    4. 球体:
      1. 绑定球体缓冲区
      2. 将缓冲区数据设置为aVert属性
      3. 致电gl.drawArrays(gl.TRIANGLES, 0, vertexCount)

    在此示例中,您使用相同的着色器使用两个绘制调用绘制两个不同的缓冲区。


    现在假设您有多个立方体,您想用不同的颜色(相同的着色器,但不同的制服)进行渲染。假设您的着色器还采用定位立方体中心的uniform vec3 aPos 值。

    1. 绑定着色器
    2. 将缓冲区数据设置为aVert属性
    3. 红立方:
      1. 将着色器上的 uColor 统一设置为 [1,0,0,1](红色)
      2. uPos 统一设置为[0,0,0]
      3. 致电gl.drawArrays(gl.TRIANGLES, 0, vertexCount)
    4. 蓝色立方体:
      1. 将着色器上的 uColor 统一设置为 [0,0,1,1](蓝色)
      2. uPos 统一设置为[10,0,0]
      3. 致电gl.drawArrays(gl.TRIANGLES, 0, vertexCount)

    在此示例中,您使用一个着色器将一个缓冲区绘制为两个对象,并使用两个不同的绘制调用,每个绘制调用在该着色器中具有不同的统一值。


    我应该创建更多缓冲区或创建更多顶点数组或创建更多程序吗?

    可以,或两者都根据需要。你有不同的几何图形要画吗?然后你需要更多的缓冲区。你有不同的方法来渲染那个几何图形吗?然后你需要更多的着色器。缓冲区定义了一个空白画布,着色器是您的油漆和画笔。也许您使用相同的画笔和相同的颜料绘制多个对象,或者您不使用。这取决于你。

    我目前正在尝试为一个项目制作多个球体。这些球体将充当围绕原子核运行的电子。基本上我正在尝试制作原子的 3d 模型。

    一个缓冲区(一个球体)和一个着色器的简单版本。着色器将定义:

    attribute vec3 aVert;
    uniform vec4 uColor;
    uniform float uRadius; // radius of sphere
    uniform float uOrbitRadius; // radius of orbit distance
    uniform fload uOrbitAngle; // radians around the orbit
    

    此着色器将有一个顶点着色器,它根据uRadius 缩放球体,然后通过uOrbitAngleuOrbitRadius 上的一些三角函数将球体移入轨道。

    它会有一个片段着色器,可以进行着色/照明/任何事情,并将结果着色为uColor

    然后你渲染一个氢原子:

    1. 绑定着色器
    2. 绑定缓冲区
    3. 在着色器中设置aVert属性
    4. 细胞核:
      1. 将着色器uColor 设置为[0.5,0.5,0.5,1](灰色)
      2. 将着色器uRadius 设置为10
      3. 将着色器uOrbitRadius 设置为0
      4. 将着色器uOrbitAngle 设置为0
      5. 致电gl.drawArrays()
    5. 电子:
      1. 将着色器 uColor 设置为 [1,0,1,1] (megenta)
      2. 将着色器uRadius 设置为1
      3. 将着色器uOrbitRadius 设置为20
      4. 将着色器 uOrbitAngle 设置为每帧增加的数量
      5. 致电gl.drawArrays()

    然后您可以通过重复电子渲染来添加更多电子,只更改uOrbitAngle

    但这实际上取决于您希望这两个对象的外观,这将决定您如何构建它。

    【讨论】:

    • 非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多