webGl shader的学习记录(四):如何与人互动绘制多个三角形。

赖绪
2023-12-01

 正在这一章节中我们将会学习到如何使用鼠标创造多个三角形,从而实现互动

 老规矩首先我们需要先处理一下顶点着色器与片元着色器

    let vertexShaderSource = `
       //设置浮点数精度为中等精度
        precision mediump float;
        // 接收顶点坐标 (x, y)
        attribute vec2 a_Position;
        // 接收 canvas 的尺寸(width, height)
        attribute vec2 a_Screen_Size;
        void main(){
            vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;
            position = position * vec2(1.0,-1.0);
            gl_Position = vec4(position, 0, 1);
        }
    `;
    //片元着色器
    let fragmentShaderSource =`
        precision mediump float;
        uniform vec4 u_Color;
        void main(){
            vec4 color = u_Color/vec4(255,255,255,1);
            gl_FragColor = color;
        }
    `

如果你并不太理解上面的内容是什么意思的话,可以去看这一章,你会大概的明白是什么意思

下面就是老生常谈的代码了,创建出来顶点着色器然后是片元着色器

我有任务了 先去工作了,做完了再回来写

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<canvas id="canvas"></canvas>
<script>
    let vertexShaderSource = `
       //设置浮点数精度为中等精度
        precision mediump float;
        // 接收顶点坐标 (x, y)
        attribute vec2 a_Position;
        // 接收 canvas 的尺寸(width, height)
        attribute vec2 a_Screen_Size;
        void main(){
            vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;
            position = position * vec2(1.0,-1.0);
            gl_Position = vec4(position, 0, 1);
        }
    `;
    //片元着色器
    let fragmentShaderSource =`
        precision mediump float;
        uniform vec4 u_Color;
        void main(){
            vec4 color = u_Color/vec4(255,255,255,1);
            gl_FragColor = color;
        }
    `

    let canvas = document.getElementById('canvas');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    let gl = canvas.getContext('webgl');

    //编写程序三角形的程序
    //--编写顶点着色器
    let vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader,vertexShaderSource);
    gl.compileShader(vertexShader);
    //编写片元着色器
    let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader,fragmentShaderSource);
    gl.compileShader(fragmentShader);
    //创建着色器程序
    let program = gl.createProgram();
    gl.attachShader(program,vertexShader);
    gl.attachShader(program,fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);
    //创建三角形使用的相关程序
    var positions = [1,0, 0,1, 0,0];//先默认的设置三个顶点 两两一对
    let buffer = gl.createBuffer();//创建一个缓冲区
    gl.bindBuffer(gl.ARRAY_BUFFER,buffer);//将上面的缓冲区设置为当前使用的缓冲区
    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(positions),gl.STATIC_DRAW);//将我们使用的数据,放入到缓冲区中
    //上面我们已经将需要使用的数据放进了 缓存区中了
    //下面我们处理的是 读取之前放进去的缓存区中的数据
    let a_Position = gl.getAttribLocation(program,'a_Position');
    //我们需要告诉 WebGL 如何从之前创建的缓冲区中获取数据,并且传递给顶点着色器中的 a_Position 属性
    gl.enableVertexAttribArray(a_Position);

    //每次取两个数据
    let size = 2;
    //每个数据的类型是32位浮点型
    let type = gl.FLOAT;
    //不需要归一化数据
    let normalize = false;
    // 每次迭代运行需要移动数据数 * 每个数据所占内存 到下一个数据开始点。
    let stride = 0;
    // 从缓冲起始位置开始读取
    let offset = 0;
    // 将 a_Position 变量获取数据的缓冲区指向当前绑定的 buffer。
    gl.vertexAttribPointer(a_Position, size, type, normalize, stride, offset)

    //处理片元着色器
    let u_Color = gl.getUniformLocation(program,'u_Color');//取到片元着色器的变量
    gl.uniform4f(u_Color,this.randomColor().r,this.randomColor().g,this.randomColor().b,this.randomColor().a);//设置颜色
    //处理顶点着色器中的变量
    let a_Screen_Size = gl.getAttribLocation(program,'a_Screen_Size');//取到屏幕的大小
    gl.vertexAttrib2f(a_Screen_Size,canvas.width,canvas.height);//设置参数
    this.render(gl); //屏幕清空
    //设置点击事件
    canvas.addEventListener('mouseup', e => {
        var x = e.pageX;
        var y = e.pageY;
        positions.push(x, y);
        if (positions.length % 6 == 0) {
            //向缓冲区中复制新的顶点数据。
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.DYNAMIC_DRAW);
            //重新渲染
            this.render(gl);
        }
    })
    //渲染函数
    function render(gl) {
        gl.clearColor(0, 0, 0, 1.0);
        //用上一步设置的清空画布颜色清空画布。
        gl.clear(gl.COLOR_BUFFER_BIT);
        //绘制图元设置为三角形
        var primitiveType = gl.TRIANGLES;
        //从顶点数组的开始位置取顶点数据
        var drawOffset = 0;
        //因为我们要绘制 N 个点,所以执行 N 次顶点绘制操作。
        gl.drawArrays(primitiveType, 0, positions.length / 2);
        console.log('画布设置成功');
    }

    //随机取到相关的颜色
    function randomColor() {
        return {
            r: Math.random() * 255,
            g: Math.random() * 255,
            b: Math.random() * 255,
            a: Math.random() * 1
        };
    }


</script>

</body>
</html>

 

 类似资料: