threejs视频教程学习(5):水天一色小岛

2024-01-11 21:59

本文主要是介绍threejs视频教程学习(5):水天一色小岛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

内容来源:老陈threejs入门教程

陈老师讲的还是很不错的,贴图材料可以加视频里的qq群,或者用我下载的这个(微云):https://share.weiyun.com/6uA7pnYc

基础内容

<template><div class="container" id="container"></div>
</template><script setup lang="ts">
// 引入threejs
import * as THREE from 'three';
// 导入轨道控制器,模块化开发导入的是jsm不是js
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { onMounted } from 'vue';onMounted(() => {// 创建场景const scene = new THREE.Scene();// 创建透视相机,通过相机来观察const camera = new THREE.PerspectiveCamera(75, // 角度window.innerWidth / window.innerHeight, // 长宽比1, // 近端2000 // 远端);// 设置相机的位置camera.position.set(-50, 50, 130);// 设置摄像机视锥体的长宽比camera.aspect = window.innerWidth / window.innerHeight;// 更新摄像头投影矩阵camera.updateProjectionMatrix();// 将相机添加到场景中scene.add(camera);// 初始化渲染器const renderer = new THREE.WebGLRenderer({antialias: true // 抗锯齿});// 设置渲染的尺寸renderer.setSize(window.innerWidth, window.innerHeight);// 设置渲染的输出编码renderer.outputEncoding = THREE.sRGBEncoding;// 将wbgl渲染的canvas内容添加到dom元素中document.getElementById('container')?.appendChild(renderer.domElement);// 使用渲染器,通过相机将场景渲染进来renderer.render(scene, camera);// 监听平面大小的改变,修改相机的比例、渲染器的宽高window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);});// 创建轨道控制器const controls = new OrbitControls(camera, renderer.domElement);// 设置控制器阻尼,让物体拥有惯性,必须在动画循环里调用update()controls.enableDamping = true;// 添加坐标辅助器const axesHelper = new THREE.AxesHelper(10);scene.add(axesHelper);// 创建一个渲染函数,当场景发生变化后重新渲染const render = () => {controls.update();renderer.render(scene, camera);// 使用浏览器自带的请求动画帧函数不断的进行渲染requestAnimationFrame(render);};render();/** ******************创建物体的相关逻辑开始**************************** *//** ********************创建物体的相关逻辑结束********************************/
});</script>

天空

天空是通过创建一个大型的球体,然后添加天空贴图来实现的。

 // 创建纹理加载器const textureLoader = new THREE.TextureLoader();// 创建天空球const skyGeometry = new THREE.SphereGeometry(1000, 60, 60);const skyTexture = textureLoader.load('../../../../public/textures/sky.jpg'); // 天空纹理const skyMaterial = new THREE.MeshBasicMaterial({map: skyTexture // 颜色贴图});const sky = new THREE.Mesh(skyGeometry, skyMaterial);scene.add(sky);

在这里插入图片描述
将球体反转

将球体进行反转,使其球里面是亮的外面是黑的

// 反转球体,主要是反转z轴
skyGeometry.scale(1, 1, -1);

在这里插入图片描述
注: 天空贴图有点问题,不是完全的360度,会出现重合的问题
在这里插入图片描述
将天空贴图替换为视频纹理
图片中云是静态的,可以通过替换为视频纹理来解决这个问题。

 // 添加视频纹理const skyVideo = document.createElement('video');skyVideo.src = '../../../../public/textures/sky.mp4';skyVideo.loop = true; // 设置视频循环播放// 添加鼠标点击事件,当鼠标点击时开始播放视频window.addEventListener('click', () => {if (skyVideo.paused && skyVideo.readyState === 4) {skyVideo.play();// 更新材质skyMaterial.map = new THREE.VideoTexture(skyVideo);skyMaterial.map.needsUpdate = true;}});

在这里插入图片描述

水面和小岛

创建水面

// 导入水面
import { Water } from 'three/examples/jsm/objects/Water2';// 创建水面const waterGeometry = new THREE.CircleGeometry(300, 30);const water = new Water(waterGeometry, {// 材质宽高textureWidth: 1024,textureHeight: 1024,// 水面颜色color: 0xeeeeff,// 水面流动的方向flowDirection: new THREE.Vector2(1, 1),// 波纹大小scale: 1});// 水面旋转至水平water.rotation.x = -Math.PI / 2;// 添加水面scene.add(water);

感觉我这个水面乖乖的
在这里插入图片描述

添加小岛

// 导入gltf模型加载库
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 导入模型解压库
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';// 添加小岛const loader = new GLTFLoader();const dracoLoader = new DRACOLoader();// 设置路径dracoLoader.setDecoderPath('../../../../public/draco/');// 设置加载器loader.setDRACOLoader(dracoLoader);loader.load('../../../../public/island2.glb', gltf => {scene.add(gltf.scene);});

在这里插入图片描述
场景是黑色的是因为我们没有设置环境纹理,没有环境反射的光,所以看不见场景。另外我们的天空贴图只是普通的图片,是无法反射光的,还需要导入hdr的环境纹理

