最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Three.js+React使二維圖片呈現(xiàn)3D效果

 更新時(shí)間:2022年02月22日 10:14:17   作者:dragonir  
這篇文章主要為大家介紹了如何利用Three.js+React技術(shù)棧,將二維漫畫圖片轉(zhuǎn)化為三維視覺效果。文中的實(shí)現(xiàn)方法講解詳細(xì),需要的可以參考一下

背景

逛 sketchfab 網(wǎng)站的時(shí)候我看到有很多二維平面轉(zhuǎn) 3D 的模型例子,于是仿照他們的例子,使用 Three.js + React 技術(shù)棧,將二維漫畫圖片轉(zhuǎn)化為三維視覺效果。本文包含的內(nèi)容主要包括:THREE.Group 層級(jí)模型、MeshPhongMaterial 高光網(wǎng)格材質(zhì)、正弦余弦函數(shù) 創(chuàng)建模型移動(dòng)軌跡等。

效果

實(shí)現(xiàn)效果如下圖所示:頁面主要有背景圖、漫畫圖片主體以及 Boom 爆炸背景圖片構(gòu)成,按住鼠標(biāo)左鍵移動(dòng)模型可以獲得不同視圖,讓圖片在視覺上有 3D 景深效果。

已適配:

PC端

移動(dòng)端

在線預(yù)覽:https://dragonir.github.io/3d/#/comic

實(shí)現(xiàn)

本文實(shí)現(xiàn)比較簡(jiǎn)單,和我前面幾篇文章實(shí)現(xiàn)基本上是相同的,流程也比較簡(jiǎn)單,主要是素材準(zhǔn)備流程比較復(fù)雜。下面看看具體實(shí)現(xiàn)方法。

素材制作

準(zhǔn)備一張自己喜歡的圖片作為素材原圖,圖片內(nèi)容最好可以分成多個(gè)層級(jí),以實(shí)現(xiàn) 3D 景深效果,本實(shí)例中使用的是一張漫畫圖片,剛好可以切分成多個(gè)層級(jí)。

在 Photoshop 中打開圖片,根據(jù)自己需要的分層數(shù)量,創(chuàng)建若干圖層,并將地圖復(fù)制到每個(gè)圖層上,然后根據(jù)對(duì)圖層景深層級(jí)的劃分,編輯每個(gè)圖層,結(jié)合使用魔棒工具和套索工具刪除多余的部分,然后將每個(gè)圖層單獨(dú)導(dǎo)出作為素材。我分為如上 7 個(gè)圖層,外加一個(gè)邊框,一共有 8 個(gè)圖層。

資源引入

其中 OrbitControls 用于鏡頭軌道控制、TWEEN 用于鏡頭補(bǔ)間動(dòng)畫。

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";

場(chǎng)景初始化

初始化渲染容器、場(chǎng)景、攝像機(jī)、光源。攝像機(jī)初始位置設(shè)置為位于偏左方的 (-12, 0, 0),以便于后面使用 TWEEN 實(shí)現(xiàn)翻轉(zhuǎn)動(dòng)畫效果。

// 場(chǎng)景
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);
// 相機(jī)
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);
// 環(huán)境光
ambientLight = new THREE.AmbientLight(0xdddddd);
scene.add(ambientLight);

創(chuàng)建漫畫主體

首先創(chuàng)建一個(gè) Group,用于添加圖層網(wǎng)格,然后遍歷圖層背景圖片數(shù)組,在循環(huán)體中創(chuàng)建每個(gè)面的網(wǎng)格,該網(wǎng)格使用平面立方體 PlaneGeometry,材質(zhì)使用物理材質(zhì) MeshPhysicalMaterial,對(duì)每個(gè)網(wǎng)格位置設(shè)置相同的x軸和y軸值和不同的z軸值以創(chuàng)建景深效果。最后將 Group 添加到場(chǎng)景 Scene 中。

