webGL小白眼瞎边缘 SOS

guyu
  • 3
新手上路,请多包涵

webGL小白最近开始跟着webGL编程指南学习,但是在绘制3个顶点颜色不同的三角形这部分一直无法生效;已经自查了很多很多次,而且电子书里的示例代码也无法正常运行;
麻烦路过的大佬瞅一眼,救救孩子眼睛要瞎了

附上我的垃圾代码供各位检查:

html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body onload="main()">
    <canvas id="mutiAttributeColor" width="400px" height="400px">
        please try modern browser that supports canvas
    </canvas>
</body>
<script src="./static/js/mutiAttributeColor.js"></script>
</html>

js文件:

/**
 * 定义顶点着色器
 */
const VSHADER_SOURCE = `
 attribute vec4 a_Position;
 attribute vec4 a_Color;
 varying vec4 v_Color;
 void main() {
     gl_Position = a_Position;
     gl_PointSize = 10.0;
     v_Color = a_Color;
 }`;
/**
 * 定义片元着色器
 */
const FSHADER_SOURCE = `
 varying vec4 v_Color;
 void main() {
     gl_FragColor = v_Color;
 }`;

/**
 * 主函数
 */
function main() {
    // 获取画布
    const canvas = document.getElementById('mutiAttributeColor');
    // 获取三维上下文
    const gl = canvas.getContext('webgl');
    // 编译着色器
    const vertShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertShader, VSHADER_SOURCE);
    gl.compileShader(vertShader);

    const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragShader, FSHADER_SOURCE);
    gl.compileShader(fragShader);
    // 合并程序
    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertShader);
    gl.attachShader(shaderProgram, fragShader);
    gl.linkProgram(shaderProgram);
    gl.useProgram(shaderProgram);
    // 初始化缓冲区对象
    const n = initBuffers(gl, shaderProgram);
    // 设置背景色
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    // 清空画布
    gl.clear(gl.COLOR_BUFFER_BIT);
    // 绘制图形
    gl.drawArrays(gl.POINTS, 0, n);
}
/**
 * 初始化缓冲区对象
 * @param {*} gl 三维上下文
 * @param {*} shaderProgram 着色器程序 
 */
function initBuffers(gl, shaderProgram) {
    // 指定绘制图形的顶点坐标,顶点尺寸
    const verticesColors = new Float32Array([
        0.0, 0.5, 1.0, 0.0, 0.0,
        -0.5, -0.5, 0.0, 1.0, 0.0,
        0.5, -0.5, 0.0, 0.0, 1.0,
    ]);
    // 指定绘制图形顶点个数
    const n = 3;
    // 步骤1:创建缓冲区对象
    const vertexColorBuffer = gl.createBuffer();
    // 步骤2:将缓冲区对象绑定到目标上
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
    // 步骤3:将数据写入缓冲区对象中
    gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

    const FSIZE = verticesColors.BYTES_PER_ELEMENT;

    // 步骤4:将缓冲区对象分配给对应的attribute变量
    // 步骤5:开启attribute变量
    
    // 获取坐标点
    const a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);
    gl.enableVertexAttribArray(a_Position);

    // 获取颜色
    const a_Color = gl.getAttribLocation(shaderProgram, 'a_Color');
    gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);
    gl.enableVertexAttribArray(a_Color);

    return n;
}
回复
阅读 463
1 个回答

在webgl中除了片元着色器的浮点类型(float)没有默认精度,其他类型浏览器都有默认精度;所以需要在片元着色器中加上精度限定precision lowp float;

声明变量精度高低的三个关键子lowpmediumphighp

完整代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body onload="main()">
    <canvas id="mutiAttributeColor" width="400px" height="400px">
        please try modern browser that supports canvas
    </canvas>

    <script>
        /**
         * 定义顶点着色器
         */
        const VSHADER_SOURCE = `
            attribute vec4 a_Position;
            attribute vec4 a_Color;
            varying vec4 v_Color;
            void main() {
                gl_Position = a_Position;
                gl_PointSize = 10.0;
                v_Color = a_Color;
            }
         `;
        /**
         * 定义片元着色器
         */
        const FSHADER_SOURCE = `
        precision lowp float;// 注意此处需要精度限定词
            varying vec4 v_Color;
            void main() {
                gl_FragColor = v_Color;
            }
        `;

    
        /**
         * 主函数
         */
        function main() {
            // 获取画布
            const canvas = document.getElementById('mutiAttributeColor');
            // 获取三维上下文
            const gl = canvas.getContext('webgl');
            // 编译着色器
            const vertShader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(vertShader, VSHADER_SOURCE);
            gl.compileShader(vertShader);

            const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(fragShader, FSHADER_SOURCE);
            gl.compileShader(fragShader);
            // 合并程序
            const shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertShader);
            gl.attachShader(shaderProgram, fragShader);

            gl.linkProgram(shaderProgram);
            

            gl.useProgram(shaderProgram);
            
            // 初始化缓冲区对象
            const n = initBuffers(gl, shaderProgram);
            // 设置背景色
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            // 清空画布
            gl.clear(gl.COLOR_BUFFER_BIT);
            // 绘制图形
            gl.drawArrays(gl.POINTS, 0, n);
        }
        /**
         * 初始化缓冲区对象
         * @param {*} gl 三维上下文
         * @param {*} shaderProgram 着色器程序 
         */
        function initBuffers(gl, shaderProgram) {
            // 指定绘制图形的顶点坐标,顶点尺寸
            const verticesColors = new Float32Array([
                0.0, 0.5, 1.0, 0.0, 0.0,
                -0.5, -0.5, 0.0, 1.0, 0.0,
                0.5, -0.5, 0.0, 0.0, 1.0,
            ]);
            // 指定绘制图形顶点个数
            const n = 3;
            // 步骤1:创建缓冲区对象
            const vertexColorBuffer = gl.createBuffer();
            // 步骤2:将缓冲区对象绑定到目标上
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
            // 步骤3:将数据写入缓冲区对象中
            gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

            const FSIZE = verticesColors.BYTES_PER_ELEMENT;

            // 步骤4:将缓冲区对象分配给对应的attribute变量
            // 步骤5:开启attribute变量

            // 获取坐标点
            const a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);
            gl.enableVertexAttribArray(a_Position);

            // 获取颜色
            const a_Color = gl.getAttribLocation(shaderProgram, 'a_Color');
            gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);
            gl.enableVertexAttribArray(a_Color);

            return n;
        }
    </script>

</body>

</html>
宣传栏