Javascript Webgl:步幅不工作。不';t跨过缓冲区中的值

Javascript Webgl:步幅不工作。不';t跨过缓冲区中的值,javascript,webgl,stride,Javascript,Webgl,Stride,我在webgl中做一个lorenz吸引子,通常我在玩多维奇怪吸引子。我在webgl中为此制作了一个粒子系统,在大多数情况下,该系统运行良好。粒子系统的工作原理是渲染gl点的x和y值,同时将更高的维度保留在同一缓冲区中,以计算其各自的导数。缓冲区示例:x=缓冲区[i],y=缓冲区[i+1],z=缓冲区[i+2],w=缓冲区[i+3]等等 我注意到当z大于1时,这些点消失了。这是我目前无法解决的另一个问题,因此我通过完全跨过这些值来绕过它,因为z无论如何都不应该是可视化的一部分,但是这个跨步系统不起

我在webgl中做一个lorenz吸引子,通常我在玩多维奇怪吸引子。我在webgl中为此制作了一个粒子系统,在大多数情况下,该系统运行良好。粒子系统的工作原理是渲染gl点的x和y值,同时将更高的维度保留在同一缓冲区中,以计算其各自的导数。缓冲区示例:x=缓冲区[i],y=缓冲区[i+1],z=缓冲区[i+2],w=缓冲区[i+3]等等

我注意到当z大于1时,这些点消失了。这是我目前无法解决的另一个问题,因此我通过完全跨过这些值来绕过它,因为z无论如何都不应该是可视化的一部分,但是这个跨步系统不起作用

我知道另一种解决方案是制作一个只包含x和y值的位置数组的副本,并将其作为二维系统传递到着色器程序中,这是可行的!这样做可以消除“消失点”问题,但由于垃圾收集(我希望没有垃圾收集),它会导致大量粒子的延迟

这是缓冲区代码:

dims = 3;
drawScene(gl, program, positions) {
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        var positionAttributeLocation = gl.getAttribLocation(program, "a_position");        
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

        // positions is array of x,y,z coordinates 
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
        gl.enableVertexAttribArray(positionAttributeLocation);

        const size = this.dims;         
        const type = gl.FLOAT;
        const normalize = true; 
        const stride = 4 * (this.dims-2); // gl.FLOAT=4 bytes, then stride +1 extra per dim above 2
        const offset = 0;
        gl.vertexAttribPointer(
            positionAttributeLocation, size, type, normalize, stride, offset);

        const primitiveType = gl.POINTS;
        const count = positions.length / this.dims;

        gl.drawArrays(primitiveType, offset, count);
    }

步幅不对。步幅应该是
dims*4
,如果只需要x和y,则大小仅为2

其他问题

  • 另外,你不能正常化浮动

  • 您应该在初始时间而不是渲染时间查找位置

  • 您应该创建一个缓冲区并重用它

    该代码目前正在每帧创建一个新的缓冲区,最终将耗尽内存

  • 代码每一帧都在执行从本机JavaScript数组到新数组的转换。这也是一种分配

    您应该只创建一个Float32Array并更新其中的值

  • 代码通过调用
    gl.bufferData
    在WebGL的每个帧内分配一个新数组。而是调用
    gl.bufferSubData
    来上传数据

  • 如果您经常更改缓冲区中的数据,则应将其标记为
    gl.DYNAMIC\u DRAW
    ,以便WebGL知道您计划经常更新它。它可以将其用作性能提示

  • const gl=document.querySelector('canvas').getContext('webgl');
    常数vs=`
    属性向量2 a_位置;
    void main(){
    gl_位置=vec4(a_位置,0,1);
    gl_PointSize=5.0;
    }`;
    常数fs=`
    精密中泵浮子;
    void main(){
    gl_FragColor=vec4(1,0,0,1);
    }`;
    常量prg=twgl.createProgram(gl[vs,fs]);
    const positionAttributeLocation=gl.getAttributeLocation(prg,'a_position');
    常数dims=3;
    常数num=100;
    常量位置=新的浮点数组(dims*num);
    //在初始化时创建缓冲区
    const positionBuffer=gl.createBuffer();
    gl.bindBuffer(gl.ARRAY\u BUFFER,positionBuffer);
    //只需分配空间
    gl.bufferData(gl.ARRAY_BUFFER,positions.ByTeleLength,gl.DYNAMIC_DRAW);
    功能绘图场景(总图、程序、位置){
    gl.clearColor(0.0,0.0,0.0,1.0);
    总账清除(总账颜色缓冲位);
    //更新职位
    gl.bindBuffer(gl.ARRAY\u BUFFER,positionBuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER,0,位置);
    gl.EnableVertexAttributeArray(位置属性位置);
    常数大小=2;
    常量类型=gl.FLOAT;
    常量normalize=false;
    恒定步幅=4*dims;
    常数偏移=0;
    gl.VertexAttribute指针(
    位置属性位置、大小、类型、规格化、步幅、偏移);
    gl.useProgram(程序);
    常量原语类型=gl.POINTS;
    常数计数=位置。长度/dims;
    总账.DrawArray(原语类型、偏移量、计数);
    }
    函数渲染(时间){
    时间*=0.001;
    对于(设i=0;i
    
    画布{
    边框:1px纯黑;
    }