var layerGroup = new THREE.Group();
let aspect = 18;
for (let i=0; i<layers.length; i++) {
  let mesh = new THREE.Mesh(new THREE.PlaneGeometry(10.41, 16), new THREE.MeshPhysicalMaterial({
    map: new THREE.TextureLoader().load(layers[i]),
    transparent: true,
    side: THREE.DoubleSide
  }));
  mesh.position.set(0, 0, i);
  mesh.scale.set(1 - (i / aspect), 1 - (i / aspect), 1 - (i / aspect));
  layerGroup.add(mesh);
  // 文字
  if (i === 5) {
    mesh.material.metalness = .6;
    mesh.material.emissive = new THREE.Color(0x55cfff);
    mesh.material.emissiveIntensity = 1.6;
    mesh.material.opacity = .9;
  }
  // 會(huì)話框
  if (i === 6) {
    mesh.scale.set(1.5, 1.5, 1.5);
    animateLayer = mesh;
  }
}
layerGroup.scale.set(1.2, 1.2, 1.2);

到這一步,實(shí)現(xiàn)效果如下圖所示:

THREE.Group 層級(jí)模型

將具有相同主體的網(wǎng)格可以通過 Group 合并在一起,以便于提高運(yùn)行效率。Three.js 層級(jí)模型 Group 的基類是 Object3D,它是 Three.js 中大部分對(duì)象的基類,提供了一系列的屬性和方法來對(duì)三維空間中的物體進(jìn)行操縱。如可以通過 .add(object) 方法來將對(duì)象進(jìn)行組合,該方法將對(duì)象添加為子對(duì)象。

但最好使用 Group 來作為父對(duì)象,因?yàn)?nbsp;Group 相比較Object3D 更語義化,可以使用 Group 作為點(diǎn)、線、網(wǎng)格等模型的父對(duì)象,用來構(gòu)建一個(gè)層級(jí)模型。

創(chuàng)建Boom背景

為了加強(qiáng)視覺效果,我添加了一個(gè)Boom 爆炸圖形平面作為背景,用鼠標(biāo)移動(dòng)的時(shí)候隨著光線的變化,可以看到該圖案有金屬漸變效果,這種效果主要是通過高光材質(zhì) MeshPhongMaterial 的 specular 和 shininess 屬性實(shí)現(xiàn)的。

const boom = new THREE.Mesh(new THREE.PlaneGeometry(36.76, 27.05), new THREE.MeshPhongMaterial({
  map: new THREE.TextureLoader().load(boomImage),
  transparent: true,
  shininess: 160,
  specular: new THREE.Color(0xff6d00),
  opacity: .7
}));
boom.scale.set(.8, .8, .8);
boom.position.set(0, 0, -3);
layerGroup.add(boom)
scene.add(layerGroup);

添加后效果:

MeshPhongMaterial 高光網(wǎng)格材質(zhì)

MeshPhongMaterial 是一種用于具有鏡面高光的光澤表面的材質(zhì)。該材質(zhì)使用非物理的 Blinn-Phong 模型來計(jì)算反射率。與 MeshLambertMaterial 中使用的 Lambertian 模型不同,該材質(zhì)可以模擬具有鏡面高光的光澤表面,如涂漆木材。

構(gòu)造函數(shù)

MeshPhongMaterial(parameters: Object)

parameters:可選,用于定義材質(zhì)外觀的對(duì)象,具有一個(gè)或多個(gè)屬性。 材質(zhì)的任何屬性都可以從此處傳入(包括從Material繼承的任何屬性)。

