WebGL 2 Samples - draw_instanced_ubo
uniform blocs multi-instanced drawing
#version 300 es
#define POSITION_LOCATION 0
precision highp float;
precision highp int;
layout(std140, column_major) uniform;
uniform Transform
{
mat4 MVP[2];
} transform;
layout(location = POSITION_LOCATION) in vec2 pos;
flat out int instance;
void main()
{
instance = gl_InstanceID;
gl_Position = transform.MVP[gl_InstanceID] * vec4(pos, 0.0, 1.0);
}
#version 300 es
precision highp float;
precision highp int;
layout(std140) uniform;
uniform Material
{
vec4 Diffuse[2];
} material;
flat in int instance;
out vec4 color;
void main()
{
color = material.Diffuse[instance % 2];
}
'use strict';
var canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
var gl = canvas.getContext('webgl2', { antialias: false });
var isWebGL2 = !!gl;
if(!isWebGL2) {
document.getElementById('info').innerHTML = 'WebGL 2 is not available. See <a href="https://www.khronos.org/webgl/wiki/Getting_a_WebGL_Implementation">How to get a WebGL 2 implementation</a>';
return;
}
// -- Init program
var program = createProgram(gl, getShaderSource('vs'), getShaderSource('fs'));
gl.useProgram(program);
// -- Init Buffer
var vertexPosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
var vertices = new Float32Array([
-0.3, -0.5,
0.3, -0.5,
0.0, 0.5
]);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
var uniformTransformLocation = gl.getUniformBlockIndex(program, 'Transform');
var uniformMaterialLocation = gl.getUniformBlockIndex(program, 'Material');
gl.uniformBlockBinding(program, uniformTransformLocation, 0);
gl.uniformBlockBinding(program, uniformMaterialLocation, 1);
var uniformTransformBuffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformTransformBuffer);
var transforms = new Float32Array([
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
-0.5, 0.0, 0.0, 1.0,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.0, 0.0, 1.0
]);
gl.bufferData(gl.UNIFORM_BUFFER, transforms, gl.DYNAMIC_DRAW);
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
var uniformMaterialBuffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformMaterialBuffer);
var materials = new Float32Array([
1.0, 0.5, 0.0, 1.0,
0.0, 0.5, 1.0, 1.0
]);
gl.bufferData(gl.UNIFORM_BUFFER, materials, gl.STATIC_DRAW);
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
// -- Render
gl.clearColor(0,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uniformTransformBuffer);
gl.bindBufferBase(gl.UNIFORM_BUFFER, 1, uniformMaterialBuffer);
var vertexPosLocation = 0; // set with GLSL layout qualifier
gl.enableVertexAttribArray(vertexPosLocation);
gl.vertexAttribPointer(vertexPosLocation, 2, gl.FLOAT, false, 0, 0);
gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 2);
// -- Delete WebGL resources
gl.deleteBuffer(vertexPosBuffer);
gl.deleteBuffer(uniformTransformBuffer);
gl.deleteBuffer(uniformMaterialBuffer);
gl.deleteProgram(program);
参考 http://webglsamples.org/WebGL2Samples/#draw_instanced_ubo