复刻掘金健康生活的3D宣传图

image.png

很熟悉吧,经常逛掘金的童鞋们,一定见过这张图咯,今天我们就用前端技术还原出里面部分的3d模型的,首先我们分析一下里面的元素

分析

image.png

除了基础的场景,背景布,灯光,还有一些文字,贴图和各种材质,我们一步一步的做,一个一个元素的往里加

布景
背景布

image.png

颜色使用吸管工具大致取一下,不过会受到灯光的影响

``` js // 创建背景布 function initGround () { const geometry = new THREE.PlaneGeometry(80, 80, 1, 1); const material = new THREE.MeshLambertMaterial({ color: 0x5abe64, // 画布颜色 side: THREE.DoubleSide // 双面可见 }); const plane = new THREE.Mesh(geometry, material); plane.receiveShadow = true // 是否接受阴影 return plane }

const plan = initGround() plan.rotation.x = -0.5 * Math.PI scene.add(plan) ```

第一个元素

image.png

白色材质的一个倒圆角的立方体,制作立方体,首先要有顶点信息,有了顶点之后,再连线,通过线条,进行挤压,最终形成一个立方体,带着这个思路,我们首先要做一下顶点

image.png

需要8个连接点,还有所有的圆角顶点,圆角顶点所使用的是 椭圆曲线 EllipseCurve 四个椭圆曲线顺序链接就可以形成一个闭环的圆角矩形,说干就干

因为大部分都是这种圆角矩形的结构,所以获取圆角矩形的顶点信息写一个公共的方法getpoint

``` js

/* * Perform an A Search on a graph given a start and end node. * @param {R} radius * @param {L} length * @param {S} subsection * @return {points} points */ function getPoint (R, L, S) { const curve1 = new THREE.EllipseCurve( L, L, // ax, aY R, R, // xRadius, yRadius 0, 0.5 * Math.PI, // aStartAngle, aEndAngle false, // aClockwise 0 // aRotation ); const curve2 = new THREE.EllipseCurve( -L, L, // ax, aY R, R, // xRadius, yRadius 0, 0.5 * Math.PI, // aStartAngle, aEndAngle false, // aClockwise 0.5 * Math.PI // aRotation ); const curve3 = new THREE.EllipseCurve( -L, -L, // ax, aY R, R, // xRadius, yRadius 0, 0.5 * Math.PI, // aStartAngle, aEndAngle false, // aClockwise Math.PI // aRotation ); const curve4 = new THREE.EllipseCurve( L, -L, // ax, aY R, R, // xRadius, yRadius 0, 0.5 * Math.PI, // aStartAngle, aEndAngle false, // aClockwise -0.5 * Math.PI // aRotation );

// 创建组合曲线对象CurvePath var CurvePath = new THREE.CurvePath(); // 把多个线条有顺序的插入到CurvePath中 CurvePath.curves.push(curve1, curve2, curve3, curve4); //分段数S var points = CurvePath.getPoints(S); return points } ```

image.png

最终导出的是一组二维坐标 vector2

将这组二维坐标通过lineloop的api进行线的渲染,看一下效果

js var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices geometry.setFromPoints(points); console.log(points) //材质对象 var material = new THREE.LineBasicMaterial({ color: 0x000000 }); //线条模型对象 var line = new THREE.LineLoop(geometry, material); scene.add(line); //线条对象添加到场景中

image.png

现在了顶点,形成了线条,那么下面就将顶点使用挤压缓冲几何体(ExtrudeGeometry)进行挤压,形成一个真正的圆角矩形立方体,

