我的目标是为着色器顶点内的顶点指定自定义位置,而不是依赖 JavaScript“new Float32Array(positions)”来定义顶点位置。数据应表示一个简单的三角形。此外,我的目标是确保顶点按照预期精确定位,以实现所需的视觉结果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL Example</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
window.onload = function() {
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');
const shaderSource = {
vertex: `
uniform vec2 screenSize; // Screen size uniform
void main(void) {
// Define combined vertices
vec3 vertices[3];
vertices[0] = vec3(0.0, 1.0, 0.0);
vertices[1] = vec3(-1.0, -1.0, 0.0);
vertices[2] = vec3(1.0, -1.0, 0.0);
// Adjust vertices based on screen size
for (int i = 0; i < 3; i++) {
vertices[i].x *= screenSize.x / screenSize.y; // Adjust x coordinate based on aspect ratio
}
// Create another vec3 to store the vertices
vec3 finalPosition = vec3(0.0);
// Add the selected vertex to finalPosition
finalPosition vec3(vertices[0],vertices[1],vertices[2]);
// Calculate final position
gl_Position = vec4(finalPosition, 1.0);
}
`,
fragment: `
void main(void) {
gl_FragColor = vec4(0, 0.8, 0, 1);
}
`
};
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, shaderSource.vertex);
gl.compileShader(vertShader);
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, shaderSource.fragment);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
// Clear the canvas
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw the triangle
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
</script>
</body>
</html>
解决方案是使用 gl_VertexID 它根据您想要设置的 numverts 创建一个虚拟点。 gl_VertexID 将从 0 - numverts 开始,并且需要一些数学公式来计算您想要的形状。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL Triangle</title>
<canvas id="c"></canvas>
<script src="https://webgl2fundamentals.org/webgl/resources/webgl-utils.js"></script>
<script>
// WebGL2 - No Data - Point Circle
// from https://webgl2fundamentals.org/webgl/webgl-no-data-point-circle.html
'use strict';
const gl = document.querySelector('#c').getContext('webgl2');
const vs = `#version 300 es
uniform int numVerts;
uniform vec2 resolution;
#define PI radians(180.0)
void main() {
float u = float(gl_VertexID) / float(numVerts); // goes from 0 to 1
// Define the vertices of the triangle
vec2 vertex1 = vec2(0.0, 0.0); // Define the coordinates of the first vertex
vec2 vertex2 = vec2(0.0, 2.0); // Define the coordinates of the second vertex
vec2 vertex3 = vec2(1.0, -0.7); // Define the coordinates of the third vertex
// Interpolate between the vertices to get the position of the current point
vec2 pos = mix(mix(vertex1, vertex2, u), vertex3, u);
//float angle = u * PI * 2.0; // goes from 0 to 2PI
//float radius = 0.2;
//vec2 pos = vec2(cos(angle), sin(angle)) * radius;
gl_Position = vec4(pos, 0, 1);
gl_PointSize = 10.0;
}
`;
const fs = `#version 300 es
precision highp float;
out vec4 outColor;
void main() {
outColor = vec4(0, 0, 1, 1);
}
`;
// setup GLSL program
const program = webglUtils.createProgramFromSources(gl, [vs, fs]);
const numVertsLoc = gl.getUniformLocation(program, 'numVerts');
const resolutionLoc = gl.getUniformLocation(program, 'resolution');
const numVerts = 3;
// draw
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.useProgram(program);
// tell the shader the number of verts
gl.uniform1i(numVertsLoc, numVerts);
// tell the shader the resolution
gl.uniform2f(resolutionLoc, gl.canvas.width, gl.canvas.height);
const offset = 0;
gl.drawArrays(gl.TRIANGLES, offset, numVerts);
</script>
</head>
<body>
<canvas id="c" width="400" height="400"></canvas>
<script src="webgl-utils.js"></script>
</body>
</html>