找回密码
 立即注册
首页 业界区 业界 W.js ,一个超级小的三维 WebGL 引擎的使用方法 ...

W.js ,一个超级小的三维 WebGL 引擎的使用方法

利怡悦 7 天前
目录

  • 前言
  • 它的特点
  • API
  • 入门使用
  • 内置模型
  • 导入自己的模型
  • 动画
  • 自定义投影矩阵
  • 摄像机与主角绑定
  • 解除绑定

前言

我们知道,在网页上搞三维,three.js 和 babylon.js 都是成熟最佳的选择,可是有时候它们体积又显得太大了。
我以前有研究过各种网页三维引擎,体积都挺大。我为什么要找体积小的呢?因为我对计算机图形学懂得不多,体积小让我有对它运行方式的探索欲。
我曾经找过一个最小的 https://github.com/wakufactory/wwg ,这个只有不到 10 kb 大小,但感觉有点太底层了。
后来我又找到了这个, https://github.com/xem/W/ ,它的官网是 https://xem.github.io/W/  ,这个显然做的用心多了,因为它是为极致小体积的JS游戏提供三维解决方案而设计,所以语法非常精妙,玩了一会儿,感觉很有意思。今天我就来分享一下它的使用(它官网上写的教程文档太简短了...)。
阅读它的源代码,可能需要一些 WebGL 的知识,大家可以在 https://www.cnblogs.com/duyuanshang/p/18791113 这里简单入门 ~
它的特点

它可以引入 3D 模型(OBJ 格式),上色纹理透明度也可以调,而且还可以搞灯光!总共体积只有个位数 KB 大小。
动画、索引等也支持。还不错。极致迷你版的 three.js ,不过仓库有两年没有维护过了,我真想好好的将其源码研究透,并继续迭代优化更强大和实用的功能。
它的特性是「微小」,这是它的关键特性。作者 xem 说:“我开发 W 的主要目标是针对大小受限的游戏马拉松(例如 js13kgames.com)”。
API

在官网只列出了以下几个 API,不过我觉得很够用了!把最复杂的 Webgl 里的操作封装起来,怎么都要比类似于计算器只提供加减按键要好。
  1. // 初始化框架
  2. W.reset(canvasElement);
  3. // 设置清屏颜色(默认为"#fff")
  4. W.clearColor("#rgb");
  5. // 设置相机
  6. // 参数:位置(x,y,z),旋转角度(rx,ry,rz),视野(fov)
  7. W.camera({x, y, z, rx, ry, rz, fov});
  8. // 设置光源方向
  9. W.light({x, y, z});
  10. // 设置环境光强度(0到1之间)
  11. W.ambient(f);
  12. // 创建对象组:名称,位置,旋转
  13. W.group({n, x, y, z, rx, ry, rz});
  14. // 绘制内置3D对象
  15. // 参数:所属组,名称,尺寸,位置,旋转,背景,纹理,平滑度...
  16. let settings = {g, n, size, x, y, z, rx, ry, rz, b, t, mix, s, ns, mode};
  17. W.plane(settings); // 平面
  18. W.billboard(settings); // 公告板
  19. W.cube(settings); // 立方体
  20. W.pyramid(settings); // 金字塔
  21. W.sphere(settings); // 球体
  22. // 添加并绘制自定义3D模型(见下方OBJ文件加载器)
  23. W.add("custom_model", { vertices, uv, indices });
  24. W.custom_model(settings);
  25. // 移动/缩放组或对象:名称,位置,旋转,动画效果,延迟(毫秒)
  26. W.move({n, size, x, y, z, rx, ry, rz, a}, delay);
  27. // 也可以使用M参数设置自定义变换矩阵
  28. W.move({n, M}, delay);
  29. // 移动相机/光源:参数设置,动画效果,延迟
  30. W.camera({x, y, z, rx, ry, rz, a}, delay);
  31. W.light({x, y, z, a}, delay);
  32. // 删除元素:名称,延迟
  33. W.delete(n, delay);
复制代码
入门使用

