学习threejs,使用粒子实现下雪特效

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.Points简介
      • 1.11 ☘️THREE.PointsMaterial点云材质
  • 二、🍀使用粒子实现下雪特效
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用粒子实现下雪特效,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.Points简介

当我们大量使用粒子时,会很快遇到性能问题,导致页面卡顿,这是因为每添加一个粒子就是一个模型,因为每个粒子对象分别由THREE.js进行管理,所以,three.js提供了另一种方式来处理大量粒子,那就是使用THREE.Points。通过THREE.Points,three.js不再需要管理大量的单个粒子对象,而只需管理THREE.Points实例即可。
创建方法:
var cloud = new THREE.Points(geom, material);
geom:THREE.Geometry对象,用于创建粒子对象
material:THREE.PointCloudMaterial 粒子云材质

1.11 ☘️THREE.PointsMaterial点云材质

概念
设置所有粒子的大小,颜色,顶点颜色,透明度,是否根据相机距离的远近改变大小等属性。
var material = new THREE.PointsMaterial({size: 4, vertexColors: true, color: 0xffffff});
属性
color: PointCloud中所有的粒子的颜色都相同,除非设置了vertexColors且该几何体的colors属性不为空,才会使用colors颜色,否则都使用该属性。
map:在粒子上应用某种材质。
size:粒子的大小。
sizeAnnutation:false,无论相机的位置,所有的粒子大小一致;true,离相机近的粒子更大一些,离相机越远越小。
vetexColors:true,且该几何体的colors属性有值,则该粒子会舍弃第一个属性–color,而应用该几何体的colors属性的颜色。
opacity:粒子透明度。
transparent:是否透明。
blending:渲染粒子时的融合模式。
fog:是否受场景的雾化影响。

二、🍀使用粒子实现下雪特效

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set,定义相机方向lookAt。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.DirectionalLight平行光源,设置平行光源位置,scene添加平行光源。
  • 5、加载几何模型:添加THREE.AxesHelper坐标辅助工具,scene场景中加入坐标辅助工具。
  • 6、加入controls控制,加入gui控制,定义gui的redraw重绘方法,方法中生成15000个随机粒子,使用THREE.PointMaterial点云材质,该材质使用“snow.png”图片作为纹理,创建render下雨动画,使用requestAnimationFrame执行下雨动画。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>learn32(使用粒子实现下雪特效)</title><script src="lib/threejs/91/three.js"></script><script src="https://johnson2heng.github.io/three.js-demo/lib/js/controls/OrbitControls.js"></script><script src="https://johnson2heng.github.io/three.js-demo/lib/js/libs/stats.min.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
