当前位置:网站首页>Threejs realizes rain, snow, overcast, sunny, flame
Threejs realizes rain, snow, overcast, sunny, flame
2022-07-05 04:00:00 【Zuo Ben】
1, Introduce
This example uses r95 edition Three.js library . Use Threejs Particle effect realizes rain , snow , overcast , a sunny day , flame .
The renderings are as follows :
2, Main description
overcast , Sunny way , Mainly to replace the background image of the scene .
It's raining 、 snow 、 Flame is mainly realized by particles , There are two ways to create particles :
1, Use THREE.Points Create a collection of particles , Use THREE.PointsMaterial To style particles .
2, Use Three.Sprite() Constructors create particles manually . The only parameter we pass in is material , It can only be THREE.SpriteMaterial or THREE.SpriteCanvasMaterial.
Sprite Suitable for creating a small number of particles , If you want to create a large number of particles, you should use Points.
I'm going to use Points Realize rain and snow , The main codes are as follows :
function createPointRainy() {
var img = rainy_sw == 1 ? "raindrop-4.png" : rainy_sw == 2 ? "snowflake3.png" : "";
var name = rainy_sw == 1 ? "particles_rainy" : rainy_sw == 2 ? "particles_snowy" : "";
var texture = new THREE.TextureLoader().load("assets/textures/particles/" + img);
var geom = new THREE.Geometry();
var material = new THREE.PointsMaterial({
size: 1.5,
transparent: true, // Whether to set transparency
opacity: 1, // transparent
map: texture, // Particle material
blending: THREE.AdditiveBlending,
sizeAttenuation: true, // Is it the same size
color: 0xffffff
});
var range = 120;
for (var i = 0; i < 1500; i++) {
var particle = new THREE.Vector3(
Math.random() * range - range / 2,
Math.random() * range * 1.5,
1 + (i / 10 - 80)
)
if (rainy_sw == 2) {
// Define how fast raindrops fall , The range of longitudinal motion speed is 0.1~0.3
particle.velocityY = (0.1 + Math.random() / 5) - 0.1;
// Define particles ( Raindrop ) How to move horizontally , The range of lateral motion speed is -0.16~+0.16
particle.velocityX = ((Math.random() - 0.5) / 3) - 0.05;
} else {
particle.velocityY = 0.15 + Math.random() / 5;
particle.velocityX = (Math.random() - 0.5) / 3;
}
geom.vertices.push(particle);
}
cloud = new THREE.Points(geom, material);
cloud.sortParticles = true;
cloud.name = name;
scene.add(cloud);
}
Use Sprite Achieve flame effect , The main codes are as follows :
function initFlame() {
var texture = new THREE.TextureLoader().load("assets/textures/particles/flamex.png");
//sprite texture of material
var material = new THREE.SpriteMaterial({
// With canvas As texture
map: texture,
// Mixing degree Add and mix
blending: THREE.AdditiveBlending
});
// loop 1000 Add particles
for (var i = 0; i < 2000; i++) {
var particle = new THREE.Sprite(material);
initParticle(particle, i);
krq.add(particle);
krq.name = "particles_flame";
}
scene.add(krq);
}
3, Source code
<!DOCTYPE html>
<html>
<head>
<title>Threejs Realize rain , snow , overcast , a sunny day , flame </title>
<script type="text/javascript" src="libs/three.js"></script>
<script type="text/javascript" src="libs/OrbitControls.js"></script>
<script type="text/javascript" src="libs/OBJLoader.js"></script>
<script type="text/javascript" src="libs/other/Tween.min.js"></script>
<script type="text/javascript" src="libs/dat.gui.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="dom"></div>
<script type="text/javascript">
var camera;
var renderer;
var cloud;
var rainy_sw = 3; // 1 rain 2 snow 3 Fine 4 Yin
var flame_sw = true;
// Initialize an empty container , Loading particles
var krq = new THREE.Object3D();
var textureLoader = new THREE.TextureLoader();
function init() {
// Create a scene , It will contain all our elements , Like an object , Cameras and lights .
var scene = new THREE.Scene();
var urls = [
'assets/textures/cubemap/flowers/posx.jpg',
'assets/textures/cubemap/flowers/negx.jpg',
'assets/textures/cubemap/flowers/posy.jpg',
'assets/textures/cubemap/flowers/negy.jpg',
'assets/textures/cubemap/flowers/posz.jpg',
'assets/textures/cubemap/flowers/negz.jpg'
];
var urls1 = [
'assets/textures/cubemap/flowers/posx1.jpg',
'assets/textures/cubemap/flowers/negx1.jpg',
'assets/textures/cubemap/flowers/posy1.jpg',
'assets/textures/cubemap/flowers/negy1.jpg',
'assets/textures/cubemap/flowers/posz1.jpg',
'assets/textures/cubemap/flowers/negz1.jpg'
];
var cubeLoader = new THREE.CubeTextureLoader();
scene.background = cubeLoader.load(urls);
// Create a camera , It defines where we are looking
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// Aim the camera at the center of the scene
camera.position.x = 10;
camera.position.y = 50;
camera.position.z = 90;
camera.lookAt(scene.position);
var orbit = new THREE.OrbitControls(camera);
// Create a renderer and set the size ,WebGLRenderer The computer graphics card will be used to render the scene
renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true,
});
renderer.setClearColor(new THREE.Color(0x121A39));
renderer.setSize(window.innerWidth, window.innerHeight);
var alight = new THREE.AmbientLight("#ffffff", 1);
alight.name = "aLight";
scene.add(alight);
// Display the coordinate axis on the screen
var axes = new THREE.AxesHelper(100);
// scene.add(axes);
// Add planes to the scene
createPlaneGeometryBasicMaterial();
// Add the output of the renderer to HTML Elements
document.getElementById("dom").appendChild(renderer.domElement);
// Use GUI Debug library
var controls = new function() {
this.rainy = function() {
scene.remove(scene.getObjectByName("particles_snowy"));
if (rainy_sw != 1) {
rainy_sw = 1;
scene.background = cubeLoader.load(urls1);
scene.getObjectByName("aLight").intensity = 0.6;
createPointRainy();
}
}
this.snowy = function() {
scene.remove(scene.getObjectByName("particles_rainy"));
if (rainy_sw != 2) {
rainy_sw = 2;
scene.background = cubeLoader.load(urls1);
scene.getObjectByName("aLight").intensity = 2;
createPointRainy();
}
}
this.sunny = function() {
if (rainy_sw != 3) {
scene.remove(scene.getObjectByName("particles_rainy"));
scene.remove(scene.getObjectByName("particles_snowy"));
scene.background = cubeLoader.load(urls);
scene.getObjectByName("aLight").intensity = 1.2;
rainy_sw = 3;
}
}
this.cloudy = function() {
if (rainy_sw != 4) {
scene.remove(scene.getObjectByName("particles_rainy"));
scene.remove(scene.getObjectByName("particles_snowy"));
scene.background = cubeLoader.load(urls1);
scene.getObjectByName("aLight").intensity = 1;
rainy_sw = 4;
}
}
this.flame = function() {
if (flame_sw) {
initFlame();
flame_sw = !flame_sw;
}
}
}
var gui = new dat.GUI();
gui.add(controls, 'rainy'); // rain
gui.add(controls, 'snowy'); // snow
gui.add(controls, 'sunny'); // Fine
gui.add(controls, 'cloudy'); // Yin
gui.add(controls, 'flame'); // flame
// Start animation
renderScene();
function createPointRainy() {
var img = rainy_sw == 1 ? "raindrop-4.png" : rainy_sw == 2 ? "snowflake3.png" : "";
var name = rainy_sw == 1 ? "particles_rainy" : rainy_sw == 2 ? "particles_snowy" : "";
var texture = new THREE.TextureLoader().load("assets/textures/particles/" + img);
var geom = new THREE.Geometry();
var material = new THREE.PointsMaterial({
size: 1.5,
transparent: true, // Whether to set transparency
opacity: 1, // transparent
map: texture, // Particle material
blending: THREE.AdditiveBlending,
sizeAttenuation: true, // Is it the same size
color: 0xffffff
});
var range = 120;
for (var i = 0; i < 1500; i++) {
var particle = new THREE.Vector3(
Math.random() * range - range / 2,
Math.random() * range * 1.5,
1 + (i / 10 - 80)
)
if (rainy_sw == 2) {
// Define how fast raindrops fall , The range of longitudinal motion speed is 0.1~0.3
particle.velocityY = (0.1 + Math.random() / 5) - 0.1;
// Define particles ( Raindrop ) How to move horizontally , The range of lateral motion speed is -0.16~+0.16
particle.velocityX = ((Math.random() - 0.5) / 3) - 0.05;
} else {
particle.velocityY = 0.15 + Math.random() / 5;
particle.velocityX = (Math.random() - 0.5) / 3;
}
geom.vertices.push(particle);
}
cloud = new THREE.Points(geom, material);
cloud.sortParticles = true;
cloud.name = name;
scene.add(cloud);
}
function initFlame() {
var texture = new THREE.TextureLoader().load("assets/textures/particles/flamex.png");
//sprite texture of material
var material = new THREE.SpriteMaterial({
// With canvas As texture
map: texture,
// Mixing degree Add and mix
blending: THREE.AdditiveBlending
});
// loop 1000 Add particles
for (var i = 0; i < 2000; i++) {
var particle = new THREE.Sprite(material);
initParticle(particle, i);
krq.add(particle);
krq.name = "particles_flame";
}
scene.add(krq);
}
/**
* The particle Delay divergence
* @param particle
* @param delay
*/
function initParticle(particle, delay) {
particle.position.set(5, Math.random() + 5, 0);
particle.scale.x = particle.scale.y = Math.random() * 3;
// Here is a series of animations
var xx = Math.random() * 10 - 5;
var yy = Math.cos((Math.PI / 100) * xx) * 20;
// Displacement
new TWEEN.Tween(particle.position)
.delay(delay)
.to({
x: xx,
y: yy,
z: Math.random() * 10 - 5
}, 2000)
.onComplete(function() {
initParticle(particle, delay);
})
.start();
// size
new TWEEN.Tween(particle.scale)
.delay(delay)
.to({
x: 0.01,
y: 0.01
}, 1000)
.start();
}
/**
* Create the ground and add materials
* wrapS Attributes define the texture along x Axial behavior , and warpT Attributes define the texture along y Axial behavior .
* Three.js The following two options are provided for these attributes :
* ·THREE.RepeatWrapping Allow the texture to repeat itself .
* ·THREE.ClampToEdgeWrapping Is the default value of the attribute .
* The property value is THREE.ClampToEdgeWrapping when , Then the whole texture will not repeat , Only the pixels at the edge of the texture will be repeated to fill the remaining space .
*/
function createPlaneGeometryBasicMaterial() {
var cubeMaterial = new THREE.MeshStandardMaterial({
map: textureLoader.load("assets/textures/stone/cd.jpg"),
side: THREE.DoubleSide,
});
cubeMaterial.map.wrapS = THREE.RepeatWrapping;
cubeMaterial.map.wrapT = THREE.RepeatWrapping;
cubeMaterial.map.repeat.set(3, 3)
// Create the ground plane and set the size
var planeGeometry = new THREE.PlaneGeometry(100, 100);
var plane = new THREE.Mesh(planeGeometry, cubeMaterial);
// Set the plane position and rotate
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.z = -5;
plane.position.y = -5;
scene.add(plane);
}
function renderScene() {
orbit.update(); // Drag the
TWEEN.update();
if (cloud) {
var vertices = cloud.geometry.vertices;
vertices.forEach(function(v) {
v.y = v.y - (v.velocityY);
v.x = v.x - (v.velocityX);
if (v.y <= 0) v.y = 60;
if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1;
});
cloud.geometry.verticesNeedUpdate = true;
}
// Use requestAnimationFrame Function to render
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
}
// Rendered scenes
renderer.render(scene, camera);
}
window.onload = init;
// Modify the scene as the form changes
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Listen for form resizing events
window.addEventListener('resize', onResize, false);
</script>
</body>
</html>
If you need a complete code, please leave a message or contact me
边栏推荐
- How to solve the problem that easycvr changes the recording storage path and does not generate recording files?
- Is there a sudden failure on the line? How to make emergency diagnosis, troubleshooting and recovery
- 花了2晚,拿到了吴恩达@斯坦福大学的机器学习课程证书
- Summary of scene design
- PlasticSCM 企业版Crack
- 面试字节,过关斩将直接干到 3 面,结果找了个架构师来吊打我?
- Use object composition in preference to class inheritance
- Installation of postman and postman interceptor
- 我国算力规模排名全球第二:计算正向智算跨越
- grandMA2 onPC 3.1.2.5的DMX参数摸索
猜你喜欢
面试字节,过关斩将直接干到 3 面,结果找了个架构师来吊打我?
函数基础学习02
How is the entered query SQL statement executed?
Containerd series - what is containerd?
A brief introduction to the behavior tree of unity AI
[wp]bmzclub writeup of several questions
MindFusion.Virtual Keyboard for WPF
[brush questions] BFS topic selection
Rome链分析
Plasticscm enterprise crack
随机推荐
Analysis of glibc strlen implementation mode
ActiveReportsJS 3.1 VS ActiveReportsJS 3.0
Operation flow of UE4 DMX and grandma2 onpc 3.1.2.5
lds链接的 顺序问题
为什么百度、阿里这些大厂宁愿花25K招聘应届生,也不愿涨薪5K留住老员工?
An elegant program for Euclid‘s algorithm
[数组]566. 重塑矩阵-简单
【PHP特性-变量覆盖】函数的使用不当、配置不当、代码逻辑漏洞
Is there a sudden failure on the line? How to make emergency diagnosis, troubleshooting and recovery
[web Audit - source code disclosure] obtain source code methods and use tools
[software reverse analysis tool] disassembly and decompilation tool
Summary of scene design
技术教程:如何利用EasyDSS将直播流推到七牛云?
NEW:Devart dotConnect ADO. NET
如何实现实时音视频聊天功能
Why do big companies such as Baidu and Alibaba prefer to spend 25K to recruit fresh students rather than raise wages by 5K to retain old employees?
postman和postman interceptor的安装
输入的查询SQL语句,是如何执行的?
[vérification sur le Web - divulgation du code source] obtenir la méthode du code source et utiliser des outils
@Transactional 注解导致跨库查询失效的问题