Three.js--》实现图片转3D效果展示

目录

项目搭建

初始化three.js基础代码

加载图片纹理

设置着色器


今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。

项目搭建

本案例还是借助框架书写three项目,借用vite构建工具搭建vue项目,vite这个构建工具如果有不了解的朋友,可以参考我之前对其讲解的文章:vite脚手架的搭建与使用 。搭建完成之后,用编辑器打开该项目,在终端执行 npm i 安装一下依赖,安装完成之后终端在安装 npm i three 即可。

因为我搭建的是vue3项目,为了便于代码的可读性,所以我将three.js代码单独抽离放在一个组件当中,在App根组件中进入引入该组件。具体如下:

<template>
  <!-- 3D图片效果 -->
  <Image3DEffect></Image3DEffect>
</template>

<script setup>
import Image3DEffect from './components/Image3DEffect.vue';
</script>

<style lang="less">
  *{
    margin: 0;
    padding: 0;
  }
</style>

初始化three.js基础代码

three.js开启必须用到的基础代码如下:

导入three库

import * as THREE from 'three'

初始化场景

const scene = new THREE.Scene()

初始化相机

// 设置相机
const camera = new THREE.PerspectiveCamera(90,window.innerWidth/window.innerHeight,0.1,1000)
camera.position.set(0,0,5)

初始化渲染器

// 渲染器
let renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth,window.innerHeight)

监听屏幕大小的改变,修改渲染器的宽高和相机的比例

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

设置渲染函数: 

// 创建渲染函数
const render = () => {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();

ok,写完基础代码之后,接下来开始具体的Demo实操。 

加载图片纹理

这里通过TextureLoader加载各图片纹理文件,图片资源大家可以随便在网上找一个就行,如果想要图片资源的朋友可以在这个网站找找看:https://pixabay.com/zh/ ,在加载图片纹理时,我们还要加载器深度图。

Depth Map(深度图)是一种图像格式,它记录了每个像素距离相机的距离信息。深度图可以用来表示三维场景中物体的距离,是3D渲染中常用的图像格式之一。

在图形渲染管线中,深度图通常用于实现深度测试和阴影计算。深度测试是指在将三维物体渲染到屏幕上时,比较每个像素的深度值(即该像素距离相机的距离),如果一个像素前面有另一个像素,则只显示前面的像素,从而保证渲染顺序的正确性。而阴影计算则是通过比较光源与物体之间的深度值,确定每个像素是否被遮挡(即在阴影中)。

生成深度图的网站:LeiaPix Converter | Depth Animations ,我们直接导入图片即可:

我们可以对深度图片的相关样式进行修改:

最后点击Depath Map  下载深度图片即可。

// 加载纹理
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load("/images/woman.jpg")
const depthTexture = textureLoader.load("/images/woman_depth.jpg")

设置着色器

着色器(Shader)是一种在图形渲染管线中运行的程序,它可以对渲染过程中的顶点、像素等进行各种计算和处理,从而实现各种复杂的渲染效果。

着色器通常分为两种类型顶点着色器片元着色器。顶点着色器是用来计算顶点的位置、法线、纹理坐标等信息,并将其传递给片元着色器进行处理;片元着色器则是用来计算每个像素(片元)的颜色值,通常根据纹理、灯光、材质等信息进行计算,并输出最终颜色值到屏幕上。

// 创建屏幕
const geomery = new THREE.PlaneGeometry(19.2,12.8)
// 创建鼠标对象
const mouse = new THREE.Vector2()
// 设置着色器材质
const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0 },
    uTexture: { value: texture },
    uDepthTexture: { value: depthTexture },
    uMouse: { value: mouse }
  },
  vertexShader: `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    uniform sampler2D uTexture;
    uniform sampler2D uDepthTexture;
    uniform vec2 uMouse;
    varying vec2 vUv;
    uniform float uTime;
    void main() {
      vec4 color = texture2D(uTexture, vUv);
      vec4 depth = texture2D(uDepthTexture, vUv);
      float depthValue = depth.r;
      float x = vUv.x + (uMouse.x+sin(uTime))*0.01*depthValue;
      float y = vUv.y + (uMouse.y+cos(uTime))*0.01*depthValue;
      vec4 newColor = texture2D(uTexture, vec2(x, y));
      gl_FragColor = newColor;
    }
  `,
})
const plane = new THREE.Mesh(geomery,material)
scene.add(plane)

最后我们设置渲染函数和监听事件:

// 设置渲染函数
const render = () =>{ 
  material.uniforms.uMouse.value = mouse;
  material.uniforms.uTime.value = performance.now() / 1000;
  requestAnimationFrame(render)
  renderer.render(scene,camera)
} 
render()

// 设置鼠标移动监听事件
window.addEventListener("mousemove", (event) => {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});

动态图的文件太大上传不了glf,这里就已图片代替了,效果就是鼠标移动图片跟着轻微的移动,如果是已经感受到上面讲解到生成深度图的网站的人应该能理解我说过的话。

接下来我们可以给该3D背景图添加点文字:

