我用线段近似曲线:
for (i=1; i<=100; i=i+0.2)
{
arr = calculateCurve(i, 1, 1, 1, 1); //function returns an array of verticles
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
prevArr[0]/scale,
prevArr[1]/scale,
prevArr[2]/scale,
arr[0]/scale,
arr[1]/scale,
arr[2]/scale
]), gl.STATIC_DRAW);
gl.drawArrays(gl.LINES, 0, 2);
prevArr = arr;
}
我需要再次使用gl.drawArrays()来旋转曲线,因为在这种情况下性能非常慢。 我会创建一个包含100个顶点的巨大缓冲区,但我想知道是否可以通过更改顶点着色器中的旋转矩阵来重绘场景。
答案 0 :(得分:1)
创建“巨大”缓冲区不是问题,缓冲区的大小甚至达不到10kb(如果使用的绘制模式不同于LINE_STRIP
- > glDrawArrays
或{{1但是,多次调用Float32Array
是。
这里正确的方法是缓冲孔线。为此,生成一个glBufferData
,其大小可以容纳所有要渲染的浮点数。然后只拨打glDrawArrays
和glBufferData
一次。
如果你没有每帧更改一行,你也可以在第一次缓冲线后跳过nav{ position: absolute; width: 100%;left: 0;top: 0;}
。
答案 1 :(得分:0)
通过旋转曲线不太清楚你的意思。我看到至少有两种解释。一个是您希望曲线顶点位于相同的位置,但更改观察者位置,以便您以不同的角度查看相同的曲线。第二个是你想要每帧都有不同的曲线形状。
如果你想要的是1),那么你所要做的就是将一个矩阵作为统一发送到GPU并在顶点着色器中进行gl_Position = matrix * position
。这样做意味着您不必每帧都重新生成曲线上的顶点位置。
如果你想要的是2),那么你需要提出一些数学来计算顶点着色器中曲线上每个点的位置。如何做到这一点非常依赖于案例,我认为您需要显示更多关于如何计算曲线上位置的代码。
答案 2 :(得分:0)
您可以通过将它们乘以旋转矩阵来旋转WebGL中的顶点。
例如,此代码将生成一个在Z轴上旋转顶点的矩阵。
function rotationZ(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
}
这是一个有效的例子:
function rotationZ(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
}
// Using TWGL (twgljs.org) to keep the code small
var gl = document.getElementById("c").getContext("webgl");
// compiles shader, links and looks up locations
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
// make some curve points
points = [];
for (var i = 0; i < 100; ++i) {
var a = i / 100 * Math.PI * 2;
var r = 0.5;
points.push(
Math.sin(Math.sin(a * 2.)) * r ,
Math.cos(a) * r);
}
var arrays = {
position: { numComponents: 2, data: points, },
};
// calls gl.createBuffer, gl.bindBuffer, gl.bufferData for each array
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
function render(time) {
var uniforms = {
u_matrix: rotationZ(time * 0.001),
};
gl.useProgram(programInfo.program);
// calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
// calls gl.uniformXXX, gl.activeTexture, gl.bindTexture
twgl.setUniforms(programInfo, uniforms);
// calls gl.drawArray or gl.drawElements
twgl.drawBufferInfo(gl, bufferInfo, gl.LINE_LOOP);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
canvas { border: 1px solid blue; }
<!--
note! I'm using a square canvas so I don't have to deal with aspect
which would complicate the example
See the articles linked in the answer for details about aspect
-->
<canvas id="c" width="150" height="150"></canvas>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script id="vs" type="notjs">
attribute vec4 position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * position;
}
</script>
<script id="fs" type="notjs">
precision mediump float;
void main() {
gl_FragColor = vec4(0,0,0,1);
}
</script>
This article explains how rotation works及其后面的文章将转换为使用矩阵。