javascript - 如何使用扩展 ANGLE_instanced_arrays 做一些事情?
问题描述
我想做任何 ANGLE_instanced_arrays,我阅读了 MDN 上的文档,但我什么都不懂。好吧,我知道我可以制作图形 2D 和 3D 之类的:示例,但对我来说,这些示例太高级了,很难理解所有代码。谁能帮我举个例子?
这部分我对文档官方的理解:
ANGLE_instanced_arrays 扩展是 WebGL API 的一部分,如果它们共享相同的顶点数据、图元计数和类型,则允许多次绘制相同的对象或相似对象组。
解决方案
没有你能画ANGLE_instanced_arrays
吗?有图和无图的区别是
您调用不同的绘图函数并传递要绘制多少个实例的额外参数。
ext.drawArraysInstancedANGLE
或ext.drawElementsInstancedANGLE
代替正常的ext.drawArrays
或ext.drawElements
您向顶点着色器添加一个或多个属性,每个绘制的实例的值只会更改一次。换句话说,如果您正在绘制一个立方体,则在绘制第一个立方体时,每个顶点的属性值将是相同的值,在绘制第二个立方体时将是不同的值,在绘制第三个立方体时将是第三个值。当每个顶点的正常属性发生变化时,这些属性每个立方体/项目仅更改一次。
要添加的最明显的属性是每个立方体位置的额外位置,以便每个立方体可以将不同的位置添加到顶点位置,但您可以为纯立方体颜色添加另一个属性或添加矩阵属性,以便您可以完全独立地定向每个立方体或无论你想要什么。
对于每个立方体只更改一次的属性,您可以通过调用将它们的顶点除数设置为 1
ext.vertexAttribDivisorANGLE
。意思是“1
每 1 个实例提升属性”。0
(默认)表示advance the attribute every vertex (every iteration of the vertex shader)
.
这是一个绘制单个四边形(2 个三角形,6 个顶点)的示例
const vs = `
attribute vec4 position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * position;
}
`;
const fs = `
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}
`;
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl");
const program = twgl.createProgram(gl, [vs, fs]);
const positionLocation = gl.getAttribLocation(program, "position");
const matrixLocation = gl.getUniformLocation(program, "u_matrix");
const colorLocation = gl.getUniformLocation(program, "u_color");
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
// one face
-1, -1,
1, -1,
-1, 1,
-1, 1,
1, -1,
1, 1,
],
), gl.STATIC_DRAW);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.enableVertexAttribArray(positionLocation);
{
const size = 2; // 2 values per vertex
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);
}
gl.useProgram(program);
gl.uniform4fv(colorLocation, [1, .5, .2, 1]);
gl.uniformMatrix4fv(matrixLocation, false, m4.scaling([.25, .25, .25]));
const offset = 0;
const vertexCount = 6;
gl.drawArrays(gl.TRIANGLES, offset, vertexCount);
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
这是一个使用 . 绘制 100 个四边形的示例ANGLE_instanced_arrays
。我们为每个四边形添加了planeOffset
一个偏移量,并为每个四边形添加了planeColor
一个颜色。
const vs = `
attribute vec4 position;
attribute vec2 planeOffset; // per plane offset
attribute vec4 planeColor; // per plane color
uniform mat4 u_matrix;
varying vec4 v_color;
void main() {
mat4 translation = mat4(
vec4(1, 0, 0, 0),
vec4(0, 1, 0, 0),
vec4(0, 0, 1, 0),
vec4(planeOffset, 0, 1));
gl_Position = u_matrix * translation * position;
v_color = planeColor;
}
`;
const fs = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`;
function main() {
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl");
const ext = gl.getExtension("ANGLE_instanced_arrays");
if (!ext) {
alert("need ANGLE_instanced_arrays");
return;
}
const program = twgl.createProgram(gl, [vs, fs]);
const positionLocation = gl.getAttribLocation(program, "position");
const offsetLocation = gl.getAttribLocation(program, "planeOffset");
const colorLocation = gl.getAttribLocation(program, "planeColor");
const matrixLocation = gl.getUniformLocation(program, "u_matrix");
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
// one face
-1, -1,
1, -1,
-1, 1,
-1, 1,
1, -1,
1, 1,
],
), gl.STATIC_DRAW);
// make 100 offsets and 100 colors
const colors = [];
const offsets = [];
const numInstances = 100;
for (let i = 0; i < 100; ++i) {
colors.push(Math.random(), Math.random(), Math.random(), 1);
offsets.push(Math.random() * 20 - 10, Math.random() * 20 - 10);
}
// put those in buffers
const offsetBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(offsets), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.enableVertexAttribArray(positionLocation);
{
const size = 2; // 2 values per vertex
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);
}
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
gl.enableVertexAttribArray(offsetLocation);
{
const size = 2; // 2 values per vertex
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.vertexAttribPointer(offsetLocation, size, type, normalize, stride, offset);
ext.vertexAttribDivisorANGLE(offsetLocation, 1);
}
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.enableVertexAttribArray(colorLocation);
{
const size = 4; // 4 values per vertex
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.vertexAttribPointer(colorLocation, size, type, normalize, stride, offset);
ext.vertexAttribDivisorANGLE(colorLocation, 1);
}
gl.useProgram(program);
gl.uniformMatrix4fv(matrixLocation, false, m4.scaling([.1, .1, .1]));
const offset = 0;
const vertexCount = 6;
ext.drawArraysInstancedANGLE(gl.TRIANGLES, offset, vertexCount, numInstances);
}
main();
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
推荐阅读
- python - DataFrame 来自现有列的新列
- firebase - 如何更新存储在firestore中的发布者信息,以及使用flutter应用程序
- asp.net - 我在 asp:label 元素的字符串中使用下划线时遇到问题
- javascript - 窗口按键侦听器也在文本框按键上调用
- javascript - 你能发现这个 React 组件代码中的错字吗?
- uwp - 是否有将 Uno 3 添加到现有 UWP 应用程序的指南?
- azure-active-directory - MS Graph 和系统帐户访问示例
- c++ - 访问 std::variant 中的公共结构成员
- java - 使用带有 SQL WHERE 子句的 Java 变量从结果集中获取主键值
- javascript - 如何存储使用他的出生日期的人的年龄输入但它不起作用