下面是一个最极简的使用:
(可以试试在 https://img1.ccgxk.com/htmleditor/index.html 这个页面调试代码)
  1. [/code][indent]我将它的核心库 w.js ,传到了我的 CDN 上:
  2. 带注释版: https://img1.ccgxk.com/wjs/w.js (23.8 kB) ,
  3. 压缩版: https://img1.ccgxk.com/wjs/min/w.min.js (9.9kb),大家感兴趣可以下载
  4. [/indent]效果如下:
  5. [align=center] 1.png [/align]
  6. 三个立方体被搞成了长方体,三个金字塔体,外加一个像摄像机一样的组合(一个正方体和一个金字塔体)。
  7. [code]W.light({x:0,y:-1,z:0});  // 环境光的方向
  8. W.ambient(0.22);  // 环境光的强度
  9. W.clearColor("#FFFFFF");  // 背景颜色(白色)
复制代码
如果向 js 后面追加以上的代码,还可以设置环境光的方向、强度,以及背景颜色。这便是入门了!
内置模型

这个迷你的库里,甚至内置了五种最常用的模型:

  • W.plane :一个平面
  • W.billboard :一个始终对着摄像头的平面
  • W.cube :立方体
  • W.pyramid  :金字塔
  • W.sphere :球
这样写,就是设置一个模型了:
  1. W.cube({x:5,w:10, h:.5,d:.5,b:"f44"});
复制代码
内部的属性是这样解释的:
名称:

  • n 就是 name ,名称
  • g 就是所属的 group 组合名
大小:

  • w h d 设置宽度、高度、纵深,默认 1
  • size 就是将 w 和 h  d 设置成一样的值,默认 1
位置:

  • x y z 是位置,默认 0 0 0
  • rx ry rz 是旋转,默认 0 0 0
  • M:自定义变换矩阵(Array(16),替换 x, y, z, rx, ry, rz)
纹理:

  • b 是背景颜色,是一个 #rgb 颜色,默认 #888 (井号 # 可以省略)
  • t 是背景纹理,一个存在于 DOM 中的 IMG、CANVAS 或 VIDEO 元素
  • mix 是混合纹理,要求同时设置了背景颜色 b 和背景纹理 t,然后混合。0 代表完全纹理, 1 代表完全颜色
渲染:

  • s 是平滑着色,默认为 false。这个需要完整版的库。
  • mode 绘图方式,是 webgl 里的内容,这里默认是 TRIANGLES,常用的有 LINE_LOOP 线框...
  • ns: 默认情况下,形状将根据方向光进行着色,但可以通过此"无着色"选项禁用
这五个形状就在这里了:
  1. [/code][align=center] 2.png [/align]
  2. [size=5]导入自己的模型[/size]
  3. W 导入自己的模型很简单,第一步是将 OBJ 信息导入,第二步直接配置即可,如下所示,我把一个立方体搞了进去。
  4. [code]
复制代码
那个 OBJ 模型呢,常用的三种数据为:
  1. W.add("model", {vertices: [...], uv: [...], indices: [...]});
复制代码

  • vertices : 这个必须要有,是顶点数据
  • uv:这个可选,是 uv 纹理坐标数组,如果你有纹理的话
  • indices:如果模型使用索引缓冲区,这个就是索引数组
注意,默认采用的配置属性里,是应用的平面着色,而不是光溜溜的平滑着色。
这个网址 https://xem.github.io/W/obj2js/   是一个工具,用于将 OBJ 文件转换为 W 自定义模型,同时也可以缩减一下体积之类的。
由于该网址国内访问受限,我制作了个中文版,传到我的 CDN 里: https://img1.ccgxk.com/wjs/obj2js/index.html
动画

这个是最好玩的!
  1. [/code]W.move({}) 这个函数可以移动我们指定名称的物体,它的移动效果。
  2. 上面有两个参数,一个是 a:1000,一个是 3000,前者这个 a 如果不定义,则没有那种过渡的动画效果,也就是直接就变化了... 后面的 3000 则是动画延时,以毫秒为计。写多少,就多少毫秒后执行!
  3. 当然,不止如此,W.camera({}) 和 W.light({}) 可以直接移动摄像机和灯光:
  4. [code]
复制代码
自定义投影矩阵

默认的投影方式是视角投影,大概意思是近小远大,符合人眼。
W.js 支持自定义投影,我们在里面可以导入我们的投影矩阵。
比如正交投影,物体无论远近,大小都看起来一样。
  1. <canvas id=c5 width=320 height=340></canvas>
  2. <label><input type=radio name=p id=p1 checked>视角投影(默认)</label>
  3. <label><input type=radio name=p id=p2>正交投影(自定义)</label>
复制代码
在这个例子中,右下角有个单选框,可以切换投影方式:
视角投影:
3.png

正交投影:
4.png

当然,这个启用方式是手动启用的。我发现直接写到代码里,好像不怎么管用...
摄像机与主角绑定

根据官网的例子,我做了下精简:
  1. <canvas id=c width=320 height=300></canvas>
  2. <table >
  3. <tr>
  4. <td colspan=2>
  5. <button id=u>前</button>
  6. <tr>
  7. <td>
  8. <button id=l>左</button>
  9. <td>
  10. <button id=r>右</button>
  11. <tr>
  12. <td colspan=2>
  13. <button id=d>后</button>
  14. </table>
复制代码

按下前后左右,摄像机会随着球而运动。这是因为下面这两行代码将两者绑定到了一起:
  1. W.sphere({n:"M",size:1,y:-.9,z:18,rx:-90,ry:0, b:"ccc",s:1});
  2. W.camera({g:"M",z:.5,y:-2.5,rx:90});  // 摄像机,此时它的 g 属性为主角 sphere 的 n 属性,摄像机与主角绑定
复制代码
顺便一提,W 库里面是无法访问当前某元素的坐标情况的,所以需要我们使用第三方的变量来记录。
解除绑定

为了更便于理解,这次搞的是一个「<button id="headBodySeparation">头身分离</button>」的动作。
将下面的代码追加入上一小节的代码:
  1. <button id="headBodySeparation">头身分离</button>
复制代码
6.png

移动到合适的位置后,我们单击这个「<button id="headBodySeparation">头身分离</button>」的按键,这样「头」就和「身体」解除绑定了!摄像机也一样,我们感兴趣可以尝试一下!
7.png

至此,10kb 大小的 W.js 这个三维引擎 JS 库的主要学习内容就完成了。(当然,还有个 自定义变换矩阵 的知识点,不过看起来用处不大就不说了)

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册