headless-gl踩坑实录
headless-gl介绍
对于浏览器端canvas渲染,主要是WebGL调用底层OpenGL ES 2.0 API交互来实现图像渲染。不过不同浏览器或不同Android机型对WebGL支持不同,效果存在一定差异,为了统一图像渲染效果,需要在服务端进行渲染操作,通过搜索也可以查到业界常用的一些开源解决方案,如headless-gl,puppeteer。
headless-gl项目地址:https://github.com/stackgl/headless-gl
本文一部分是对headless-gl的README.md做一些汉化,一部分是记录使用中遇到的一些问题。headless-gl主要基于node.js开发,底层调用Open GL相关API实现,相当于使用js对底层逻辑进行再映射,有兴趣的可以查阅源码。
headless-gl使用
headless-gl 以 node.js 实现,所以安装方式如下:
npm install gl
声明十分简单,代码如下所示:
var width = 64
var height = 64
var gl = require('gl')(width, height, { preserveDrawingBuffer: true })
运行测试一下:
node app.js
由于webGL属于2D渲染,只涉及宽高输入,preserveDrawingBuffer代表保留缓冲区,为了后续图片导出使用。
其实和浏览器端使用类似,浏览器只是使用canvas进行获取。
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl');
其实获取到gl实例后,后面的操作就是和浏览器相同的了。一个通用例子如下:
const planeVertices = [-1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1];
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(planeVertices), gl.STATIC_DRAW);
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(
vertexShader,
`
顶点着色器实现代码。。
`
);
gl.compileShader(vertexShader);
const postprocessFragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(
postprocessFragShader,
`
片元着色器实现代码。。
`
);
gl.compileShader(postprocessFragShader);
const postprocessProgram = gl.createProgram();
gl.attachShader(postprocessProgram, vertexShader);
gl.attachShader(postprocessProgram, postprocessFragShader);
gl.linkProgram(postprocessProgram);
/**
* function 具体实现函数 细节不再展示
*/
function postprocess(Params... params) {
// do something...
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
对于上述代码来说,一方面要把前端参数通过postprocess传进来,一方面要通过glsl语言,自定义自己的着色器代码,最终导出图像。(PS:可以使用sharp库,操作简单功能强大)
headless-gl使用遇到的坑
总结下使用中遇到的坑:
- headless-gl支持扩展有限,有些是OpenGL原生扩展,有些是作者自定义的,支持如下几种:
- STACKGL_resize_drawingbuffer
- STACKGL_destroy_context
- ANGLE_instanced_arrays
- OES_element_index_uint
- OES_texture_float
- OES_texture_float_linear
- OES_vertex_array_object
- OES_standard_derivatives
- WEBGL_draw_buffers
- EXT_blend_minmax
- EXT_texture_filter_anisotropic
- 操作系统相关
如果是在无显卡服务器上使用的情况,建议不要在Centos 7 上使用该库,首先是node.js安装就十分麻烦,glibc版本太低,需要自行编译。其次是Centos 7 的mesa版本较低,对于一些OpenGL的扩展支持并不好,本文是在Debian 10 系统上成功实践。
如果有Centos 7实践成功的,可以在评论区分享经验。 - 函数相关
在向着色器传递参数时,数组可能不支持(uniform1fv函数),建议慎用,或者直接将数组定义在着色器中。