<template>
  <div class="canvas-container" ref="screenDom"></div>
  <div class="content">
    <h1>学习更多前端技术</h1>
    <h2>请关注亦世凡华、</h2>
  </div>
</template>

<style lang="less">
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.canvas-container {
  width: 100vw;
  height: 100vh;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
}
.content{
  position: fixed;
  top: 40%;
  left: 20%;
}
.content h1 {
  color: rgb(255, 247, 0);
  font-size: 40px;
  margin-bottom: 30px;
}
</style>

demo做完,给出本案例的完整代码:(获取素材也可以私信博主)

<template>
  <div class="canvas-container" ref="screenDom"></div>
  <div class="content">
    <h1>学习更多前端技术</h1>
    <h2>请关注亦世凡华、</h2>
  </div>
</template>

<script setup>
import * as THREE from 'three'
import { ref,onMounted } from 'vue'

let screenDom = ref(null);
// 设置场景
const scene = new THREE.Scene()
// 设置相机
const camera = new THREE.PerspectiveCamera(90,window.innerWidth/window.innerHeight,0.1,1000)
camera.position.set(0,0,5)
// 渲染器
let renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth,window.innerHeight)
onMounted(()=>{
  screenDom.value.appendChild(renderer.domElement);
})

// 监听屏幕大小变化
window.addEventListener("resize",()=>{ 
  renderer.setSize(window.innerWidth,window.innerHeight)
  camera.aspect = window.innerWidth/window.innerHeight
  camera.updateProjectionMatrix()
})

// 加载纹理
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load("/images/woman.jpg")
const depthTexture = textureLoader.load("/images/woman_depth.jpg")

// 创建屏幕
const geomery = new THREE.PlaneGeometry(19.2,12.8)
// 创建鼠标对象
const mouse = new THREE.Vector2()
// 设置着色器材质
const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0 },
    uTexture: { value: texture },
    uDepthTexture: { value: depthTexture },
    uMouse: { value: mouse }
  },
  vertexShader: `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    uniform sampler2D uTexture;
    uniform sampler2D uDepthTexture;
    uniform vec2 uMouse;
    varying vec2 vUv;
    uniform float uTime;
    void main() {
      vec4 color = texture2D(uTexture, vUv);
      vec4 depth = texture2D(uDepthTexture, vUv);
      float depthValue = depth.r;
      float x = vUv.x + (uMouse.x+sin(uTime))*0.01*depthValue;
      float y = vUv.y + (uMouse.y+cos(uTime))*0.01*depthValue;
      vec4 newColor = texture2D(uTexture, vec2(x, y));
      gl_FragColor = newColor;
    }
  `,
})
const plane = new THREE.Mesh(geomery,material)
scene.add(plane)

// 设置渲染函数
const render = () =>{ 
  material.uniforms.uMouse.value = mouse;
  material.uniforms.uTime.value = performance.now() / 1000;
  requestAnimationFrame(render)
  renderer.render(scene,camera)
} 
render()

