如何在 WebGL 中绘制两个由顶点着色的三角形?
How can I draw two triangles colored by vertex in WebGL?
我正在尝试解决一个示例问题,该问题要求我绘制两个不同的三角形,每个三角形按顶点着色,如下所示:
我快到了,但似乎有什么不对劲。这是我的结果:
问题是,左边的三角形是我想要的样子:三种颜色,RGB,每个顶点一种。我不知道第二个是怎么得到这些颜色的。我的意图是在其中两个中使用相同的颜色向量 - 尽管如果有人告诉我如何使用两个不同的颜色向量 fColor
我会很感激,这样我就可以为它们中的每一个定义不同的颜色。我不知道直角三角形是如何得到这些颜色的。它们甚至不是我为左边定义的同一组颜色。这是进入 HTML:
的着色器代码
<script id="vertex-shader" type="x-shader/x-vertex">
# version 300 es
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;
void main()
{
fColor = vColor;
gl_Position = vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
# version 300 es
precision mediump float;
in vec4 fColor;
out vec4 fragColor;
void main()
{
fragColor = fColor;
}
</script>
这里是 javascript:
window.onload = function init()
{
var canvas = document.getElementById( "gl-canvas" );
gl = canvas.getContext('webgl2');
if (!gl) { alert( "WebGL 2.0 isn't available" ); }
//
// Initialize our data for a single triangle
//
// First, initialize the three points.
var vertices = [vec3(-1,-1,0),
vec3(-0.5, 1, 0),
vec3(0, -1, 0),
vec3(0,-1,0),
vec3(0.5, 1, 0),
vec3(1,-1,0)];
var colors = [vec3(1,0,0), vec3(0,1,0), vec3(0,0,1)];
//
// Configure WebGL
//
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
// Load shaders and initialize attribute buffers
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
// Load the data into the GPU
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Associate out shader variables with our data buffer
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var cBufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
var vColor = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vColor);
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Redefine buffer for the vertices and colors
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vColor);
gl.drawArrays(gl.TRIANGLES,3,3);
};
很抱歉代码部分太长了,但我是 GLSL 的新手(javascript/html),我不知道错误在哪里,所以我发布了整个代码。
gl.vertexAttribPointer
指定一个顶点属性数组。它还将当前绑定到 ARRAY_BUFFER
目标的缓冲区与属性相关联。因此,在指定顶点属性时需要确保绑定了正确的缓冲区对象:
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
// [...]
gl.vertexAttribPointer( vPosition, 3, gl.FLOAT, false, 0, 0 ); // bufferId is currently bound
// [...]
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
// [...]
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 ); // cBufferId is currently bound
// [...]
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
// [...]
// bufferId is currently bound
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId); // therfore you have to bind cBufferId
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
// [...]
但是,由于要绘制3到6的顶点,还必须指定3到6的颜色属性:
var colors = [vec3(0,1,0), vec3(1,0,0), vec3(0,1,0),
vec3(0,0,1), vec3(1,0,0), vec3(0,0,1)];
指定 1 个顶点缓冲区和 1 个颜色缓冲区
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Associate out shader variables with our data buffer
var vPosition = gl.getAttribLocation( program, "vPosition");
gl.vertexAttribPointer(vPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray( vPosition );
var cBufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
var vColor = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer(vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vColor);
分别画出两个三角形:
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.drawArrays(gl.TRIANGLES, 3, 6);
或立即
gl.drawArrays(gl.TRIANGLES, 0, 6);
我正在尝试解决一个示例问题,该问题要求我绘制两个不同的三角形,每个三角形按顶点着色,如下所示:
我快到了,但似乎有什么不对劲。这是我的结果:
问题是,左边的三角形是我想要的样子:三种颜色,RGB,每个顶点一种。我不知道第二个是怎么得到这些颜色的。我的意图是在其中两个中使用相同的颜色向量 - 尽管如果有人告诉我如何使用两个不同的颜色向量 fColor
我会很感激,这样我就可以为它们中的每一个定义不同的颜色。我不知道直角三角形是如何得到这些颜色的。它们甚至不是我为左边定义的同一组颜色。这是进入 HTML:
<script id="vertex-shader" type="x-shader/x-vertex">
# version 300 es
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;
void main()
{
fColor = vColor;
gl_Position = vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
# version 300 es
precision mediump float;
in vec4 fColor;
out vec4 fragColor;
void main()
{
fragColor = fColor;
}
</script>
这里是 javascript:
window.onload = function init()
{
var canvas = document.getElementById( "gl-canvas" );
gl = canvas.getContext('webgl2');
if (!gl) { alert( "WebGL 2.0 isn't available" ); }
//
// Initialize our data for a single triangle
//
// First, initialize the three points.
var vertices = [vec3(-1,-1,0),
vec3(-0.5, 1, 0),
vec3(0, -1, 0),
vec3(0,-1,0),
vec3(0.5, 1, 0),
vec3(1,-1,0)];
var colors = [vec3(1,0,0), vec3(0,1,0), vec3(0,0,1)];
//
// Configure WebGL
//
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
// Load shaders and initialize attribute buffers
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
// Load the data into the GPU
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Associate out shader variables with our data buffer
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var cBufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
var vColor = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vColor);
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Redefine buffer for the vertices and colors
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vColor);
gl.drawArrays(gl.TRIANGLES,3,3);
};
很抱歉代码部分太长了,但我是 GLSL 的新手(javascript/html),我不知道错误在哪里,所以我发布了整个代码。
gl.vertexAttribPointer
指定一个顶点属性数组。它还将当前绑定到 ARRAY_BUFFER
目标的缓冲区与属性相关联。因此,在指定顶点属性时需要确保绑定了正确的缓冲区对象:
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
// [...]
gl.vertexAttribPointer( vPosition, 3, gl.FLOAT, false, 0, 0 ); // bufferId is currently bound
// [...]
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
// [...]
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 ); // cBufferId is currently bound
// [...]
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
// [...]
// bufferId is currently bound
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId); // therfore you have to bind cBufferId
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
// [...]
但是,由于要绘制3到6的顶点,还必须指定3到6的颜色属性:
var colors = [vec3(0,1,0), vec3(1,0,0), vec3(0,1,0),
vec3(0,0,1), vec3(1,0,0), vec3(0,0,1)];
指定 1 个顶点缓冲区和 1 个颜色缓冲区
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Associate out shader variables with our data buffer
var vPosition = gl.getAttribLocation( program, "vPosition");
gl.vertexAttribPointer(vPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray( vPosition );
var cBufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
var vColor = gl.getAttribLocation(program, "vColor");
gl.vertexAttribPointer(vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vColor);
分别画出两个三角形:
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.drawArrays(gl.TRIANGLES, 3, 6);
或立即
gl.drawArrays(gl.TRIANGLES, 0, 6);