当前位置: 首页 > news >正文

学习threejs,使用粒子实现雨滴特效

在这里插入图片描述

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


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.Points简介
      • 1.11 ☘️THREE.PointCloudMaterial材质
  • 二、🍀使用THREE.Points批量管理粒子
    • 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.PointCloudMaterial材质

概念
设置所有粒子的大小,颜色,顶点颜色,透明度,是否根据相机距离的远近改变大小等属性。
var material = new THREE.PointCloudMaterial({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:是否受场景的雾化影响。

二、🍀使用THREE.Points批量管理粒子

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.PointCloudMaterial点云材质,该材质使用“rain.png”图片作为纹理,创建render下雨动画,使用requestAnimationFrame执行下雨动画。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>learn31(使用粒子实现雨滴特效)</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 = function () {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, 0, 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 controlsvar initControls = () => {controls = new THREE.OrbitControls(camera, renderer.domElement)controls.enableDamping = truecontrols.autoRotate = false}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/rain.png')var geom = new THREE.Geometry()var material = new THREE.PointCloudMaterial({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(range * Math.random() - range / 2, range * Math.random() - range / 2, range * Math.random() - range / 2)particle.velocityY = 0.1 + Math.random() / 5particle.velocityX = (Math.random() - 0.5) / 3geom.vertices.push(particle)geom.colors.push(new THREE.Color(0xffffff))}cloud = new THREE.Points(geom, material)cloud.verticesNeedUpdate = truescene.add(cloud)}var statsvar initStats = () => {stats = new Stats()document.body.appendChild(stats.dom)}var render = () => {//产生雨滴动画效果var vertices = cloud.geometry.verticesvertices.forEach(function (v) {v.y = v.y - (v.velocityY) * 3v.x = v.x - (v.velocityX) * .5if (v.y <= -60) v.y = 60;if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1})//设置实时更新网格的顶点信息cloud.geometry.verticesNeedUpdate = truerenderer.render(scene, camera)}var onWindowResize = () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()render()renderer.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.lryc.cn/news/470765.html

相关文章:

  • 分布式-单元化架构1
  • C++模板、STL
  • 计算机视觉中的点算子:从零开始构建
  • 国际中文教育知识图谱问答
  • 酒店大板轻触开关与传统的开关有什么区别
  • 【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析
  • 对比两个json串的diff,支持map的深度递归
  • 【我的创作纪念日1024】
  • 萤石设备视频接入平台EasyCVR私有化视频平台变电站如何实现远程集中监控?
  • 什么是多线程?请描述 Java 中实现多线程的基本方式?
  • Dynamic Sparse No Training: Training-Free Fine-tuning for Sparse LLMs
  • 解决n+1查询数据库问题
  • DICOM 基础知识:深入理解DICOM数据结构与标签说明
  • Git - 如何删除 push 过一次的文件链路追踪?
  • 软件测试学习总结
  • c语言错题——#define对应的查找替换
  • Visual Basic介绍及简单例子
  • Matlab学习01-矩阵
  • 【复旦微FM33 MCU 外设开发指南】外设篇1——硬件除法器
  • 在元神操作系统启动时自动执行任务脚本
  • JAVA学习-练习试用Java实现“判断是否为等边三角形的方法”
  • Leetcode 140 Word Break II
  • 文理学院数据库应用技术实验报告0
  • Bootstrap 4 按钮
  • 【笔记】LLM位置编码之标准位置编码
  • 环 境 配 置
  • 理解dbt artifacts及其实际应用
  • 100种算法【Python版】第15篇——KMP算法
  • 【软件工程】软件项目管理/工程项目管理复习资料
  • C语言基础题(大合集2)