使用Three.js让二维图片呈现3D效果 您所在的位置:网站首页 三维动画个人总结 使用Three.js让二维图片呈现3D效果

使用Three.js让二维图片呈现3D效果

2023-03-18 11:53| 来源: 网络整理| 查看: 265

使用Three.js让二维图片呈现3D效果_图层

声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。

背景

逛 ​​sketchfab​​​ 网站的时候我看到有很多二维平面转 ​​3D​​​ 的模型例子,于是仿照他们的例子,使用 ​​Three.js​​​ + ​​React​​​ 技术栈,将二维漫画图片转化为三维视觉效果。本文包含的内容主要包括:​​THREE.Group​​​ 层级模型、​​MeshPhongMaterial​​​ 高光网格材质、​​正弦余弦函数​​ 创建模型移动轨迹等。

效果

实现效果如 ​​👇​​​ 下图所示:页面主要有背景图、漫画图片主体以及 ​​💥 Boom​​​ 爆炸背景图片构成,按住鼠标左键移动模型可以获得不同视图,让图片在视觉上有 ​​3D​​ 景深效果。

使用Three.js让二维图片呈现3D效果_图层_02

已适配:

​​💻​​ PC端​​📱​​ 移动端

​​👀​​​ 在线预览:​​https://dragonir.github.io/3d/#/comic​​

实现

本文实现比较简单,和我前面几篇文章实现基本上是相同的,流程也比较简单,主要是素材准备流程比较复杂。下面看看具体实现方法。

素材制作

准备一张自己喜欢的图片作为素材原图,图片内容最好可以分成多个层级,以实现 ​​3D​​ 景深效果,本实例中使用的是一张漫画图片,刚好可以切分成多个层级。

使用Three.js让二维图片呈现3D效果_默认值_03

在 ​​Photoshop​​ 中打开图片,根据自己需要的分层数量,创建若干图层,并将地图复制到每个图层上,然后根据对图层景深层级的划分,编辑每个图层,结合使用魔棒工具和套索工具删除多余的部分,然后将每个图层单独导出作为素材。我分为 ​​👆​​​ 如上 ​​7​​​ 个图层,外加一个边框,一共有 ​​8​​ 个图层。

使用Three.js让二维图片呈现3D效果_图层_04

资源引入

其中 ​​OrbitControls​​​ 用于镜头轨道控制、​​TWEEN​​ 用于镜头补间动画。

import React from 'react';import * as THREE from "three";import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";场景初始化

初始化渲染容器、场景、摄像机、光源。摄像机初始位置设置为位于偏左方的 ​​(-12, 0, 0)​​​,以便于后面使用 ​​TWEEN​​ 实现翻转动画效果。

// 场景container = document.getElementById('container');renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);container.appendChild(renderer.domElement);scene = new THREE.Scene();// 添加背景图片scene.background = new THREE.TextureLoader().load(background);// 相机camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.set(-12, 0, 0);camera.lookAt(new THREE.Vector3(0, 0, 0));// 直射光light = new THREE.DirectionalLight(0xffffff, 1);light.intensity = .2;light.position.set(10, 10, 30);light.castShadow = true;light.shadow.mapSize.width = 512 * 12;light.shadow.mapSize.height = 512 * 12;light.shadow.camera.top = 100;light.shadow.camera.bottom = - 50;light.shadow.camera.left = - 50;light.shadow.camera.right = 100;scene.add(light);// 环境光ambientLight = new THREE.AmbientLight(0xdddddd);scene.add(ambientLight);创建漫画主体

首先创建一个 ​​Group​​​,用于添加图层网格,然后遍历图层背景图片数组,在循环体中创建每个面的网格,该网格使用平面立方体 ​​PlaneGeometry​​​,材质使用物理材质 ​​MeshPhysicalMaterial​​​,对每个网格位置设置相同的x轴和y轴值和不同的z轴值以创建景深效果。最后将 ​​Group​​​ 添加到场景 ​​Scene​​ 中。

var layerGroup = new THREE.Group();let aspect = 18;for (let i=0; i { });

镜头控制,本示例中显示了模型平移以及水平垂直旋转的角度,以达到最好的预览效果。

controls = new OrbitControls(camera, renderer.domElement);controls.target.set(0, 0, 0);controls.enableDamping = true;controls.enablePan = false;// 垂直旋转角度限制controls.minPolarAngle = 1.2;controls.maxPolarAngle = 1.8;// 水平旋转角度限制controls.minAzimuthAngle = -.6;controls.maxAzimuthAngle = .6;

屏幕缩放适配。

window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight);}, false);

对于会话框图层网格,我给它添加了在一条光滑曲线上左右移动的动画效果,主要是通过修改它在 ​​x​​​ 轴和 ​​y​​​ 轴上的 ​​position​​ 来实现的 。

function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); controls && controls.update(); TWEEN && TWEEN.update(); // 会话框摆动动画 step += 0.01; animateLayer.position.x = 2.4 + Math.cos(step); animateLayer.position.y = .4 + Math.abs(Math.sin(step));}​​💡​​ 正弦余弦函数创建模型移动轨迹

使用 ​​step​​​ 变量并在函数 ​​Math.cos()​​​ 和 ​​Math.sin()​​​ 的帮助下 ,创建出一条光滑的轨迹。​​step+= 0.01​​ 定义的是球的弹跳速度。

到此,本示例的完整实现都描述完毕了,大家感兴趣的话,可以动手试着把自己喜欢的图片改造成 ​​3D​​​ 视图。拜托,使用 ​​Three.js​​​ 这样展示图片超酷的好吗! ​​😂​​

​​🔗​​​ 完整代码:​​https://github.com/dragonir/3d/tree/master/src/containers/Comic​​

总结

本文知识点主要包含的的新知识:

​​THREE.Group​​ 层级模型​​MeshPhongMaterial​​ 高光网格材质​​正弦余弦函数​​ 创建模型移动轨迹

想了解场景初始化、光照、阴影、基础几何体、网格、材质及其他 ​​Three.js​​ 的相关知识,可阅读我往期文章。转载请注明原文地址和作者。如果觉得文章对你有帮助,不要忘了一键三连哦 👍。

Sign up for more like this.


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有