WebGL 在顶点着色器中定位顶点?

问题描述 投票:0回答:1

我的目标是为着色器顶点内的顶点指定自定义位置,而不是依赖 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>
javascript position webgl vertex-shader vertex
1个回答
0
投票

解决方案是使用 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>

© www.soinside.com 2019 - 2024. All rights reserved.