<canvas id="canvas">canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_Position;
attribute float a_PointSize;
void main() {
// 点位
gl_Position = a_Position;
// 尺寸
gl_PointSize = a_PointSize;
}
script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main(){
gl_FragColor = vec4(1,1,0,1);
}
script>
<script type="module">
// 这里的 utils.js 参考之前博文,不做重复阐述
import { initShaders } from "./utils.js";
const canvas = document.querySelector("#canvas");
canvas.width = 200;
canvas.height = 200;
// 获取着色器文本
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
// 三维画笔
const gl = canvas.getContext("webgl");
// 初始化着色器
initShaders(gl, vsSource, fsSource);
// 在 js 中 获取 attribute 变量
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
const a_PointSize = gl.getAttribLocation(gl.program, "a_PointSize");
// 存储顶点数据的数组
const a_points = [
{ x: 0, y: 0, size: 10 },
];
render();
// 渲染方法
function render() {
gl.clearColor(0, 0, 0, 1); // 声明颜色 rgba
gl.clear(gl.COLOR_BUFFER_BIT); // 刷底色
a_points.forEach(({ x, y, size }) => {
gl.vertexAttrib2f(a_Position, x, y);
gl.vertexAttrib1f(a_PointSize, size); // 这里修改尺寸大小
gl.drawArrays(gl.POINTS, 0, 1);
});
}
// 鼠标点击事件
canvas.addEventListener("click", ({ clientX, clientY }) => {
const { left, top, width, height } = canvas.getBoundingClientRect();
const [cssX, cssY] = [clientX - left, clientY - top];
// 解决坐标原点位置的差异
const [halfWidth, halfHeight] = [width / 2, height / 2];
const [xBaseCenter, yBaseCenter] = [
cssX - halfWidth,
cssY - halfHeight,
];
// 解决y方向的差异
const yBaseCenterTop = -yBaseCenter;
// 解决坐标基底的差异
const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight];
const size = Math.random() * 50 + 10;
a_points.push({ x, y, size });
render();
});
script>
1 )在片元着色器脚本中定义相关代码
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_FragColor;
void main() {
gl_FragColor = u_FragColor;
}
script>
2 )在js中获取片元着色器暴露出的uniform变量
<script type="module">
const u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor'); // 关键代码
script>
3 )修改uniform 变量
// 设置随机颜色
const color = new Float32Array([
Math.random(),
Math.random(),
Math.random(),
1.0
]);
gl.uniform4fv(u_FragColor, color); // 在合适的地方进行修改:render方法中的 arr.forEach 循环中处理
gl.uniform4f(u_FragColor,1.0,1.0,0.0,1.0);
//等同于
const color=new Float32Array([1.0,1.0,0.0,1.0]);
gl.uniform4fv(u_FragColor,color);