大家好,大家都叫我西瓜。因为想转职写游戏,而游戏中会让人第一个想到、也是能在第一瞬间吸引人的就是画面了,笔者从事网站开发多年,也就顺势从 WebGL 开始学习,这系列文章将以做出范例的方式,跟大家分享这几个月学习的心得
这系列文章假设读者能够看懂 Javascript,并且对於 Web 技术有基础的了解
简单来说,WebGL 是一组在 Web 上操作 GPU 的 Javascript API,而 WebGL 绝大部分的 API 都可以找到 openGL 上对应的版本,且名字几乎没有差别,猜测制定 WebGL 标准时只打算做一层薄薄的包装,这样一方面浏览器可能比较好实做,但是也因此 WebGL 直接使用时是非常底层的,甚至偶尔会需要去算线性代数、矩阵的东西
看到这边读者们可能会想说:哇,我要来把 Tab 关掉了,洗洗睡。老实说,如果对於基础原理没有兴趣,想要『快速』做出东西,这边确实可以左转 three.js 或是 babylon.js,笔者是基於下面这个因素决定学习 WebGL 的:
当你了解其原理时,比较不容易受到框架、潮流演进的影响
为什麽?在了解原理的状况下,比较能知道框架帮你做了什麽,遇到变化比较大的需求的时候可能比较容易想到方法应对;前端技术更迭速度大家都知道,但是基础原理是不会有太大的变化的;最後,透过 WebGL 学到的原理多多少少也能应用在其他平台上吧
笔者近期学习 WebGL 所使用的资源主要是 WebGL2 Fundamentals,这个网站上的教学写的非常完整,从基础一路到各个功能的实做,因此本次铁人赛系列文章所提及的概念或多或少会与这个网站重叠,有兴趣的读者不妨交互参考看看;同时,如果有大大发现文章内容有误,欢迎使用我的网站这边的联络方式联络我改正,感谢!
要制作范例,我们会需要编辑器,任何纯文字编辑器皆可,接着透过浏览器执行网页,理论上最新版 Chrome, Firefox, Edge 以及 Safari 都可以,WebGL 在这些浏览器都可以使用,笔者将使用 Chrome 示范;除此之外,我们需要一种方法让浏览器读取我们写的网页,这边可以使用任何静态网页服务器,例如:
http-server
会开启网页服务器,以当前的工作目录当成网站根目录,预设把 port 开在 8080
,可以透过 http://localhost:8080
打开网站,同时具有检视资料夹的功能ruby -run -ehttpd . -p8000
: ruby 内建的网页服务器,与 http-server
类似,执行後 commandline 当前的工作目录当成网站根目录,-p8000
意思是 port 开在 8000
,可以透过 http://localhost:8000
打开网站python3 -m http.server
/ python -m SimpleHTTPServer
: python 内建的网页服务器,预设把 port 开在 8000
,可以透过 http://localhost:8000
打开网站准备好开发用网页服务器,就可以来建立第一个范例的 HTML 档案: 01-hello-webgl.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01-hello-webgl</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="module" src="01-hello-webgl.js"></script>
</body>
</html>
这边可以看到有一个 <canvas id="canvas"></canvas>
,这就是 WebGL 操作的『画布』,WebGL 绘制的东西将透过这个元素呈现,另外 <script type="module" src="01-hello-webgl.js"></script>
以 ES Module 的形式引入我们主要要写的 Javascript: 01-hello-webgl.js
console.log('hello')
先这样就好,使用浏览器透过网站服务器打开 01-hello-webgl.html
,并且按下 F12 或是右键检视元件开启开发者工具,接着应该可以在 Console 看到 hello
表示一切正常:
为了确保之後对原始码的更动在浏览器重整时使用更动後的版本,建议切换至 Network tab 关闭快取,以 Chrome 为例:
要取得 WebGL instance,我们透过 <canvas />
JS DOM API 的 .getContext()
并且传入 'webgl'
来取得,像是这样:
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
window.gl = gl;
第一行透过 id 取得元素,取得 gl
之後也设定到 window.gl
上方便在开发工具 Console 中玩转:
另一个常见的绘制 API 为 CanvasRenderingContext2D,这时要传入的字串就变成
'2d'
:.getContext('2d')
,在之後绘制文字的时候会需要这边的帮忙
老实说,我们距离绘制一些有意义的东西还有点遥远,不过倒是可以先找个颜色填满(事实上是清除)画面让第一天有点东西
首先要透过 gl.clearColor(red, green, blue, alpha)
设定清除用的颜色,这边 red, green, blue, alpha 是介於 0 - 1 之间的浮点数,设定好之後,gl.clear(gl.COLOR_BUFFER_BIT)
进行清除,而 gl.COLOR_BUFFER_BIT
是用来指定清除颜色的部份,以笔者的主题色 #6bde99
/ rgb(108 225 153)
为例,大概像是这样:
gl.clearColor(108/255, 225/255, 153/255, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
虽然只是拿油漆工具填满整张画布,但是第一天至少让画面有点东西了,画面上的绿色区块就是 <canvas>
,因为我们没有设定长宽,在 Chrome 上预设的大小是 300x150
光是从 gl.clearColor
/ gl.clear
这两个就可以感受到 WebGL 是来自另外一个世界的 API,在 GPU 这边许多东西都是介於 0 到 1 之间的浮点数,而 gl.COLOR_BUFFER_BIT
更是体现跟底层沟通用的 bit flag
本篇的完整程序码可以在这边找到:
明天开始来绘制 GL 最常见的基本元素:三角形,并介绍绘制的基本流程
日子来到了第二天,我们先去 tableau public 的官网看看吧! 注册帐号跟下载程序这两件事...
资料来源: [HITCON年会] 亲爱的,问题不一定是骇客造成的 保密防谍、人人有责 骇客语录 ...
-ISO 31000 该问题的核心概念是如何定性或定量地分析风险,以确定风险敞口,以货币价值,得分...
以往工作的经历,身边工程师对测试的认识 对於目前撰写程序的开发员来说,「测试」一词大多是不会感到陌生...
接续我们在昨天所阐述的设计流程, 接着来看看这些设计流程是如何在实际运作的Action上被实践的。 ...