一堆废话的前言
2024年五一过后,在掘金上无意看到 alphardex的一篇文章,# SU7,启动!尝试还原了 SU7 网页的炫酷特效,实现的效果真的很炫酷,了解了一个新的名词shader。
在这之前,对webgl并没有深入学习,用过canvas,但是不多。对3D更是不了解,仅仅知道一丢丢关于vtk和一些医疗影像的处理和使用。但这也是在已经封装的基础上去用。
顺着shader这个词,在掘金上找到了大神古柳,一系列手把手带你入门shader,整体看下来,觉得shader魅力四射。但是在使用shader上,不仅仅需要创造力,还需要一些知识基础。
跟着古柳大佬的教程指导,找到了b站up主进华的threejs的入门课程,跟着课程,一步步的了解threejs。但是这个系列看完后(断断续续花了两个多星期),发现要用shader还是需要去了解一些数学几何知识,webgl还是得学。
由于本人除了上班的时间,几乎都在家里带娃,晚上娃睡了,刷刷小视频,就到了深夜。的确是很颓,很废.
初代的90后大姨(特指八青妹),已经被碾压在了沙滩上。但是内心对可视化还是很向往的。最大的动力和野心就是,下次幼儿园家长开放日的时候,想在幼儿们面前秀一波。
第一步:安装插件
就像上学前先买书包和笔一样,那用vscode来写webgl需要准备点啥呢? 哎,等等,不是先讲原理之类的吗?不好意思,八青妹讲不好,可看寒璃讲解的,很棒!也是八青妹学习的偶像大佬。
学习webgl就少不了编写shader程序,shader程序使用GLSL(OpenGL Shading Language)编写。 例如在vertexShader.js中的代码如下:
let vertexShader =`
attribute vec3 a_position;
void main() {
gl_Position = vec4(a_position, 1.0);
}
`
export default vertexShader;
在backtick内容区域的代码是无高亮的,这怎么能忍?
在vscode编辑器中安装插件comment-tagged-templates,在vertexShader.js里面添加注释/*glsl*/
let vertexShader = /*glsl*/`
attribute vec3 a_position;
void main() {
gl_Position = vec4(a_position, 1.0);
}
`
export default vertexShader;
但是重启后代码块并没有高亮显示。
原因很简单,没有安装glsl语言的插件库!安装插件库GLSL Syntax for VS Code,这样comment-tagged-templates读取/*glsl*/注释后,就能按照GLSL Syntax for VS Code的高亮规则来进行高亮了。
第二步:将基础的代码块分文件区分
准备四个js文件,一个做主要展示的app.js,一个是vertexShader.js,一个是fragmentShader.js,一个是initShaders.js。
当然还要准备一个html! 绘制一个底色为蓝色的400x400画布,画一个红点。
该案例为最简单的webgl案例了。其中有如何将顶点着色器和片元着色器进行关联之类的等等,我也不是很明白,所以建议,后面都用封装好的。只需要更改着色器里面的内容,而如何关联的用函数封装下吧。
也就是上述代码片段中Create Shaders和Create Program进行整合下
export default function initShaders(gl, vertexSource, fragmentSource) {
}
/**
* Create Shades
*/
function createShader(gl, type, source) {
}
/**
* Create Program
*/
function createProgram(gl, vertexShader, fragmentShader) {
let program = gl.createProgram()
if (!program) return null
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
// link prgram result
let linked = gl.getProgramParameter(program, gl.LINK_STATUS)
if (linked) {
return program
} else {
let error = gl.getProgramInfoLog(program)
console.log('link program error: ' + error)
gl.deleteProgram(program)
gl.deleteShader(vertexShader)
gl.deleteShader(fragmentShader)
return null
}
}
在原来的js中引入上述js文件
import initShaders from './initShaders.js'
let canvas = document.getElementById('webgl')
let gl = canvas.getContext('webgl')
// vertexShader, fragmentShader
let vertexShader = `
void main() {
gl_Position = vec4(0.0, 0.5, 0.0, 1.0);
gl_PointSize = 10.0;
}
`
let fragmentShader = `
void main() {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
`
initShaders(gl, vertexShader, fragmentShader)
// 清空canvas画布
gl.clearColor(0.5, 0.5, 0.5, 1.0) // rgba()
gl.clear(gl.COLOR_BUFFER_BIT)
// 画一个点
gl.drawArrays(gl.POINTS, 0, 1)