如何在 Webgl 的缓冲区中仅使用 4 个顶点绘制 2 个嵌套矩形?
How to draw 2 nested rectangles using ONLY 4 vertices in the buffer in Webgl?
我知道如何使用统一变量来移动矩形,但我不知道如何使它变小或变大以适应另一个。任何帮助表示赞赏。谢谢!
var vertices =
[
vec2(0.0, 0.0 ),
vec2(0.4, 0),
vec2(0, 0.4),
vec2(0.4, 0.4)
];
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 0.9, 0.9, 0.9, 1.0 );
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
// Create a buffer for the vertex shader in the GPU.
var bufferId = gl.createBuffer();
// Tell the GPU to expect data for this buffer
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
// Send data into the buffer.
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Set up the buffer for use
var vPosition = gl.getAttribLocation( program, "myvPosition" );
// myvPosition (identified using vPosition) will correspond to 2 floats per vertex,
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
// Enable use of the vertex buffer with myvPosition
gl.enableVertexAttribArray( vPosition );
// Get an index to each uniform variable in the GPU's shader
var xIndex = gl.getUniformLocation( program, "xAdjust" );
var yIndex = gl.getUniformLocation( program, "yAdjust" );
var rIndex = gl.getUniformLocation( program, "red" );
var gIndex = gl.getUniformLocation( program, "green" );
var bIndex = gl.getUniformLocation( program, "blue" );
gl.uniform1f( xIndex, -0.25 ); // move to the left
gl.uniform1f( gIndex, 1.0 );
gl.clear( gl.COLOR_BUFFER_BIT ); // note new place to put clear
render();
gl.uniform1f( xIndex, +0.25 ); // move to the right
gl.uniform1f( rIndex, 1.0 );
render();
};
function render()
{
gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );
}
例如:我可以更改 gl.uniform1f(xIndex, ) 中的值以沿 x 轴移动矩形
是时候学习变换矩阵了。有很多数学,但我会尽量解释得尽可能简单。
让我们选择新方块 1x1:
var vertices =
[
vec2(0, 0),
vec2(1, 0),
vec2(0, 1),
vec2(1, 1)
];
现在,如果您想将它向左移动 1(就像您所做的那样),您需要将所有顶点的 [x] 添加 1。这个看起来很简单。
如果要旋转它,那就复杂多了。想象一下,您的对象将来自 50000 个顶点,而不仅仅是 4 个 => 超级复杂!
所以人们发明了一些被广泛使用的程序。我们为我们拥有的每个对象创建转换矩阵。在 2D 中,矩阵是 3x3。在 3D 中,矩阵是 4x4。
矩阵是如何工作的?首先创建顶点,然后使用
初始化矩阵
// js example
var model1M = mat3.create([
1, 0, 0,
0, 1, 0,
0, 0, 1]);
这意味着 "no transformation done" 呢。然后通过矩阵操作平移、旋转、缩放对象。 记住,转换顺序很重要!!
move & rotate != rotate & move
一旦你想渲染,你发送矩阵到着色器。
// this is how you send 1 float value
gl.uniform1f( xIndex, -0.25 ); // move to the left
// this is how we send 3x3 matrix
var mvmi = gl.getUniformLocation( program, "modelViewMatrix" );
gl.uniformMatrix3fv(mvmi, false, model1M);
在着色器中:
// you have to modify what is in vec4
gl_Position = modelViewMatrix * vec4( position, 1.0 );
完成了。
问题是 mat3
在 js 中不存在。转换数学:
http://upload.wikimedia.org/wikipedia/commons/2/2c/2D_affine_transformation_matrix.svg
您需要先完成所有的数学运算。但更简单的是下载库,例如 http://glmatrix.net/ and include gl-matrix-min.js
. Then follow documentation http://glmatrix.net/docs/2.2.0/symbols/mat3.html .
简单的食谱:
var DEG_TO_RAD = 0.0174532925;
// create matrix, you dont have to type numbers in
var modelMatrix = mat3.create();
// move
mat3.translate(modelMatrix, modelMatrix, [-0.5, -0.5]);
// rotate by 45 degrees
mat3.rotate(modelMatrix, modelMatrix, 45*DEG_TO_RAD);
// make square smaller
mat3.scale(modelMatrix, modelMatrix, [0.4, 0.4]);
我知道如何使用统一变量来移动矩形,但我不知道如何使它变小或变大以适应另一个。任何帮助表示赞赏。谢谢!
var vertices =
[
vec2(0.0, 0.0 ),
vec2(0.4, 0),
vec2(0, 0.4),
vec2(0.4, 0.4)
];
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 0.9, 0.9, 0.9, 1.0 );
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
// Create a buffer for the vertex shader in the GPU.
var bufferId = gl.createBuffer();
// Tell the GPU to expect data for this buffer
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
// Send data into the buffer.
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Set up the buffer for use
var vPosition = gl.getAttribLocation( program, "myvPosition" );
// myvPosition (identified using vPosition) will correspond to 2 floats per vertex,
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
// Enable use of the vertex buffer with myvPosition
gl.enableVertexAttribArray( vPosition );
// Get an index to each uniform variable in the GPU's shader
var xIndex = gl.getUniformLocation( program, "xAdjust" );
var yIndex = gl.getUniformLocation( program, "yAdjust" );
var rIndex = gl.getUniformLocation( program, "red" );
var gIndex = gl.getUniformLocation( program, "green" );
var bIndex = gl.getUniformLocation( program, "blue" );
gl.uniform1f( xIndex, -0.25 ); // move to the left
gl.uniform1f( gIndex, 1.0 );
gl.clear( gl.COLOR_BUFFER_BIT ); // note new place to put clear
render();
gl.uniform1f( xIndex, +0.25 ); // move to the right
gl.uniform1f( rIndex, 1.0 );
render();
};
function render()
{
gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );
}
例如:我可以更改 gl.uniform1f(xIndex, ) 中的值以沿 x 轴移动矩形
是时候学习变换矩阵了。有很多数学,但我会尽量解释得尽可能简单。
让我们选择新方块 1x1:
var vertices =
[
vec2(0, 0),
vec2(1, 0),
vec2(0, 1),
vec2(1, 1)
];
现在,如果您想将它向左移动 1(就像您所做的那样),您需要将所有顶点的 [x] 添加 1。这个看起来很简单。 如果要旋转它,那就复杂多了。想象一下,您的对象将来自 50000 个顶点,而不仅仅是 4 个 => 超级复杂!
所以人们发明了一些被广泛使用的程序。我们为我们拥有的每个对象创建转换矩阵。在 2D 中,矩阵是 3x3。在 3D 中,矩阵是 4x4。
矩阵是如何工作的?首先创建顶点,然后使用
初始化矩阵// js example
var model1M = mat3.create([
1, 0, 0,
0, 1, 0,
0, 0, 1]);
这意味着 "no transformation done" 呢。然后通过矩阵操作平移、旋转、缩放对象。 记住,转换顺序很重要!!
move & rotate != rotate & move
一旦你想渲染,你发送矩阵到着色器。
// this is how you send 1 float value
gl.uniform1f( xIndex, -0.25 ); // move to the left
// this is how we send 3x3 matrix
var mvmi = gl.getUniformLocation( program, "modelViewMatrix" );
gl.uniformMatrix3fv(mvmi, false, model1M);
在着色器中:
// you have to modify what is in vec4
gl_Position = modelViewMatrix * vec4( position, 1.0 );
完成了。
问题是 mat3
在 js 中不存在。转换数学:
http://upload.wikimedia.org/wikipedia/commons/2/2c/2D_affine_transformation_matrix.svg
您需要先完成所有的数学运算。但更简单的是下载库,例如 http://glmatrix.net/ and include gl-matrix-min.js
. Then follow documentation http://glmatrix.net/docs/2.2.0/symbols/mat3.html .
简单的食谱:
var DEG_TO_RAD = 0.0174532925;
// create matrix, you dont have to type numbers in
var modelMatrix = mat3.create();
// move
mat3.translate(modelMatrix, modelMatrix, [-0.5, -0.5]);
// rotate by 45 degrees
mat3.rotate(modelMatrix, modelMatrix, 45*DEG_TO_RAD);
// make square smaller
mat3.scale(modelMatrix, modelMatrix, [0.4, 0.4]);