从WebGL的着色器中更新缓冲区 [英] Updating buffers from within shaders in webgl

查看:72
本文介绍了从WebGL的着色器中更新缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是着色器和WebGL的初学者,并且我采取了一些捷径来开发当前的功能,所以请多多包涵.

I'm a beginner at shaders and WebGL and I've taken some shortcuts to develop what I currently have, so please bear with me.

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

Is there a way to update attribute buffer data within the GPU only? Basically what I want to do is to send in three buffers t0, t1, t2 into the GPU representing points and their position in time 0, 1, and 2 respectively. Then I wish to update their new position tn depending on the properties of t2, t1, and t0 depending on the velocity of the points, turning angle, and so on.

我当前的实现会更新javascript中的位置,然后在每次绘制时将缓冲区复制到WebGL中.但为什么?这对我来说似乎效率极低,而且我不明白为什么我不能始终不执行着色器中的所有操作来跳过从CPU-> GPU移走数据.这有可能吗?

My current implementation updates the positions in javascript and then copies the buffers into WebGL at every draw. But why? This seems terribly inefficient to me, and I don't see why I couldn't do everything in the shader to skip moving data from CPU->GPU all the time. Is this possible somehow?

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

This is current vertex shader which sets color on the point depending on the turn direction and angle it's turning at (tn is updated in JS atm by debugging functions):

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,以准备另一个循环,但都在顶点着色器中(不仅是为了提高效率,而且还出于其他一些与问题无关但与我正在从事的项目有关的原因).

What I want to do is to update the position gl_Position (tn) depending on these properties, and then somehow shuffle/copy the buffers tn->t2, t2->t1, t1->t0 to prepare for another cycle, but all within the vertex shader (not only for the efficiency, but also for some other reasons which are unrelated to the question but related to the project I'm working on).

推荐答案

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

Note, your question should probably be closed as a duplicate since how to write output from a vertex shader is already covered but just to add some notes relevant to your question...

在WebGL1中无法更新GPU中的缓冲区.您可以将数据存储在纹理中并更新纹理.尽管如此,您仍然无法从自身更新纹理

In WebGL1 is it not possible to update buffers in the GPU. You can instead store your data in a texture and update a texture. Still, you can not update a texture from itself

 pos = pos + vel   // won't work

但是您可以更新另一个纹理

But you can update another texture

 newPos = pos + vel   // will work

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

Then next time pass the texture called newPos as pos and visa versa

在WebGL2中,您可以使用"transformFeedback"将输出的顶点着色器(变量)写入缓冲区.它具有相同的问题,即您无法写回正在读取的缓冲区.

In WebGL2 you can use "transformFeedback" to write the output a vertex shader (the varyings) to a buffer. It has the same issue that you can not write back to a buffer you are reading from.

此答案中,有一个写入纹理的示例以及一个使用transformfeedback写入缓冲区的示例.

There is an example of writing to a texture and also an example of writing to a buffer using transformfeedback in this answer

还有一个将顶点数据放入纹理的示例此处

Also an example of putting vertex data in a texture here

有一个使用纹理更新 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