特殊屬性

  • .emissive[Color]:材質(zhì)的放射光顏色,基本上是不受其他光照影響的固有顏色。默認(rèn)為 黑色
  • .emissiveMap[Texture]:設(shè)置發(fā)光貼圖。默認(rèn)值為 null。放射貼圖顏色由放射顏色和強(qiáng)度所調(diào)節(jié)。
  • .emissiveIntensity[Float]:放射光強(qiáng)度。調(diào)節(jié)發(fā)光顏色。默認(rèn)為 1。
  • .envMap[TextureCube]:環(huán)境貼圖。默認(rèn)值為 null。
  • .isMeshPhongMaterial[Boolean]:用于檢查此類或派生類是否為 Phong 網(wǎng)格材質(zhì)。默認(rèn)值為 true
  • .lightMap[Texture]:光照貼圖。默認(rèn)值為 null。
  • .lightMapIntensity[Float]:烘焙光的強(qiáng)度。默認(rèn)值為 1
  • .reflectivity[Float]:環(huán)境貼圖對(duì)表面的影響程度。默認(rèn)值為 1,有效范圍介于 0(無反射) 和 1(完全反射) 之間。
  • .refractionRatio[Float]:空氣的折射率除以材質(zhì)的折射率。折射率不應(yīng)超過 1。默認(rèn)值為 0.98。
  • .shininess[Float].specular 高亮的程度,越高的值越閃亮。默認(rèn)值為 30。
  • .skinning[Boolean]:材質(zhì)是否使用蒙皮。默認(rèn)值為 false。
  • .specular[Color]:材質(zhì)的高光顏色。默認(rèn)值為 0x111111 的顏色 Color。這定義了材質(zhì)的光澤度和光澤的顏色。
  • .specularMap[Texture]:鏡面反射貼圖值會(huì)影響鏡面高光以及環(huán)境貼圖對(duì)表面的影響程度。默認(rèn)值為 null。

使用 Phong 著色模型計(jì)算著色時(shí),會(huì)計(jì)算每個(gè)像素的陰影,與 MeshLambertMaterial 使用的 Gouraud 模型相比,該模型的結(jié)果更準(zhǔn)確,但代價(jià)是犧牲一些性能。

鏡頭控制、縮放適配、動(dòng)畫

鏡頭補(bǔ)間動(dòng)畫,鏡頭切換到正確位置。

Animations.animateCamera(camera, controls, { x: 0, y: 0, z: 20 }, { x: 0, y: 0, z: 0 }, 3600, () => { });

鏡頭控制,本示例中顯示了模型平移以及水平垂直旋轉(zhuǎn)的角度,以達(dá)到最好的預(yù)覽效果。

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

屏幕縮放適配。

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

對(duì)于會(huì)話框圖層網(wǎng)格,我給它添加了在一條光滑曲線上左右移動(dòng)的動(dòng)畫效果,主要是通過修改它在 x 軸和 y 軸上的 position 來實(shí)現(xiàn)的 。

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  controls && controls.update();
  TWEEN && TWEEN.update();
  // 會(huì)話框擺動(dòng)動(dòng)畫
  step += 0.01;
  animateLayer.position.x = 2.4 + Math.cos(step);
  animateLayer.position.y = .4 + Math.abs(Math.sin(step));
}

正弦余弦函數(shù)創(chuàng)建模型移動(dòng)軌跡

使用 step 變量并在函數(shù) Math.cos() 和 Math.sin() 的幫助下 ,創(chuàng)建出一條光滑的軌跡。step+= 0.01 定義的是球的彈跳速度。

到此,本示例的完整實(shí)現(xiàn)都描述完畢了,大家感興趣的話,可以動(dòng)手試著把自己喜歡的圖片改造成 3D 視圖。拜托,使用 Three.js 這樣展示圖片超酷的好嗎!

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

總結(jié)

本文知識(shí)點(diǎn)主要包含的的新知識(shí):

THREE.Group 層級(jí)模型

MeshPhongMaterial 高光網(wǎng)格材質(zhì)

正弦余弦函數(shù) 創(chuàng)建模型移動(dòng)軌跡

