WebGL:如何将值绑定到mat4属性? [英] WebGL: How to bind values to a mat4 attribute?

查看:127
本文介绍了WebGL:如何将值绑定到mat4属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些WebGL应用程序中,我们假设我们有一个GLSL顶点着色器,它的开始是这样的:

In some WebGL application, let's assume that we have a GLSL vertex shader which starts like this:

attribute vec4 foo1;
attribute vec4 foo2;
attribute vec4 foo3;
attribute vec4 foo4;

以及一些相应的Javascript代码,用于为这些属性绑定数据结构:

and some corresponding Javascript code for binding a data structure for those attributes:

var buf = gl.createBuffer(), loc;
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([…]));

loc = gl.getAttribLocation(program, 'foo1');
gl.enableVertexArray(loc);
gl.vertexAttribPointer(loc, 4, gl.FLOAT, false, 16, 0);

loc = gl.getAttribLocation(program, 'foo2');
gl.enableVertexArray(loc);
gl.vertexAttribPointer(loc, 4, gl.FLOAT, false, 16, 4);

loc = gl.getAttribLocation(program, 'foo3');
gl.enableVertexArray(loc);
gl.vertexAttribPointer(loc, 4, gl.FLOAT, false, 16, 8);

loc = gl.getAttribLocation(program, 'foo4');
gl.enableVertexArray(loc);
gl.vertexAttribPointer(loc, 4, gl.FLOAT, false, 16, 12);

现在,根据GL ES 2.0规范,顶点着色器属性可以定义为floatvec2vec3vec4mat2mat3mat4

Now, according to the GL ES 2.0 specs, a vertex shader attribute can be defined as either a float, vec2, vec3, vec4, mat2, mat3 or mat4.

因此,如果我更改顶点着色器代码以仅定义一个mat4属性,就像这样...

So if I change the vertex shader code to define just one mat4 attribute, like so...

attribute mat4 foo;

...问题是将某些指针绑定到mat4属性的相应JS代码是什么?

... the question is what is the corresponding JS code to bind some pointers to a mat4 attribute?

我在WebGL中发现了问题 mat3属性,但是答案不够明确.阅读答案和其他一些文档,似乎似乎正确的解决方案是:

I have found the question mat3 attribute in WebGL, but the answer is not explicit enough. Reading the answers and some other documentation, it seems that the correct solution is along the lines of:

loc = gl.getAttribLocation(program, 'foo');
gl.enableVertexArray(loc);
gl.vertexAttribPointer(loc  , 4, gl.FLOAT, false, 16, 0);
gl.vertexAttribPointer(loc+1, 4, gl.FLOAT, false, 16, 4);
gl.vertexAttribPointer(loc+2, 4, gl.FLOAT, false, 16, 8);
gl.vertexAttribPointer(loc+3, 4, gl.FLOAT, false, 16, 12);

我是否正确假设的4个vec4组件的位置总是相邻并以递增的顺序进行?这是否记录在某处?

Am I right in assuming that the locations of the 4 vec4 components of a mat4 are always adjacent and in increasing order? Is this documented somewhere?

除了这些位置计入MAX_VERTEX_ATTRIBS限制(在WebGL中通常为16)之外,还有其他好方法要注意吗?

Besides these locations counting towards the MAX_VERTEX_ATTRIBS limit (normally 16 in WebGL), is there any other good practice to be aware of?

推荐答案

您是正确的. 摘自规范第2.10.4节

You're correct. From the spec section 2.10.4

将属性变量声明为mat2时,其矩阵列取自通用属性ii + 1(x, y)组件.将属性变量声明为mat3时,其矩阵列取自通用属性ii + 2(x, y, z)组件.当将属性变量声明为mat4时,其矩阵列取自通用属性ii + 3(x, y, z, w)组件.

When an attribute variable is declared as a mat2, its matrix columns are taken from the (x, y) components of generic attributes i and i + 1. When an attribute variable is declared as a mat3, its matrix columns are taken from the (x, y, z) components of generic attributes i through i + 2. When an attribute variable is declared as a mat4, its matrix columns are taken from the (x, y, z, w) components of generic attributes i through i + 3.

WebGL中的步幅和偏移量以字节为单位,所以我怀疑您想要

stride and offsets in WebGL are in bytes so I suspect you wanted

gl.vertexAttribPointer(loc  , 4, gl.FLOAT, false, 64, 0);
gl.vertexAttribPointer(loc+1, 4, gl.FLOAT, false, 64, 16);
gl.vertexAttribPointer(loc+2, 4, gl.FLOAT, false, 64, 32);
gl.vertexAttribPointer(loc+3, 4, gl.FLOAT, false, 64, 48);

让我们检查一下

var vs = `
attribute mat4 matrix;
attribute vec4 color;

varying vec4 v_color;

void main() {
  gl_PointSize = 10.0;
  gl_Position = matrix * vec4(0, 0, 0, 1);
  v_color = color;
}
`;
var fs = `
precision mediump float;

varying vec4 v_color;

void main() {
  gl_FragColor = v_color;
}
`;

var m4 = twgl.m4;
var gl = document.querySelector("canvas").getContext("webgl");
var program = twgl.createProgramFromSources(gl, [vs, fs]);

var matrixLoc = gl.getAttribLocation(program, "matrix");
var colorLoc = gl.getAttribLocation(program, "color");

function r(min, max) {
  if (max === undefined) {
    max = min;
    min = 0;
  }
  return Math.random() * (max - min) + min;
}

var numPoints = 100;
var matrices = [];
var colors = [];
for (var ii = 0; ii < numPoints; ++ii) {
  matrices.push.apply(matrices, m4.translation([r(-1,1), r(-1,1), 0]));
  colors.push(r(1), r(1), r(1), 1);
}

var buffers = twgl.createBuffersFromArrays(gl, {
  matrices: matrices,
  colors: colors,
});

gl.useProgram(program);

gl.bindBuffer(gl.ARRAY_BUFFER, buffers.matrices);
for (var ii = 0; ii < 4; ++ii) {
  gl.enableVertexAttribArray(matrixLoc + ii);
  gl.vertexAttribPointer(matrixLoc + ii, 4, gl.FLOAT, 0, 64, ii * 16);
}

gl.bindBuffer(gl.ARRAY_BUFFER, buffers.colors);
gl.enableVertexAttribArray(colorLoc);
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, 0, 0, 0);

gl.drawArrays(gl.POINTS, 0, numPoints);

canvas { border: 1px solid black; }

<script src="https://twgljs.org/dist/twgl-full.min.js"></script>
<canvas></canvas>

这篇关于WebGL:如何将值绑定到mat4属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