仅传递三角形边的长度是否足以在 WebGL 中绘制三角形?

Is passing just the length of the sides of a triangle, sufficient to draw a triangle in WebGL?

问题可能不清楚,但我会在这里解决。让我们考虑一个数组,它在 clip space :

中有一个三角形的坐标
 var coor = [ 
   -0.4, 0.6, 
    0.0, -0.5, 
   -0.5, 0.0,  
    0.5, -0.5, 
    0.0 
 ]

所以,coor 数组将帮助我们使用 WebGL 绘制三角形。但是我不想这样做,而是想这样做:

var coor2 = [ 100, 100, 100 ]

在coor2中我给出了边长来画一个三角形。这将是一个等边三角形。那么,我可以做一些事情,比如我输入三角形的三个边,然后脚本将它们转换为坐标,坐标可以被剪辑在剪辑 space 中,并且可以被 WebGL 读取吗?

提前致谢

WebGL 只关心您设置 gl_Position 以裁剪 space 值。它不关心你是怎么做到的。由您决定如何操作。在顶点着色器内部,至少在 WebGL1 中,事物是无状态的。这意味着当您绘制三角形时,您的顶点着色器将被调用 3 次。它需要在 clipspace 中将 gl_Position 设置为 3 个不同的值,调用之间没有状态。那么给定 100 三次,你将如何在每次调用顶点着色器时计算一个 不同的 值?

想象一下 JavaScript

const gl_Position1 = vertexShader(100);
const gl_Position2 = vertexShader(100);
const gl_Position3 = vertexShader(100);

函数 vertexShader 如何在没有其他输入的情况下产生 3 个不同的值?除非有其他状态,否则它不能产生不同的值。 WebGL1 中的顶点着色器没有任何其他状态。

您需要传入一些每次迭代都会更改的数据。

当然,如果值发生变化,则可以生成一个三角形。例子

function vertexShader(v) {
  const angle = v / 3 * Math.PI * 2;
  return [Math.cos(angle), Math.sin(angle), 0, 1];
}

const gl_Position1 = vertexShader(0);
const gl_Position2 = vertexShader(1);
const gl_Position3 = vertexShader(2);

会产生一个三角形。将其转换为 GLSL 和 WebGL

const gl = document.querySelector('canvas').getContext('webgl');

const vs = `
attribute float v;

#define PI radians(180.0)

void main() {
  float angle = v / 3.0 * PI * 2.0;
  gl_Position = vec4(cos(angle), sin(angle), 0, 1);
}
`;

const fs = `
precision mediump float;
void main() {
  gl_FragColor = vec4(1, 0, 0, 1);
}
`;

const program = twgl.createProgram(gl, [vs, fs]);
const vLocation = gl.getAttribLocation(program, 'v');

const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 1, 2]), gl.STATIC_DRAW);

gl.enableVertexAttribArray(vLocation);
gl.vertexAttribPointer(vLocation, 1, gl.FLOAT, false, 0, 0);

gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

当然,鉴于我们只传入了 [0, 1, 2],我们不能轻易地指定一个位置,但关键是至少现在我们有了一个可以改变的值,我们可以生成一个三角形,它只是重新迭代 WebGL 只关心您设置 gl_Position 以裁剪 space 值。它不在乎你怎么做。

有关更多信息,请参阅 this article