</head>
<style>html, body {margin: 0;height: 100%;}canvas {display: block;}
</style>
<body onload="draw()">
</body>
<script>var renderervar initRender = () => {renderer = new THREE.WebGLRenderer({antialias: true})renderer.setClearColor(new THREE.Color(0xffffff))renderer.setSize(window.innerWidth, window.innerHeight)document.body.appendChild(renderer.domElement)}var scenevar initScene = () => {scene = new THREE.Scene()}var cameravar initCamera = () => {camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 200)camera.position.set(0, 20, 100)camera.lookAt(new THREE.Vector3(0, 30, 0))}var lightvar initLight = () => {scene.add(new THREE.AmbientLight(0x404040))light = new THREE.DirectionalLight(0xffffff)light.position.set(1, 1, 1)scene.add(light)}var initModel = () => {var helper = new THREE.AxesHelper(500)scene.add(helper)}var statsvar initStats = () => {stats = new Stats()document.body.appendChild(stats.dom)}var controlsvar initControls = () => {controls = new THREE.OrbitControls(camera, renderer.domElement)controls.enableDamping = truecontrols.autoRotate = false}var render = () => {//产生雨滴动画效果var vertices = cloud.geometry.verticesvertices.forEach(function (v) {v.y = v.y - (v.velocityY)v.x = v.x - (v.velocityX) * .5if (v.y <= -60) v.y = 60if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1})//设置实时更新网格的顶点信息cloud.geometry.verticesNeedUpdate = truerenderer.render(scene, camera)}var gui, cloudvar initGui = () => {gui = {"size": 2,"transparent": true,"opacity": 0.6,"vertexColors": true,"color": 0xffffff,"sizeAttenuation": true,"rotateSystem": false,redraw: function () {if (cloud) {scene.remove(cloud)}createParticles(gui.size, gui.transparent, gui.opacity, gui.vertexColors, gui.sizeAttenuation, gui.color)//设置是否自动旋转controls.autoRotate = gui.rotateSystem}}var datGui = new dat.GUI()//将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)gui.add(controls, 'size', 0, 10).onChange(controls.redraw);datGui.add(gui, 'size',0.1,10).onChange(gui.redraw)datGui.add(gui, 'transparent').onChange(gui.redraw)datGui.add(gui, 'opacity', 0, 1).onChange(gui.redraw)datGui.add(gui, 'vertexColors').onChange(gui.redraw)datGui.addColor(gui, 'color').onChange(gui.redraw)datGui.add(gui, 'sizeAttenuation').onChange(gui.redraw)datGui.add(gui, 'rotateSystem').onChange(gui.redraw)gui.redraw()}var createParticles = (size, transparent, opacity, vertexColors, sizeAttenuation, color) => {var texture = new THREE.TextureLoader().load('data/img/snow.png')var geom = new THREE.Geometry()var material = new THREE.PointsMaterial({size: size,transparent: transparent,opacity: opacity,vertexColors: vertexColors,sizeAttenuation: sizeAttenuation,color: color,map: texture,depthTest: false  //设置解决透明度有问题的情况})var range = 120for (var i = 0; i < 15000; i++) {var particle = new THREE.Vector3(Math.random() * range - range / 2, Math.random() * range - range / 2, Math.random() * range - range / 2)particle.velocityY = 0.1 + Math.random() / 5particle.velocityX = (Math.random() - 0.5) / 3geom.vertices.push(particle)var color = new THREE.Color(0xffffff)//.setHSL ( h, s, l ) h — 色调值在0.0和1.0之间 s — 饱和值在0.0和1.0之间 l — 亮度值在0.0和1.0之间。 使用HSL设置颜色。//随机当前每个粒子的亮度//color.setHSL(color.getHSL().h, color.getHSL().s, Math.random() * color.getHSL().l);geom.colors.push(color)}cloud = new THREE.Points(geom, material)cloud.verticesNeedUpdate = truescene.add(cloud)}var onWindowResize = () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()render()render.setSize(window.innerWidth, window.innerHeight)}var animate = () => {render()stats.update()controls.update()requestAnimationFrame(animate)}var draw = () => {initRender()initScene()initCamera()initLight()initModel()initStats()initControls()initGui()animate()window.onresize = onWindowResize}
</script>
</html>

效果如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第517题超级洗衣机

题目&#xff1a; 题解&#xff1a; func findMinMoves(machines []int) (ans int) {tot : 0for _, v : range machines {tot v}n : len(machines)if tot%n > 0 {return -1}avg : tot / nsum : 0for _, num : range machines {num - avgsum numans max(ans, max(abs(sum…

算法练习:209. 长度最小的子数组

题目链接&#xff1a;209. 长度最小的子数组。 这里ans来统计最小长度&#xff0c;所以初始值设置为INT_MAX.最后如果ans结果还是INT_MAX时&#xff0c;说明无此数组。 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {if (nums.size(…

WPF+MVVM案例实战(十一)- 环形进度条实现

文章目录 1、运行效果2、功能实现1、文件创建与代码实现2、角度转换器实现3、命名空间引用 3、源代码下载 1、运行效果 2、功能实现 1、文件创建与代码实现 打开 Wpf_Examples 项目&#xff0c;在Views 文件夹下创建 CircularProgressBar.xaml 窗体文件。 CircularProgressBa…

《贪婪算法实战:寻找最短无序连续子数组的深度解析与实现》

🚀 博主介绍:大家好,我是无休居士!一枚任职于一线Top3互联网大厂的Java开发工程师! 🚀 🌟 在这里,你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人,我不仅热衷于探索一些框架源码和算法技巧奥秘,还乐于分享这些宝贵的知识和经验。 💡 无论你是刚刚踏…

堆的基本概念和插入删除方法的介绍

优先级队列的介绍&#xff1a; 1.1优先级队列&#xff1a;优先级队列是一种特殊的队列数据结构&#xff0c;每个元素都有一个与之关联的优先级&#xff0c;与普通队列不同&#xff0c;优先级队列中的元素是按照优先级顺序进行处理的&#xff0c;而不是简单的插入。 特点&…

雷军:对“雷军语音包”感到不适,希望停止使用

对于社交媒体上频繁出现的“雷军AI语音包”&#xff0c;雷军发声回应。10月29日&#xff0c;雷军发布视频表示&#xff1a;“最近两年AI特别火&#xff0c;技术进步特别得快&#xff0c;前段时间我在刷抖音的时候&#xff0c;经常看到很多人在玩‘雷军AI’&#xff0c;就是雷军…

分布式光伏是什么意思?如何高效管理?

分布式光伏系统是指在用户现场或靠近用电现场配置较小的光伏发电供电系统&#xff0c;以满足特定用户的需求。根据通知&#xff0c;分布式光伏系统主要有以下几类定义&#xff1a; 10kV以下电压等级接入&#xff0c;且单个并网点总装机容量不超过6MW的分布式电源&#xff1a;这…

项目1 yolov5鱼苗检测计数

yolov5鱼苗检测 1. yolov5鱼苗检测1.1. 环境配置1.2 Predict1.3 Validate1.4 Train1.5 生成 ONNX 2 代码解析2.1 模型2.2 数据集2.3 损失函数2.4 训练2.5 预测 之前做的项目&#xff0c;再回顾一下 环境&#xff1a;GPU1卡&#xff0c;CPU4核&#xff0c;每显卡12GB&#xff0c…

智能文档处理平台:免费体验智能化医疗信息提取

前提&#xff1a;医疗行业信息碎片化问题普遍&#xff0c;手工数据录入效率低且易错&#xff0c;导致数据管理难度大。本系统可帮助医疗机构在信息管理上迈向智能化&#xff0c;优化流程并提升效率。 系统概述&#xff1a; 思通数科推出的智能文档处理系统&#xff0c;专为解…

解决edge浏览器无法同步问题

有时候电脑没带&#xff0c;但是浏览器没有同步很烦恼。chrome浏览器的同步很及时在多设备之间能很好使用。但是edge浏览器同步没反应。 在这里插入图片描述 解决方法&#xff1a; 一、进入edge浏览器点击图像会显示未同步。点击“管理个人资料”&#xff0c;进入后点击同步&…

python代码中通过pymobiledevice3访问iOS沙盒目录获取app日志

【背景】 在进行业务操作过程中&#xff0c;即在app上的一些操作&#xff0c;在日志中会有对应的节点&#xff0c;例如&#xff0c;下面是查看设备实时视频过程对应的一些关键节点&#xff1a; 1、TxDeviceAwakeLogicHelper&#xff1a;wakeStart deviceId CxD2BA11000xxxx …

网络编程_day6

目录 【0】复习 并发服务器实现思路梳理 多进程 多线程 IO多路复用select 【1】setsockopt&#xff1a;设置套接字属性 socket属性 设置地址重用 【2】超时检测 必要性 超时检测的设置方法 1. 通过函数自带的参数设置 2. 通过设置套接字属性进行设置 3. alarm函数与sigaction函…

GPT-Sovits-1-数据处理

1.1 切割音频 将音频切割为多个10s内的片段 1.2 降噪 这一步用的是modelscope的pipeline 如果要去除背景音&#xff0c;可以用傅立叶转为为频谱&#xff0c;去除低频部分后再转回来 1.3 提取音频特征 这里用到了 funasr 库 这一步目的是输出音频样本的《文本标签文件》&am…

Linux——常见指令及其权限理解(正在更新中)

1.指令 1.1 快速了解指令 pwd 首次登录&#xff0c;默认所处的路径 whoami 当前所用的用户的名称 ls 显示当前路径下&#xff0c;文件名称 mkdir 在当前目录下&#xff0c;创建一个文件夹/目录 cd 进入一个目录 touch 新建一个文…

Kafka 物理存储机制

优质博文&#xff1a;IT-BLOG-CN 一个商业化消息队列的性能好坏&#xff0c;其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一。下面将从Kafka文件存储机制和物理结构角度&#xff0c;分析Kafka是如何实现高效文件存储&#xff0c;及实际应用效果。Kafka的基…

采用STM32CubeMX和HAL库的定时器应用实例

目录 STM32的通用定时器配置流程 定时器应用的硬件设计 定时器应用的软件设计 1. 通过STM32CubeMX新建工程 通过STM32CubeMX新建工程的步骤如下&#xff1a; 2. 通过Keil MDK实现工程 通过Keil MDK实现工程的步骤如下&#xff1a; STM32的通用定时器配置流程 通用定时器…

【优选算法篇】前缀之序,后缀之章:于数列深处邂逅算法的光与影

文章目录 C 前缀和详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;前缀和基础应用1.1 一维前缀和模板题解法&#xff08;前缀和&#xff09;图解分析C代码实现易错点提示代码解读题目解析总结 1.2 二维前缀和模板题解法&#xff08;二维前缀和&#xff09;图解分析C…

Topaz Video AI for Mac 视频无损放大软件安装教程【保姆级,操作简单轻松上手】

Mac分享吧 文章目录 Topaz Video AI for Mac 视频无损放大软件 安装完成&#xff0c;软件打开效果一、Topaz Video AI 视频无损放大软件 Mac电脑版——v5.3.5⚠️注意事项&#xff1a;1️⃣&#xff1a;下载软件2️⃣&#xff1a;安装软件&#xff0c;将安装包从左侧拖入右侧文…

CNAS软件测试的好处有哪些?上海软件测试中心推荐

在进行软件测试或其他项目检测需要选择软件测试中心时&#xff0c;我们常常会把该公司有无资质认证考虑进去。那么CNAS认可作为检测机构或实验室的一项重要资质认证&#xff0c;我们可能会产生疑问&#xff1a;CNAS认可什么意思?CNAS软件测试又有什么好处呢? 1、CNAS认可是什…

【51 Pandas+Pyecharts | 深圳市共享单车数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 处理起始时间、结束时间2.4 增加骑行时长区间列2.5 增加骑行里程区间列 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 各…