```js

/* * Perform an A Search on a graph given a start and end node. * @param {points} 顶点信息vector2 * @param {option} 挤压的参数 * @param {option.steps} 用于沿着挤出样条的深度细分的点的数量。 * @param {option.depth} 挤出的形状的深度 * @param {option.bevelEnabled} 对挤出的形状应用是否斜角 * @param {option.bevelSize} 斜角与原始形状轮廓之间的延伸距离 * @param {option.bevelOffset} 斜角的分段层数,默认值为3。 * @param {option.bevelSegments} 斜角与原始形状轮廓之间的延伸距离 */ function extrudeGeometry (points, option) { const shape = new THREE.Shape(); // 循环每一个点放在形状 shape.moveTo(points[0].x, points[0].y); for (let i = 1; i < points.length; i++) { shape.lineTo(points[i].x, points[i].y); } // 设置挤压属性 const extrudeSettings = { steps: option.steps || 32, //用于沿着挤出样条的深度细分的点的数量。 depth: option.depth || 0.2,// 挤出的形状的深度 bevelEnabled: !!option.bevelEnabled, // bool,对挤出的形状应用是否斜角 bevelThickness: option.bevelThickness || 0.2, // 设置原始形状上斜角的厚度 bevelSize: option.bevelSize || 0.1, // 斜角与原始形状轮廓之间的延伸距离 bevelOffset: option.bevelOffset || 0.05, bevelSegments: option.bevelSegments || 32 // 斜角的分段层数,默认值为3。 }; // 返回挤压的几何体包含顶点信息等 const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); return geometry } ```

第一个模型

制作第一个白色的模型,加材质

```js

// 第一个白色 const firstGeo = extrudeGeometry(points, { steps: 32, depth: 0.2, bevelEnabled: true, bevelThickness: 0.13, bevelSize: 0.1, bevelOffset: 0.1, bevelSegments: 32 }) // 设置材质 const material = whiteMaterialBool(); // 生成模型 const mesh = new THREE.Mesh(firstGeo, material); // 调整位置等信息 mesh.position.y = 0.4 mesh.rotation.x = 0.5 * Math.PI mesh.castShadow = true // 是否产生阴影 mesh.receiveShadow = true // 是否接受阴影 // 将模型加入到场景中 scene.add(mesh);

```

漫反射(反射插件)

image.png

同样的原理,把再上面的一层绿色的模型加上去,然后再加一层反光面

html <script src="../../three.js-master\examples\js/objects/Reflector.js"></script> js function initReflector() { // 反光面 reflector = new THREE.Reflector(new THREE.PlaneGeometry(20, 20), { textureWidth: window.innerWidth * window.devicePixelRatio, textureHeight: window.innerHeight * window.devicePixelRatio, color: 0x81f98d }); reflector.position.y = 1.35; reflector.rotation.x = -0.5 * Math.PI scene.add(reflector); }

镜面效果如果在3D软件可以用漫反射直接做出来,代码敲漫反射有点复杂,直接调用插件,镜面上面放一个模型 试试效果

image.png

堆砌元素

先从简单的入手,一层一层往上加,金属的那的外层稍后再加一下,接下来就是文字后面的大的绿色模块

image.png

跟底板的绿色是一样的效果 我把下面效果相同的都先堆出来

image.png

这里的代码就不铺了 就是各种调参数,可以去源码扒拉扒拉

文字的制作

接下来制作文字部分,没引入字体,直接用ai软件画一个svg导出来,找到一款差不多的字体

image.png

导出到svg文件

image.png

接下来将文字导入到场景中

```js function loadSvg () { var loader = new THREE.SVGLoader(); loader.load( "./svg/club.svg", function (data) { // 将svg挤出高度 var paths = data.paths; for (var i = 0; i < paths.length; i++) { var path = paths[i]; var shapes = path.toShapes(true); shapes.forEach((shape) => { let extrudeGeo extrudeGeo = new THREE.ExtrudeGeometry(shape, { bevelEnabled: true, depth: 20, steps: 32, bevelSegments: 32, bevelSize: 2, }); extrudeGeo.scale(0.05, 0.05, 0.05); var mesh = new THREE.Mesh(extrudeGeo, greenMaterialBool()); mesh.rotation.x = -Math.PI mesh.position.set(-4.2, 6.2, 8.5) scene.add(mesh) }); } }) }

```

logo及其他部分

image.png

导入之后尺寸和方向都不合适 稍微调整一下,再加上上面的logo部分,稍微调整一下灯光,找一下角度,就酱

image.png

大致复刻成这样,再有的就是一些耐心,铺设所有的内容,再加上阴影调整细节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙华鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值