Javascript 从webgl中的着色器内更新缓冲区

Javascript 从webgl中的着色器内更新缓冲区,javascript,glsl,webgl,Javascript,Glsl,Webgl,我是着色器和WebGL的初学者,我已经采取了一些捷径来开发我目前拥有的,所以请耐心等待 是否有办法仅在GPU内更新属性缓冲区数据?基本上,我想做的是将三个缓冲区t0、t1、t2分别发送到GPU中,分别表示时间0、1和2上的点及其位置。然后,我希望根据t2、t1和t0的属性,根据点的速度、转角等,更新它们的新位置tn 我当前的实现更新javascript中的位置,然后在每次绘制时将缓冲区复制到WebGL中。但是为什么呢?这对我来说效率非常低,我不明白为什么我不能在着色器中做所有的事情来跳过从CPU

我是着色器和WebGL的初学者,我已经采取了一些捷径来开发我目前拥有的,所以请耐心等待

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

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

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

export const VsSource=`
#定义M_PI 3.1415926535897932384626433832795
属性vec4-t0_-pos;
属性向量4 t1_pos;
属性向量4 t2_pos;
可变的vec4颜色;
属性向量4 r_纹理;
void main(){
浮动距离=距离(t1位置,t2位置);
vec4 v=正常化(t1_pos-t0_pos);
vec4 u=正常化(t2_pos-t1_pos);
浮动角度=acos(点(u,v));
浮动强度=角度/M_PI*25.0;
浮动旋转方向=(t0位置y-t1位置y)*(t2位置x-t1位置x)+(t1位置x-t0位置x)*(t2位置y-t1位置y);
如果(turnDirr>0.000000001){
颜色=vec4(1.0,0.0,0.0,强度);
}否则如果(turnDirr<-0.000000001){
颜色=vec4(0.0,0.0,1.0,强度);
}否则{
颜色=vec4(1.0,1.0,1.0,0.03);
}
gl_位置=t2_位置;
gl_PointSize=50.0;
}
`;

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

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

在WebGL1中,无法更新GPU中的缓冲区。您可以将数据存储在纹理中并更新纹理。但是,您无法从纹理本身更新纹理

 pos = pos + vel   // won't work
但是你可以更新另一个纹理

 newPos = pos + vel   // will work
然后下次将名为
newPos
的纹理作为
pos
传递,反之亦然

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

这里有一个写入纹理的示例,也有一个使用transformfeedback写入缓冲区的示例

这也是在纹理中放置顶点数据的示例


这里有一个粒子系统使用纹理更新位置的示例。

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

在WebGL1中,无法更新GPU中的缓冲区。您可以将数据存储在纹理中并更新纹理。但是,您无法从纹理本身更新纹理

 pos = pos + vel   // won't work
但是你可以更新另一个纹理

 newPos = pos + vel   // will work
然后下次将名为
newPos
的纹理作为
pos
传递,反之亦然

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

这里有一个写入纹理的示例,也有一个使用transformfeedback写入缓冲区的示例

这也是在纹理中放置顶点数据的示例


例如,粒子系统使用纹理更新侧面注释中的位置。webGL着色器的最佳浮点精度为32位。大多数已定义的字符串3.1415926535897932384626433832795将丢失,因为可以获得的最接近的字符串为~3.141593侧面注释。webGL着色器的最佳浮点精度为32位。大多数已定义的字符串3.1415926535897932384626433832795已丢失,因为您可以获得的最近值为~3.141593