// 设置鼠标移动监听事件
window.addEventListener("mousemove", (event) => {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
</script>

<style lang="less">
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.canvas-container {
  width: 100vw;
  height: 100vh;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
}
.content{
  position: fixed;
  top: 40%;
  left: 20%;
}
.content h1 {
  color: rgb(255, 247, 0);
  font-size: 40px;
  margin-bottom: 30px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/29974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】Ubuntu安装GCC9.3.0版本的Qt5.15.5

目录 一、安装GCC9.3.0 1.下载GCC9.3.0源码 2.获取依赖项的包 3.生成Makefile文件 4.编译并安装 5.生成软链接 6. 查看GCC版本 二、安装Qt 1.下载Qt安装包 2.创建Qt项目并运行 一、安装GCC9.3.0 1.下载GCC9.3.0源码 https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3…

excel爬虫相关学习1:简单的excel爬虫

目录 1 什么是excel 爬虫 2 EXCEL爬虫 2.1 excel 爬虫的入口 2.2 需要配置的信息 2.2.1 如何获得 ua信息 2.3 获取的信息 2.3.1 获取信息的基本内容 2.3.2 获取过程 2.3.3 我们只用关注“表视图 ” 即可 2.4 EXCEL获得的爬虫数据 加载到excel里 2.5 数据到了excel表后…

Three.js--》实现3d汽车模型展览搭建

目录 项目搭建 初始化three.js基础代码 添加汽车模型展示 动态修改汽车模型 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还是借助…

flink主要组件及高可用配置

背景 flink不论运行在哪种环境&#xff0c;例如Yarn&#xff0c;Mesos&#xff0c;Kebernute以及独立集群&#xff0c;每个应用都会包含重要的几个组件&#xff0c;本文就来讲述下flink的主要组件以及如何实现flink的高可用配置 flink主要组件 如图所示&#xff0c;flink主要…

Java实训日志02

文章目录 八、项目开发实现步骤&#xff08;二&#xff09;创建项目1、创建Java项目2、创建目录&#xff0c;添加素材&#xff08;1&#xff09;创建help目录添加帮助文档&#xff08;2&#xff09;创建images目录添加图像素材&#xff08;3&#xff09;创建lib目录添加数据库驱…

Dockerfile创建镜像

一、Docker镜像的创建 创建镜像有三种方法&#xff0c;分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it centos:7 /bin/bash …

设计模式之工厂方法模式笔记

设计模式之工厂方法模式笔记 说明Factory Method(工厂方法)目录UML抽象工厂示例类图咖啡抽象类美式咖啡类拿铁咖啡类 咖啡工厂接口美式咖啡工厂类拿铁咖啡工厂类 咖啡店类测试类 说明 记录下学习设计模式-工厂方法模式的写法。 Factory Method(工厂方法) 意图:定义一个用于创…

主从架构lua脚本-Redis(四)

上篇文章介绍了rdb、aof持久化。 持久化RDB/AOF-Redis&#xff08;三&#xff09;https://blog.csdn.net/ke1ying/article/details/131148269 redis数据备份策略 写job每小时copy一份到其他目录。目录里可以保留最近一个月数据。把目录日志保存到其他服务器&#xff0c;防止机…

专业的知识图谱应用门槛正在被不断降低

前⾔ 知识图谱&#xff08;knowledge graph&#xff09;⼀度被专家称为“AI皇冠上的明珠”&#xff0c;因为知识图谱技术是⼈⼯智能技术⽅向中的重要⼀环。它不仅可以为其他⼈⼯智能应⽤提供⽀持&#xff0c;如⾃然语⾔处理、推荐系统等&#xff0c;更可以帮助⼈⼯智能系统⾃主…

《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC

前言 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 Apache ShardingSphere 设计哲学为 Database Plus&#xff0c;旨在构建异构数据库上层的…

【Python 随练】统计字符类型个数

题目&#xff1a; 输入一行字符&#xff0c;分别统计出其中英文字母、空格、数字和其它字符的个数。 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个字符统计问题&#xff1a;输入一行字符&#xff0c;统计其中英文字母、空格、数字和其他字符的个数。我们将提供…

NoSQLBooster 8.0.11 for MongoDB

MongoDB最智能的IDE。 NoSQLBooster 是适用于 MongoDB Server 3.6-6.0 的跨平台 GUI 工具&#xff0c;它提供了内置的 MongoDB 脚本调试器、全面的服务器监控工具、链接流畅查询、SQL 查询、查询代码生成器、任务调度、ES2020 支持和高级 IntelliSense 体验。 嵌入式MongoDB S…

强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

redis键值对映射关系存储-Dict

基本概述 Redis是一个键值型&#xff08;Key-Value Pair&#xff09;的数据库&#xff0c;可以根据键实现快速的增删改查。而键与值的映射关系正是通过Dict来实现的。 Dict由三部分组成&#xff0c;分别是&#xff1a;哈希表&#xff08;DictHashTable&#xff09;、哈希节点&a…

redis安装

在官网下载: https://redis.io/download/ 或者直接下载: ​wget https://download.redis.io/releases/redis-6.2.12.tar.gz 解压到/usr/local/下 [rootlocalhost ~]# tar redis-6.2.12.tar.gz -C /usr/local/ [rootlocalhost ~]# cd /usr/local/redis-6.2.12 [rootlocalho…

C++算法————二分查找

又是鸽了三千万年 马上要打csp了&#xff0c;开始回流学j组的知识了&#xff0c;浅说一下二分吧&#xff08;&#xff09; --------------------------------------------------------------------------------------------------------------------------------- 二分查找 …

了解MVC、MVP、MVVM模式

前言 在Android开发中&#xff0c;当你梳理完需求后&#xff0c;你要做的并不是马上写下你的第一行代码&#xff0c;而是需先设计好整个项目的技术框架今天&#xff0c;我将全面介绍Android开发中主流的技术框架MVC、MVP 与 MVVM模式&#xff0c;并实例讲解MVP模式&#xff0c…

面试篇:SpringCloud

一、SpringCloud常见的组件有什么&#xff1f; 1、常见微服务功能架构图 2、阿里巴巴SpringCloud常用组件 注册中心/配置中心&#xff1a;Nacos负载均衡&#xff1a;Ribbon服务调用&#xff1a;Feign服务保护&#xff1a;Sentinel服务网关&#xff1a;Gateway 二、服务注册…

Compose Desktop 实战 宝可梦图鉴

Compose Desktop 实战 宝可梦图鉴 前言 阅读本文需要一定compose基础&#xff0c;如果没有请移步Jetpack Compose入门详解&#xff08;实时更新&#xff09; 接口数据来源于pokeapi 项目源代码 如果你觉得不错&#xff0c;请给我一个star&#xff0c;THKS 实现效果 闲话不…

php通过cURL爬取数据(3):CURLINFO_HTTP_CODE返回0的排查和解决方案

CURLINFO_HTTP_CODE返回0的排查和解决方案 一、curl本地服务器需要DNS解析域名二、如何排查错误原因三、无法解析 DNS的程序升级方案四、宝塔配置DNS的操作方法1.etc/resolv.conf2.通过GUI界面 一、curl本地服务器需要DNS解析域名 在使用 curl 命令发送请求到域名地址&#xf…