WebGL2?????????????????????(Instanced Arrays)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebGL2?????????????????????(Instanced Arrays)相关的知识,希望对你有一定的参考价值。

???????????????   ??????   ??????   ??????   9.png   ??????   png   10???   ??????   

???????????????

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????CPU???GPU??????????????????
????????????????????????????????????????????????????????????????????????uniform???????????????attribute?????????????????????attribute?????????????????????????????????????????????????????????????????????????????????????????????webgl??????????????????

??????

???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

for(var  i = 0; i < amount_of_models_to_draw; i++)
{
    doSomePreparations(); // bind VAO, bind Textures, set uniforms etc.
    gl.drawArrays(gl.TRIANGLES, 0, amount_of_vertices);
}

????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????webgl ??????????????????????????????VAO??????????????????????????????uniform???????????????GPU????????????????????????????????????????????????????????????????????????????????????????????????CPU???GPU????????????????????????

?????????

???????????????????????????????????????GPU???????????????WebGL?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????uniform????????????????????????????????????attribute??????????????????????????????????????????????????????????????????????????????????????????VBO?????????????????????????????? ????????????????????????????????????????????????????????????bufferData ???????????????????????????????????????attribute????????????????????????????????????
??????????????????????????????VBO?????????????????????????????????????????????????????????????????????????????? ??????????????????????????????????????????attribute???????????????????????????:

   gl.vertexAttribDivisor(index, divisor)

??????gl.vertexAttribDivisor????????????????????????????????????????????????????????????????????????divisor = 1????????????????????????????????????????????????divisor=2??????????????????????????????????????? index?????????attribute??????????????????

????????????????????????????????????????????????

gl.drawArraysInstanced(mode, first, count, instanceCount);
gl.drawElementsInstanced(mode, count, type, offset, instanceCount);

?????????????????? gl.drawArrays???gl.drawElements?????????????????????????????????????????? instanceCount???????????????????????????????????????
???????????????????????????????????????????????????????????????????????????

????????????

????????????

????????? ????????????????????????????????????????????????

 var count = 3000;
        var positions = new Float32Array([
            -1/count, 1/count, 0.0,
            -1/count, -1/count, 0.0,
            1/count, 1/count, 0.0,
            1/count, -1/count, 0.0,
        ]);
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0,
            1.0, 1.0, 1.0,
        ]);
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

        var indices = new Uint8Array([
            0,1,2,
            2,1,3
        ]);

        var indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW); //????????????????????????

        var offsetArray = [];
        for(var i = 0;i < count;i ++){
            for(var j = 0; j < count; j ++){
                var x = ((i + 1) - count/2) / count * 4;
                var y = ((j + 1) - count/2) / count * 4;
                var z = 0;
                offsetArray.push(x,y,z);
            }
        }

        var offsets = new Float32Array(offsetArray)

        var offsetBuffer = gl.createBuffer();
        var aOffsetLocation = 2;
        gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
        gl.enableVertexAttribArray(aOffsetLocation);
        gl.vertexAttribPointer(aOffsetLocation, 3, gl.FLOAT, false, 12, 0);
        gl.vertexAttribDivisor(aOffsetLocation, 1);

        // ////////////////
        // // DRAW
        // ////////////////
        gl.clear(gl.COLOR_BUFFER_BIT);// ?????????????????????
        // // ????????????????????????
        gl.bindVertexArray(triangleArray);
        gl.drawElementsInstanced(gl.TRIANGLES,indices.length,gl.UNSIGNED_BYTE,0,count * count);

###???????????????VBO???IBO??????
????????????????????????count?????????????????????????????? count * count,?????????count ??? count?????????????????? ???????????????????????????????????????????????????????????????????????????????????????WebGL1?????????????????????????????????

var positions = new Float32Array([
            -1/count, 1/count, 0.0,
            -1/count, -1/count, 0.0,
            1/count, 1/count, 0.0,
            1/count, -1/count, 0.0,
        ]);
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0,
            1.0, 1.0, 1.0,
        ]);
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

        var indices = new Uint8Array([
            0,1,2,
            2,1,3
        ]);

        var indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW); //????????????????????????

uniform????????????attribute??????