以上就是Three.js+React使二維圖片呈現(xiàn)3D效果的詳細(xì)內(nèi)容,更多關(guān)于Three.js React圖片3D效果的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js獲取select標(biāo)簽選中值的兩種方式

    js獲取select標(biāo)簽選中值的兩種方式

    獲取select標(biāo)簽選中的值有很多方法,下面通過兩種方式使用js來進(jìn)行獲取,喜歡的朋友可以參考下
    2014-01-01
  • JavaScript數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組的表示方法示例

    JavaScript數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組的表示方法示例

    這篇文章主要介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組的表示方法,從數(shù)據(jù)結(jié)構(gòu)線性表的角度分析了數(shù)組的原理并結(jié)合實(shí)例形式分析了javascript數(shù)組的定義與使用方法,需要的朋友可以參考下
    2017-04-04
  • TypeScript聯(lián)合類型,交叉類型和類型保護(hù)

    TypeScript聯(lián)合類型,交叉類型和類型保護(hù)

    這篇文章主要介紹了TypeScript聯(lián)合類型,交叉類型和類型保護(hù),聯(lián)合類型就是定義一些類型,定義的變量只需要滿足任意一種類型即可,交叉類型就是需要滿足所有類型,交叉類型使用,更多內(nèi)容我們來看看下面文章詳細(xì)內(nèi)容吧
    2021-12-12
  • js生成縮略圖后上傳并利用canvas重繪

    js生成縮略圖后上傳并利用canvas重繪

    這篇文章主要介紹了js生成縮略圖后上傳,利用canvas重繪,需要的朋友可以參考下
    2014-05-05
  • laydate時(shí)間日歷插件使用方法詳解

    laydate時(shí)間日歷插件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了laydate時(shí)間日歷插件的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • JS防止網(wǎng)頁被嵌入iframe框架的方法分析

    JS防止網(wǎng)頁被嵌入iframe框架的方法分析

    這篇文章主要介紹了JS防止網(wǎng)頁被嵌入iframe框架的方法,結(jié)合實(shí)例形式分析了針對(duì)不同瀏覽器防止網(wǎng)頁被嵌入框架的相關(guān)注意事項(xiàng)與操作技巧,需要的朋友可以參考下
    2016-09-09
  • JS實(shí)現(xiàn)輸入框提示文字點(diǎn)擊時(shí)消失效果

    JS實(shí)現(xiàn)輸入框提示文字點(diǎn)擊時(shí)消失效果

    這篇文章主要介紹了JS實(shí)現(xiàn)輸入框提示文字點(diǎn)擊時(shí)消失效果,涉及javascript針對(duì)鼠標(biāo)的響應(yīng)及事件監(jiān)聽機(jī)制相關(guān)技巧,需要的朋友可以參考下
    2016-07-07
  • JS實(shí)現(xiàn)商品篩選功能

    JS實(shí)現(xiàn)商品篩選功能

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)商品篩選功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • innerText innerHTML的用法以及注意事項(xiàng) [推薦]

    innerText innerHTML的用法以及注意事項(xiàng) [推薦]

    我們常常需要使用另外一些對(duì)象的屬性來實(shí)現(xiàn)動(dòng)態(tài)改變其中的文本,它們就是:innerText,outerText,innerHTML,outerHTML,千萬要注意它們的大小寫,因?yàn)殄e(cuò)一點(diǎn)您就得不到預(yù)期的效果了。
    2009-05-05
  • javascript中常用的字符串函數(shù)解讀

    javascript中常用的字符串函數(shù)解讀

    這篇文章主要介紹了javascript中常用的字符串函數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論

临沭县| 朔州市| 微山县| 铁力市| 岳池县| 镇赉县| 淅川县| 吉林市| 泸水县| 芮城县| 德化县| 南部县| 垫江县| 安泽县| 阿拉尔市| 大化| 平远县| 应城市| 体育| 克山县| 隆安县| 海宁市| 金昌市| 盐城市| 荆门市| 巴彦淖尔市| 高碑店市| 时尚| 那曲县| 德令哈市| 沛县| 玉环县| 依兰县| 新绛县| 甘孜县| 杂多县| 鹤壁市| 土默特右旗| 公安县| 芜湖县| 新丰县|