生成专属于你的人工智能书【3D生成器】
生成这么一本 3D 的书籍,涉及3维引擎、图案生成、文字排版等内容。本文选取了 A-frame 作为3维引擎,图案生成及文字排版部分使用原生的 canvas 操作。完成此项目的要求具备设计能力及代码能力。
https://aframe.io/
1
A-frame 的使用指南
a-frame 是基于 threejs 的 web AR 库,也可以当 threejs 的简化版本使用,a-frame 只需写 html 标签就可以实现3维空间的操作,非常适合快速新手上手。下面介绍几个本文使用到的知识点。
1.1 vr-mode-ui组件
仅适用于 <a-scene> 元素,控制是否显示进入 VR 模式的 UI 。这边我们关闭下,代码:
<a-scene vr-mode-ui="enabled: false" ></a-scene>
1.2 相机相关的设置
camera 组件
fov 视野角越大,场景中的物体越小;
fov 视野角越小,场景中的物体越大。
look-controls 组件
添加上去可以触屏移动摄像机视角。
position 组件
在 position 里设置相机的位置,例如:
<a-entity position="0 1.6 0" camera="fov:45" look-controls></a-entity>
1.3 坐标系
注意 position 组件里的坐标写法与对应的空间关系,这块建议多调整坐标试验几次熟悉。
<a-sphere position="1 1.25 -6" radius="1.25" color="#EF2D5E"></a-sphere>
完整的示例代码,更多请参考官方api文档:
<html>
<head>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false" >
<a-entity position="0 1.6 0" camera="fov:45" look-controls></a-entity>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" ></a-box>
<a-sphere position="1 1.25 -6" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>
中场休息下♨️
2
书籍封面生成
此部分采用的是 canvas 的原生开发,通过 canvas 生成图案,后导出 base64 作为模型的贴图。
需要先定义几个函数:
书名生成 getTitle
书籍难度生成 getLevel
配色生成 getColors
此处采用的逻辑都是随机从库里数据(随机是最好的方法),例如配色的生成代码:
function getColors() {
var colors = [["#240041", "#900048"],["#1C1124", "#684656"],["#394A51", "#7FA99B"],["#22559C", "#F27370"],["#FF6D24", "#4E413B"],["#F0CA6D", '#F7F2C1'],["#A13939", "#E75151"],["#657DC4","#838ED9"],["#461B93","#6A3CBC"],["#4A3333","#98D083"],["#AD1457","#F06292"],["#18587A","#FC624D"]];
var index = Math.abs(Math.ceil(Math.random() * colors.length - 1));
return colors[index];
};
介绍下背景图的生成逻辑:
1 根据封面的尺寸,等分,生成网格;
2 随机生成几个六边形或五边形;
3 计算生成的六边形及五边形按照正态分布随机摆放的位置及大小。
4 微调六边形及五边形的位置,避让文字内容。
5 生成背景图
比较重要的算法就是按照正态分布产生随机数的算法,代码:
function mathNormal(x, mu, sigma) {
mu = mu || 0;sigma = sigma || 1;
var res = (1 / (Math.sqrt(2 * Math.PI) * sigma)) * (Math.exp(-Math.pow(x - mu, 2) / (2 * Math.pow(sigma, 2))));
return res;
};
function randomStandardNormal() {
var isTarget = false,res;
while (!isTarget) {
var a = randomRange(-1, 1);
var b = randomRange(0, 1);
if (b <= mathNormal(a)) {
isTarget = true;res = [a, b];
};
};
return res;};