gl-render
v1.1.1
Published
Lightweight WebGL Renderer with ESM/IIFE support (global variable: glrender) — preserves native WebGL workflow, optimizes performance via caching, and supports TypeScript type safety.
Maintainers
Readme
gl-render
轻量级 WebGL 渲染器封装库,保留原生 WebGL 工作流的同时,通过缓存与状态管理优化性能。支持两种集成格式,适配不同开发场景:
- ESM 格式(适用于 Vue/React/TypeScript 等模块化项目):采用「命名导出」避免全局变量污染,符合现代构建工具规范。
- IIFE 格式(适用于浏览器直接引入的原生项目):暴露全局命名空间
glrender,核心类挂载于glrender.WebGLRenderer下(而非直接暴露为glrender),减少与其他库的命名冲突风险。
特性
- ✅ 双格式兼容:
- ESM:通过命名导出(
import { WebGLRenderer })集成,无全局污染,适配 Vite/Webpack 等构建工具。 - IIFE:全局命名空间
glrender包裹核心类,实例化需用new glrender.WebGLRenderer(...),结构清晰易维护。
- ESM:通过命名导出(
- ✅ 性能优化:
- 状态缓存:自动缓存着色器、程序、缓冲区,避免重复编译/绑定操作。
- 高 DPI 适配:默认开启
autoDPI,解决 Retina 屏幕画面模糊问题。 - 窗口 resize 节流:默认 100ms 节流间隔,避免高频尺寸变化导致性能损耗。
- ✅ 类型安全:完整 TypeScript 类型定义(如
WebGLRendererParameters接口),支持 IDE 智能提示,减少类型错误。 - ✅ 原生 WebGL 兼容:暴露原始
gl上下文,可直接调用gl.drawArrays、gl.createTexture等原生 API,灵活度无损耗。 - ✅ 轻量无依赖:压缩后体积 < 10KB(gzip 后),无第三方依赖,不增加项目体积负担。
安装
1. npm 安装(ESM/TypeScript 项目)
适用于模块化开发场景,通过包名 gl-render 安装:
npm install gl-render --save2. CDN 引入(IIFE 原生项目)
适用于无需构建工具的原生 HTML 项目,引入后通过全局命名空间 glrender 访问核心类:
<!-- IIFE 格式:全局命名空间 = glrender,核心类 = glrender.WebGLRenderer -->
<script src="https://unpkg.com/gl-render@latest/dist/index.global.js"></script>快速开始
场景 1:ESM + TypeScript(推荐)
通过「命名导出」导入核心类,类型提示完整,适配现代模块化项目:
// 关键:使用命名导出(非默认导出),需通过解构导入
import { WebGLRenderer } from 'gl-render';
// 1. 初始化渲染器(配置参数可选,默认值见 API 文档)
const renderer = new WebGLRenderer({
antialias: true, // 开启抗锯齿(移动端建议关闭以节省性能)
backgroundColor: '#111',// 背景色(十六进制,支持 #rgb 或 #rrggbb 格式)
autoDPI: true // 自动适配高 DPI 屏幕(解决 Retina 模糊)
});
// 2. 设置渲染尺寸并将 canvas 加入 DOM
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 3. 获取原生 WebGL 上下文(可选,用于执行原生操作)
const gl = renderer.gl;
if (!gl) throw new Error('您的浏览器不支持 WebGL,请升级浏览器');
// 4. 编译顶点/片段着色器(自动缓存,相同源码仅编译一次)
const vertexShader = renderer.compileShader(gl.VERTEX_SHADER, `
attribute vec3 aPosition;
void main() {
gl_Position = vec4(aPosition, 1.0); // 简化示例:直接使用顶点坐标
}
`);
const fragmentShader = renderer.compileShader(gl.FRAGMENT_SHADER, `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.3, 0.3, 1.0); // 红色填充色
}
`);
// 5. 创建着色器程序(自动缓存 uniform/attribute 位置,避免重复查询)
const program = renderer.createProgram(vertexShader, fragmentShader);
if (!program) throw new Error('着色器程序创建失败,请检查源码');
renderer.useProgram(program); // 激活程序
// 6. 定义三角形几何数据(原生 WebGL 缓冲区操作)
const vertices = new Float32Array([
0, 1, 0, // 上顶点
-1, -1, 0, // 左下顶点
1, -1, 0 // 右下顶点
]);
const buffer = gl.createBuffer();
renderer.bindBuffer(gl.ARRAY_BUFFER, buffer); // 缓存当前缓冲区,避免重复绑定
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 7. 配置顶点属性(从程序缓存中获取 attribute 位置,无需重复调用 getAttribLocation)
const aPosition = program.attributes.get('aPosition');
if (aPosition !== undefined && aPosition !== -1) {
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
}
// 8. 启动渲染循环(返回暂停函数,需时可调用停止)
const stopRenderLoop = renderer.startRenderLoop(() => {
gl.clear(gl.COLOR_BUFFER_BIT); // 清除背景
gl.drawArrays(gl.TRIANGLES, 0, 3); // 绘制三角形
});
// 9. 监听窗口尺寸变化(自动更新渲染尺寸,带 100ms 节流)
const removeResizeListener = renderer.onWindowResize((width, height) => {
console.log(`窗口尺寸更新为:${width}x${height}`);
});
// 10. 页面卸载时清理资源(避免内存泄漏)
window.addEventListener('unload', () => {
stopRenderLoop(); // 停止渲染循环
removeResizeListener(); // 移除窗口监听
renderer.dispose(); // 释放 WebGL 资源(着色器、程序、canvas)
});场景 2:IIFE 原生 HTML 项目
通过全局命名空间 glrender 访问核心类,无需构建工具,直接在浏览器中运行:
<!DOCTYPE html>
<html>
<head>
<title>gl-render IIFE 示例</title>
<style>
body { margin: 0; background: #000; }
#info {
position: fixed; top: 10px; left: 10px;
color: #0f0; font-family: monospace;
}
</style>
<!-- 引入 IIFE 文件:全局命名空间 = glrender -->
<script src="https://unpkg.com/gl-render@latest/dist/index.global.js"></script>
</head>
<body>
<div id="info">
包名:gl-render | 全局类:glrender.WebGLRenderer | 红色三角形示例
</div>
<script>
// ❗ 关键:实例化需通过 glrender.WebGLRenderer(非 new glrender())
const renderer = new glrender.WebGLRenderer({
antialias: true,
backgroundColor: '#111'
});
// 2. 设置尺寸并加入 DOM
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 3. 获取原生 WebGL 上下文
const gl = renderer.gl;
if (!gl) {
alert('您的浏览器不支持 WebGL,请升级浏览器');
throw new Error('WebGL 上下文初始化失败');
}
// 4. 编译着色器(逻辑与 ESM 场景完全一致)
const vertexShader = renderer.compileShader(gl.VERTEX_SHADER, `
attribute vec3 aPosition;
void main() { gl_Position = vec4(aPosition, 1.0); }
`);
const fragmentShader = renderer.compileShader(gl.FRAGMENT_SHADER, `
precision mediump float;
void main() { gl_FragColor = vec4(1.0, 0.3, 0.3, 1.0); }
`);
// 5. 创建并激活程序
const program = renderer.createProgram(vertexShader, fragmentShader);
if (!program) throw new Error('着色器程序创建失败');
renderer.useProgram(program);
// 6. 绑定几何数据并绘制
const vertices = new Float32Array([0,1,0, -1,-1,0, 1,-1,0]);
const buffer = gl.createBuffer();
renderer.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const aPosition = program.attributes.get('aPosition');
if (aPosition !== undefined && aPosition !== -1) {
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
}
// 7. 启动渲染循环
renderer.startRenderLoop(() => {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
});
</script>
</body>
</html>API 文档
1. 导出实体说明
| 格式 | 导出实体 | 描述 | 使用示例 |
|------------|-----------------------------------|----------------------------------------------------------------------|-------------------------------------------|
| ESM | WebGLRenderer(类) | 核心渲染器类,通过「命名导出」提供。 | import { WebGLRenderer } from 'gl-render' |
| ESM | WebGLRendererParameters(接口) | 构造函数配置参数的 TypeScript 类型定义,用于类型提示。 | import type { WebGLRendererParameters } from 'gl-render' |
| IIFE | window.glrender(命名空间) | IIFE 格式暴露的全局命名空间,包含所有导出内容。 | glrender.WebGLRenderer |
| IIFE | glrender.WebGLRenderer(类) | 核心渲染器类,挂载于全局命名空间下。 | new glrender.WebGLRenderer({ ... }) |
2. 构造函数参数(WebGLRendererParameters)
| 参数名 | 类型 | 默认值 | 描述 |
|----------------------|---------|--------------|----------------------------------------------------------------------|
| antialias | boolean | false | 是否开启抗锯齿(以性能换平滑边缘,移动端建议关闭) |
| backgroundColor | string | '#000000' | 画布背景色(十六进制字符串,支持 #f00 简写或 #ff0000 完整格式) |
| alpha | number | 1 | 背景透明度(0 = 完全透明,1 = 不透明,需配合 backgroundColor 使用) |
| preserveDrawingBuffer | boolean | false | 是否保留绘制缓冲区(用于 canvas.toDataURL() 截图,开启会禁用部分浏览器优化) |
| autoDPI | boolean | true | 是否自动适配高 DPI 屏幕(解决 Retina 屏幕画面模糊问题) |
3. 核心属性(只读)
| 属性名 | 类型 | 描述 |
|----------------|-----------------------|----------------------------------------------------------------------|
| domElement | HTMLCanvasElement | 渲染器对应的 canvas 元素(需手动加入 DOM 才能显示) |
| gl | WebGLRenderingContext | 原生 WebGL 上下文,可直接调用原生 API 执行底层操作 |
| width | number | 逻辑渲染宽度(单位:CSS 像素,与画布显示尺寸一致) |
| height | number | 逻辑渲染高度(单位:CSS 像素,与画布显示尺寸一致) |
| pixelRatio | number | 设备像素比(可读写,修改后会自动更新画布实际像素尺寸,默认取 window.devicePixelRatio) |
4. 核心方法
setSize(width: number, height: number, updateStyle?: boolean)
- 功能:同步渲染器的「逻辑尺寸」(CSS 像素)与「实际像素尺寸」(画布物理像素)。
- 参数:
width/height:逻辑宽度/高度(CSS 像素,即画布显示尺寸)。updateStyle:是否同步更新 canvas 的 CSS 样式(默认true,确保显示尺寸与逻辑尺寸一致)。
compileShader(type: GLenum, source: string): WebGLShader | null
- 功能:编译 GLSL 着色器源码,自动缓存编译结果(相同源码仅编译一次)。
- 返回值:编译成功返回
WebGLShader对象,失败返回null(错误信息会打印到控制台)。
createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram | null
- 功能:将顶点着色器与片段着色器链接为可执行的着色器程序,并自动缓存
uniform和attribute的位置(存储于program.uniforms和program.attributes两个 Map 中)。 - 返回值:链接成功返回
WebGLProgram对象,失败返回null(错误信息会打印到控制台)。
useProgram(program: WebGLProgram | null)
- 功能:激活指定的着色器程序,内部会缓存当前激活的程序,避免重复调用
gl.useProgram导致的状态切换开销。
bindBuffer(target: GLenum, buffer: WebGLBuffer | null)
- 功能:将缓冲区绑定到指定的 WebGL 目标(如
gl.ARRAY_BUFFER),内部会缓存当前绑定的缓冲区,避免重复绑定。
startRenderLoop(renderFn: () => void): () => void
- 功能:启动基于
requestAnimationFrame的渲染循环(默认 60fps),每帧执行传入的renderFn回调。 - 返回值:暂停渲染循环的函数(调用该函数即可停止渲染)。
onWindowResize(callback: (width: number, height: number) => void, throttle?: number): () => void
- 功能:监听窗口尺寸变化,自动更新渲染器尺寸,并触发自定义回调(默认 100ms 节流,避免高频触发)。
- 参数:
callback:尺寸变化后的回调函数,接收新的逻辑宽度和高度。throttle:节流时间间隔(默认 100ms,单位:毫秒)。
- 返回值:移除窗口监听的函数(页面卸载时调用,避免内存泄漏)。
dispose()
- 功能:彻底释放所有 WebGL 资源(着色器、程序、缓冲区、canvas 引用),调用后渲染器不可再使用(适用于单页应用路由切换等场景)。 n
