当前位置:网站首页>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
边栏推荐
- Is there a sudden failure on the line? How to make emergency diagnosis, troubleshooting and recovery
- DMX parameter exploration of grandma2 onpc 3.1.2.5
- [wp]bmzclub writeup of several questions
- 已解决(sqlalchemy+pandas.read_sql)AttributeError: ‘Engine‘ object has no attribute ‘execution_options‘
- Rust blockchain development - signature encryption and private key public key
- NEW:Devart dotConnect ADO. NET
- [software reverse analysis tool] disassembly and decompilation tool
- @Transactional 注解导致跨库查询失效的问题
- An elegant program for Euclid‘s algorithm
- Yuancosmic ecological panorama [2022 latest]
猜你喜欢
“金九银十”是找工作的最佳时期吗?那倒未必
Interview summary: This is a comprehensive & detailed Android interview guide
Yuancosmic ecological panorama [2022 latest]
ABP vNext microservice architecture detailed tutorial - distributed permission framework (Part 1)
Test d'automatisation de l'interface utilisateur télécharger manuellement le pilote du navigateur à partir de maintenant
CTF stegano practice stegano 9
Rust区块琏开发——签名加密与私钥公钥
@Transactional 注解导致跨库查询失效的问题
Rust blockchain development - signature encryption and private key public key
Quick start of UI component development of phantom engine [umg/slate]
随机推荐
[understand series after reading] 6000 words teach you to realize interface automation from 0 to 1
阿里云ECS使用cloudfs4oss挂载OSS
我就一写代码的,王总整天和我谈格局...
Why is there a reincarnation of 60 years instead of 120 years in the tiangan dizhi chronology
provide/inject
@Transactional 注解导致跨库查询失效的问题
技术教程:如何利用EasyDSS将直播流推到七牛云?
Phpmailer reported an error: SMTP error: failed to connect to server: (0)
MindFusion.Virtual Keyboard for WPF
我国算力规模排名全球第二:计算正向智算跨越
UI automation test farewell to manual download of browser driver
Interview summary: This is a comprehensive & detailed Android interview guide
What is test development? Why do so many companies hire test developers now?
陇原战“疫“2021网络安全大赛 Web EasyJaba
ABP vNext microservice architecture detailed tutorial - distributed permission framework (Part 2)
[wp][introduction] brush weak type questions
What is the reason why the webrtc protocol video cannot be played on the easycvr platform?
Use of vscode software
Timing manager based on C #
面试字节,过关斩将直接干到 3 面,结果找了个架构师来吊打我?