【问题标题】:Updating buffers from within shaders in webgl从 webgl 的着色器中更新缓冲区
【发布时间】:2020-10-25 21:30:39
【问题描述】:

我是着色器和 WebGL 的初学者,我已经采取了一些捷径来开发我目前拥有的东西,所以请多多包涵。

有没有办法只在 GPU 内更新属性缓冲区数据?基本上我想要做的是将三个缓冲区 t0、t1、t2 发送到 GPU 中,分别表示点及其在时间 0、1 和 2 中的位置。然后我希望根据点的速度、转角等根据 t2、t1 和 t0 的属性更新它们的新位置 tn。

我当前的实现会更新 javascript 中的位置,然后在每次绘制时将缓冲区复制到 WebGL。但为什么?这对我来说似乎非常低效,我不明白为什么我不能在着色器中做所有事情来跳过从 CPU-> GPU 移动数据。这有可能吗?

这是当前的顶点着色器,它根据旋转方向和旋转角度设置点的颜色(tn 在 JS atm 中通过调试函数更新):

export const VsSource = `
    #define M_PI 3.1415926535897932384626433832795
    
    attribute vec4 t0_pos;
    attribute vec4 t1_pos;
    attribute vec4 t2_pos;

    varying vec4 color;

    attribute vec4 r_texture;

    void main() {

        float dist = distance(t1_pos, t2_pos);
        vec4 v = normalize(t1_pos-t0_pos);
        vec4 u = normalize(t2_pos-t1_pos);
        float angle = acos(dot(u, v));
        float intensinty = angle / M_PI * 25.0;
        float turnDirr = (t0_pos.y-t1_pos.y) * (t2_pos.x-t1_pos.x) + (t1_pos.x-t0_pos.x) * (t2_pos.y-t1_pos.y);

        if(turnDirr > 0.000000001 ) {
            color = vec4(1.0, 0.0, 0.0, intensinty);
        } else if( turnDirr < -0.000000001 ) {
            color = vec4(0.0, 0.0, 1.0, intensinty);
        } else {
            color = vec4(1.0, 1.0, 1.0, 0.03);
        }
                
        gl_Position = t2_pos;

        gl_PointSize = 50.0;
    }
`;

我想要做的是根据这些属性更新位置 gl_Position (tn),然后以某种方式随机/复制缓冲区 tn->t2, t2->t1, t1->t0 以准备另一个循环,但都在顶点着色器中(不仅是为了效率,还有其他一些与问题无关但与我正在从事的项目相关的原因)。

【问题讨论】:

  • 旁注。 webGL 着色器的最佳浮点精度为 32 位。大多数定义的字符串 3.1415926535897932384626433832795 丢失了,因为你能得到的最接近的是 ~3.141593

标签: javascript glsl webgl


【解决方案1】:

请注意,您的问题可能应该作为重复项关闭,因为已经涵盖了如何从顶点着色器编写输出,但只是添加一些与您的问题相关的注释...

在 WebGL1 中无法更新 GPU 中的缓冲区。您可以改为将数据存储在纹理中并更新纹理。不过,您不能从自身更新纹理

 pos = pos + vel   // won't work

但你可以更新另一个纹理

 newPos = pos + vel   // will work

然后下次将名为newPos 的纹理传递为pos,反之亦然

在 WebGL2 中,您可以使用“transformFeedback”将顶点着色器(变量)的输出写入缓冲区。它有同样的问题,你不能写回你正在读取的缓冲区。

this answer 中有一个写入纹理的示例和一个使用 transformfeedback 写入缓冲区的示例

也是将顶点数据放入纹理here的示例

有一个粒子系统使用纹理来更新this Q&A中的位置的例子

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多