原文链接: webgl 贝塞尔多彩线
上一篇: webrtc 全屏截图
下一篇: webgl 彩色点大小颜色变化的随机飞舞
有点摸清门道了, 不过webgl不能绘制大于1px的线, 需要自己使用矩形模拟
https://stackoverflow.com/questions/28009734/webgl-line-strip-width
precision mediump float;
varying vec4 outVsColor;
void main() {
gl_FragColor = outVsColor;
}
// attribute vec3 aVsPosition;
// uniform vec4 uVsColor;
// void main(){
// // gl_Position = vec4(aVsPosition, 1);
// }
attribute vec4 aVsPosition;
attribute vec4 aVsColor;
varying vec4 outVsColor;
void main(){
gl_Position = aVsPosition;
outVsColor = aVsColor;
}
<template>
<div class="flex-row">
<div>gl003 贝塞尔曲线</div>
<canvas id="gl"></canvas>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from "vue";
import { initShaderProgram, clearGL } from "../common";
import { randomColor } from "../../../utils";
import fsSouce from "./fs.glsl";
import vsSource from "./vs.glsl";
import { Bezier } from "bezier-js";
const b = new Bezier(100, 25, 10, 90, -100, 90, 200, 200);
const size = 100;
const pointerList = Array(size + 1)
.fill(0)
.map((_, k) => {
const p = b.get(k / size); // {x,y,t}
return [(p.x - 100) / 200, (p.y - 100) / 200, 0];
})
.flat();
const width = 800;
const height = 800;
onMounted(() => {
const canvas = document.getElementById("gl")! as HTMLCanvasElement;
canvas.width = width;
canvas.height = height;
const gl = canvas.getContext("webgl2", {
alpha: true,
depth: true,
antialias: true,
})!;
clearGL(gl, width, height, [1, 0, 0, 1]);
const shaderProgram = initShaderProgram(gl, vsSource, fsSouce);
console.log("shaderProgram", shaderProgram);
gl.useProgram(shaderProgram);
const programInfo = {
program: shaderProgram,
attribLocations: {
aVsPosition: gl.getAttribLocation(shaderProgram, "aVsPosition"),
aVsColor: gl.getAttribLocation(shaderProgram, "aVsColor"),
// vertexColor: gl.getAttribLocation(shaderProgram, "aVertexColor"),
},
uniformLocations: {
uFsColor: gl.getUniformLocation(shaderProgram, "uFsColor"),
uVsColor: gl.getUniformLocation(shaderProgram, "uVsColor"),
modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"),
},
};
const points = new Float32Array(pointerList);
// console.log("colors", colors);
// 创建缓冲区
const vertexBuffer = gl.createBuffer();
// 绑定缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
// 分配缓冲区至指定着色器变量地址
gl.vertexAttribPointer(
programInfo.attribLocations.aVsPosition,
3,
gl.FLOAT,
false,
0,
0
);
// 连接地址
gl.enableVertexAttribArray(programInfo.attribLocations.aVsPosition);
const colors = new Float32Array(
Array(pointerList.length / 3)
.fill(0)
.map(() => randomColor(true))
.flat()
);
// console.log("colors", colors);
// 创建缓冲区
const colorBuffer = gl.createBuffer();
// 绑定缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
// 向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
// 分配缓冲区至指定着色器变量地址
gl.vertexAttribPointer(
programInfo.attribLocations.aVsColor,
4,
gl.FLOAT,
false,
0,
0
);
// 连接地址
gl.enableVertexAttribArray(programInfo.attribLocations.aVsColor);
// gl.uniform4fv(programInfo.uniformLocations.uFsColor, [0.0, 1.0, 1.0, 1.0]);
// 设置颜色缓冲区清空颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// 由于dx不支持线宽设置 https://stackoverflow.com/questions/28009734/webgl-line-strip-width
// gl.lineWidth(2);
// 需要使用矩形代替
gl.drawArrays(gl.LINE_STRIP, 0, pointerList.length / 3);
console.log("programInfo", programInfo);
});
</script>
<style></style>