我正在尝试使用THREE.InstancedBufferAttribute将matrix4发送到顶点着色器,但我无法弄清楚如何。
这样可行:
JS
// convert the geometry to an InstancedBufferGeometry
var geometry = new THREE.InstancedBufferGeometry().fromGeometry(geometry);
(...)
// transforms
var transformsCol0 = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 4), 4, 1);
var transformsCol1 = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 4), 4, 1);
var transformsCol2 = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 4), 4, 1);
var transformsCol3 = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 4), 4, 1);
// declare matrices only once outside the loop
var workingMatrix = new THREE.Matrix4();
var transformMatrix = new THREE.Matrix4();
for (var i = 0; i < instanceCount; i++) {
var instance = instances[i];
// transforms: translation
transformMatrix.makeTranslation(instance.position.x, instance.position.y, instance.position.z);
// transforms: rotation: X
workingMatrix.makeRotationX(instance.rotation.x);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
// transforms: rotation: Y
workingMatrix.makeRotationY(instance.rotation.y);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
// transforms: rotation: Z
workingMatrix.makeRotationZ(instance.rotation.z);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
// transforms: scale
workingMatrix.makeScale(instance.scale.x, instance.scale.y, instance.scale.z);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
transformsCol0.setXYZW(i, transformMatrix.elements[0], transformMatrix.elements[1], transformMatrix.elements[2], transformMatrix.elements[3]);
transformsCol1.setXYZW(i, transformMatrix.elements[4], transformMatrix.elements[5], transformMatrix.elements[6], transformMatrix.elements[7]);
transformsCol2.setXYZW(i, transformMatrix.elements[8], transformMatrix.elements[9], transformMatrix.elements[10], transformMatrix.elements[11]);
transformsCol3.setXYZW(i, transformMatrix.elements[12], transformMatrix.elements[13], transformMatrix.elements[14], transformMatrix.elements[15]);
}
geometry.addAttribute('transformsCol0', transformsCol0);
geometry.addAttribute('transformsCol1', transformsCol1);
geometry.addAttribute('transformsCol2', transformsCol2);
geometry.addAttribute('transformsCol3', transformsCol3);
着色
precision highp float;
attribute vec4 color;
attribute vec4 transformsCol0;
attribute vec4 transformsCol1;
attribute vec4 transformsCol2;
attribute vec4 transformsCol3;
varying vec4 vColor;
void main() {
vColor = color;
mat4 transforms = mat4(
transformsCol0,
transformsCol1,
transformsCol2,
transformsCol3
);
gl_Position = projectionMatrix * modelViewMatrix * transforms * vec4( position, 1.0 );
}
然而,这不会:
JS
// convert the geometry to an InstancedBufferGeometry
var geometry = new THREE.InstancedBufferGeometry().fromGeometry(geometry);
(...)
// transforms
var transforms = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 16), 16, 1);
// declare matrices only once outside the loop
var workingMatrix = new THREE.Matrix4();
var transformMatrix = new THREE.Matrix4();
for (var i = 0; i < instanceCount; i++) {
var instance = instances[i];
// transforms: translation
transformMatrix.makeTranslation(instance.position.x, instance.position.y, instance.position.z);
// transforms: rotation: X
workingMatrix.makeRotationX(instance.rotation.x);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
// transforms: rotation: Y
workingMatrix.makeRotationY(instance.rotation.y);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
// transforms: rotation: Z
workingMatrix.makeRotationZ(instance.rotation.z);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
// transforms: scale
workingMatrix.makeScale(instance.scale.x, instance.scale.y, instance.scale.z);
transformMatrix.multiply(workingMatrix);
workingMatrix.identity();
transforms.set(transformMatrix.elements, i);
}
geometry.addAttribute('transforms', transforms);
着色
attribute vec4 color;
attribute mat4 transforms;
varying vec4 vColor;
void main() {
vColor = color;
gl_Position = projectionMatrix * modelViewMatrix * transforms * vec4( position, 1.0 );
}
当我尝试运行上面的代码时,我在浏览器控制台中出现此错误
[.Offscreen-For-WebGL-0x7ff054396800]GL ERROR :GL_INVALID_VALUE : glVertexAttribPointer: size GL_INVALID_VALUE
我在github中找不到任何相关问题,但我认为此示例的创建者由于this commented-out code而面临同样的问题
答案 0 :(得分:1)
每个通用顶点属性的组件数必须为1,2,3或4.您尝试传递16个组件。
参考:https://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml
three.js r.81