???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????WebGL1???????????????????????????uniform??????????????????????????????????????????????????????????????????????????????attribute??????, layout(location=2) in vec4 offset:

var vsSource = `#version 300 es
       ......
        layout(location=2) in vec4 offset;
        ......
        void main() {
            vColor = color;
            gl_Position = position  + offset;
        }
`;

???????????????????????????VBO

??????????????????????????????????????????????????????
``` var offsetArray = [];
for(var i = 0;i < count;i ++){
for(var j = 0; j < count; j ++){
var x = ((i + 1) - count/2) / count 4 - 2/count;
var y = ((j + 1) - count/2) / count
4 - 2/count;
var z = 0;
offsetArray.push(x,y,z);
}
}

??????????????????????????????????????????????????????count ??? count ????????????
??????????????????????????????????????????????????????????????????attribute?????????

var offsetBuffer = gl.createBuffer();
var aOffsetLocation = 2; // ?????????attribute????????????
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
gl.enableVertexAttribArray(aOffsetLocation); // ???????????????attribute???????????????????????????
gl.vertexAttribPointer(aOffsetLocation, 3, gl.FLOAT, false, 12, 0); // ??????????????????????????????3?????????????????????12 = 3 * 4????????????????????????
gl.vertexAttribDivisor(aOffsetLocation, 1);

### gl.vertexAttribDivisor
??????  gl.vertexAttribDivisor(aOffsetLocation, 1); ????????????1????????????????????????(??????????????????????????????3?????????????????????12 = 3 * 4??????????????????)) ??????????????????????????????????????????????????????????????????attribute??????offset?????????????????????uniform???????????????

### gl.drawElementsInstanced ??????????????????
?????????????????????????????????????????????
    // ////////////////
    // // DRAW
    // ////////////////
    gl.clear(gl.COLOR_BUFFER_BIT);// ?????????????????????
    // // ????????????????????????
    gl.bindVertexArray(triangleArray);
    gl.drawElementsInstanced(gl.TRIANGLES,indices.length,gl.UNSIGNED_BYTE,0,count * count);
gl.drawElementsInstanced ????????????count * count?????????????????????????????????????????????????????????????????????????????????attribute??????offset?????????????????????????????????????????????????????????offsetArray?????????count*count?????????????????????????????????3???????????????????????????????????????offsetArray?????????????????????????????????????????????????????????count * count ???????????????????????????
## ??????????????????
?????????count ?????????10?????????????????????????????????

![??????10*10?????????](http://upload-images.jianshu.io/upload_images/6271001-70e41e9924b21c8d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

????????????????????????????????????????????????100????????????
????????????WebGL1?????????????????????100?????????????????????????????????????????????????????????
????????????????????????100??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????count?????????4000??????????????????4000 * 4000 = ???????????????????????????????????????

![?????????????????????](http://upload-images.jianshu.io/upload_images/6271001-fc5ee472f58590c8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 
?????????????????????????????????????????????????????????????????????????????????????????????????????????
?????????WebGL1 ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????  
?????????????????? ??????????????????????????????????????????????????????count??????5000????????????5000 * 5000 = ????????????????????????????????????????????????

![?????????](http://upload-images.jianshu.io/upload_images/6271001-f60f0a01f4055d99.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## WebGL1 ??????
???WebGL1???????????????????????????ANGLE_instanced_arrays?????????????????????????????????

var ext = gl.getExtension(???ANGLE_instanced_arrays???);

ext.vertexAttribDivisorANGLE(index, divisor);

ext.drawArraysInstancedANGLE(mode, first, count, primcount);

ext.drawElementsInstancedANGLE(mode, count, type, offset, primcount);



???????????????????????????????????????:ITman??????
![ITman???????????????](https://upload-images.jianshu.io/upload_images/6271001-71b1902df91ba0cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/256)

以上是关于WebGL2?????????????????????(Instanced Arrays)的主要内容,如果未能解决你的问题,请参考以下文章

WebGL2 row_major 限定符意外工作

WebGL2:不完整的帧缓冲区

WebGL2?????????????????????(Instanced Arrays)

webGL2统一缓冲区对象和布局的使用(std140)

我可以在 webgl2 的单通道中存储签名的 16 位值吗?

WebGL2系列之实例数组(Instanced Arrays)