import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';// 导入hdr环境纹理
const hdrLoader = new RGBELoader();
hdrLoader.loadAsync('../../../../public/050.hdr').then((texture) => {// 设置纹理映射texture.mapping = THREE.EquirectangularReflectionMapping;// 设置环境背景和环境纹理scene.background = texture;scene.environment = texture;});

在这里插入图片描述

添加平行光
添加平行光,让模型更亮一点。如果只添加平行光不添加环境光也可以看见模型,但是平行光照射不到的地方,模型依然是黑色的,因此环境光还是很重要的。

 // 添加平行光const light = new THREE.DirectionalLight(0xffffff, 1);light.position.set(100, 100, 10);scene.add(light);

最终效果

总感觉怪怪的,好像是电脑渲染的问题吧,显得有点呆😳
在这里插入图片描述
完整代码

<template><div class="container" id="container"></div>
</template><script setup lang="ts">
import { onMounted } from 'vue';
// 引入threejs
import * as THREE from 'three';
// 导入轨道控制器,模块化开发导入的是jsm不是js
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 导入水面
import { Water } from 'three/examples/jsm/objects/Water2';
// 导入gltf模型加载库
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 导入模型解压库
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';onMounted(() => {// 创建场景const scene = new THREE.Scene();// 创建透视相机,通过相机来观察const camera = new THREE.PerspectiveCamera(75, // 角度window.innerWidth / window.innerHeight, // 长宽比1, // 近端2000 // 远端);// 设置相机的位置camera.position.set(-50, 50, 130);// 设置摄像机视锥体的长宽比camera.aspect = window.innerWidth / window.innerHeight;// 更新摄像头投影矩阵camera.updateProjectionMatrix();// 将相机添加到场景中scene.add(camera);// 初始化渲染器const renderer = new THREE.WebGLRenderer({antialias: true, // 抗锯齿logarithmicDepthBuffer: true // 对数深度缓冲区});// 设置渲染的尺寸renderer.setSize(window.innerWidth, window.innerHeight);// 设置渲染的输出编码renderer.outputEncoding = THREE.sRGBEncoding;// 将wbgl渲染的canvas内容添加到dom元素中document.getElementById('container')?.appendChild(renderer.domElement);// 使用渲染器,通过相机将场景渲染进来renderer.render(scene, camera);// 监听平面大小的改变,修改相机的比例、渲染器的宽高window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);});// 创建轨道控制器const controls = new OrbitControls(camera, renderer.domElement);// 设置控制器阻尼,让物体拥有惯性,必须在动画循环里调用update()controls.enableDamping = true;// 添加坐标辅助器// const axesHelper = new THREE.AxesHelper(100);// scene.add(axesHelper);// 创建一个渲染函数,当场景发生变化后重新渲染const render = () => {controls.update();renderer.render(scene, camera);// 使用浏览器自带的请求动画帧函数不断的进行渲染requestAnimationFrame(render);};render();/** ******************创建物体的相关逻辑开始**************************** */// 创建纹理加载器const textureLoader = new THREE.TextureLoader();// 创建天空球const skyGeometry = new THREE.SphereGeometry(1000, 60, 60);const skyTexture = textureLoader.load('../../../../public/textures/sky.jpg'); // 天空纹理const skyMaterial = new THREE.MeshBasicMaterial({map: skyTexture // 颜色贴图});// 反转球体,主要是反转z轴skyGeometry.scale(1, 1, -1);const sky = new THREE.Mesh(skyGeometry, skyMaterial);scene.add(sky);// 添加视频纹理const skyVideo = document.createElement('video');skyVideo.src = '../../../../public/textures/sky.mp4';skyVideo.loop = true; // 设置视频循环播放// 添加鼠标点击事件,当鼠标点击时开始播放视频window.addEventListener('click', () => {if (skyVideo.paused && skyVideo.readyState === 4) {skyVideo.play();// 更新材质const texture = new THREE.VideoTexture(skyVideo);skyMaterial.map = texture;skyMaterial.map.needsUpdate = true;}});// 导入hdr环境纹理const hdrLoader = new RGBELoader();hdrLoader.loadAsync('../../../../public/050.hdr').then((texture) => {// 设置纹理映射texture.mapping = THREE.EquirectangularReflectionMapping;// 设置环境背景和环境纹理scene.background = texture;scene.environment = texture;});// 添加平行光const light = new THREE.DirectionalLight(0xffffff, 1);light.position.set(100, 100, 10);scene.add(light);// 创建水面const waterGeometry = new THREE.CircleGeometry(300, 30);const water = new Water(waterGeometry, {// 材质宽高textureWidth: 1024,textureHeight: 1024,// 水面颜色color: 0xeeeeff,// 水面流动的方向flowDirection: new THREE.Vector2(1, 1),// 波纹大小scale: 1});// 水面旋转至水平water.rotation.x = -Math.PI / 2;// 调整水面的位置,使水面能够掩盖一部分模型water.position.y = 3;// 添加水面scene.add(water);// 添加小岛const loader = new GLTFLoader();const dracoLoader = new DRACOLoader();// 设置路径dracoLoader.setDecoderPath('../../../../public/draco/');// 设置加载器loader.setDRACOLoader(dracoLoader);loader.load('../../../../public/island2.glb', gltf => {scene.add(gltf.scene);});/** ********************创建物体的相关逻辑结束********************************/
});
</script>

这篇关于threejs视频教程学习(5):水天一色小岛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/595826

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个