WebGL根据鼠标控制生成点位,随机改变点的大小颜色

c = a - b
在这里插入图片描述

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script>
        const canvas = document.getElementById('canvas')
        canvas.width = window.innerWidth
        canvas.height = window.innerHeight
        const gl = canvas.getContext('webgl')
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT); // 使用预设值来清空缓冲

        // 创建着色器
        const vertexShader = gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
        // 绑定数据源
        // 声明顶点着色器 attribute 变量
        // vec4是4维变量类型
        gl.shaderSource(vertexShader, `
            attribute vec4 a_Position;
            attribute float a_PositSize;
            void main(){
               gl_Position = a_Position;
               gl_PointSize = a_PositSize;
            }
        `)
        // 片元着色器变量 uniform, precision mediump float是片元着色器的规范
        gl.shaderSource(fragmentShader, `
        	precision mediump float;
        	uniform vec4 u_FragColor;
            void main(){
                gl_FragColor = u_FragColor;
            }
        `)
        // 编译着色器
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        // 创建着色器程序
        const program = gl.createProgram()
        // 绑定着色器
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        // 连接着色器
        gl.linkProgram(program)
        // 使用着色器
        gl.useProgram(program)

        const a_Position = gl.getAttribLocation(program, 'a_Position')
        const a_PositSize = gl.getAttribLocation(program, 'a_PositSize')
        const u_FragColor = gl.getUniformLocation(program, 'u_FragColor')

        const g_points = []; // 存点的位置,如果异步执行drawArrays会导致颜色缓冲区重置,所以在这里我们需要同步执行

        canvas.addEventListener('click', function (event) {
        	// 获取鼠标距离视口尺寸的距离
            const { clientX, clientY } = event
            // 获取cavans坐标宽高,距离视口尺寸的距离
            const { left, top, width, height } = canvas.getBoundingClientRect()
            // 鼠标在canvas中的位置
            const [cssX, cssY] = [clientX - left, clientY - top]
            
            // canvas坐标转webgl坐标
            // canvas画布的中心位置
            const [halfWidth, halfHeight] = [width / 2, height / 2]
            // 鼠标基于webgl坐标的中心位置
            const [xBaseCenter, yBaseCenter] = [cssX - halfWidth, cssY - halfHeight]
            // 解决y方向的差异
            const yBaseCenterTop = -yBaseCenter
            // 解决坐标基底的差异
            const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight]

			g_points.push({ x, y, z: Math.random() * 50, color: { r: Math.random(), g: Math.random(), b: Math.random(), a: 1 } });	// z随机改变点位的大小
            gl.clear(gl.COLOR_BUFFER_BIT); // 只有在绘制前清空缓冲区,才不会被drawArrays清空底色
            g_points.forEach(({ x, y, z, color: { r, g, b, a } }) => {
	            // gl.vertexAttrib[1234]f()可以为顶点 attibute 变量赋值, 数字代表参数位数,f代表参数类型浮点i整型v代表送数字等...
	            gl.vertexAttrib2f(a_Position, x, y)
	            gl.vertexAttrib1f(a_PositSize, z)
	            gl.uniform4f(u_FragColor, r, g, b, a)
	            gl.drawArrays(gl.POINTS, 0, 1)
            })
        })
    </script>
</body>

</html>

最近更新

  1. TCP协议是安全的吗?

    2024-04-04 00:50:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-04 00:50:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-04 00:50:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-04 00:50:01       20 阅读

热门阅读

  1. 蓝桥杯刷题--python-36

    2024-04-04 00:50:01       13 阅读
  2. how to Optimize mysql select clause

    2024-04-04 00:50:01       15 阅读
  3. flutter一个bloc可以对应多个state

    2024-04-04 00:50:01       15 阅读
  4. 讨论 OpenSIPS 预加载路由的问题

    2024-04-04 00:50:01       21 阅读
  5. 【电路笔记】-逻辑与门

    2024-04-04 00:50:01       20 阅读