<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type = "text/css">
html, body{
margin: 0;
height: 100%;
}
canvas{
display: block;
}
</style>
</head>
<body onload="draw();">
</body>
<script src="../build/extension/weather.js"></script>
<script src="../build/three.js"></script>
<script src="../build/three.extension.js"></script>
<script src="../build/extension/TerrainControls.js"></script>
<script src="../node_modules/three/examples/js/Detector.js"></script>
<script src="../node_modules/three/examples/js/libs/stats.min.js"></script>
<script src="../THREE.MeshLine/demo/js/dat.gui.min.js"></script>
<script src="../node_modules/three/examples/js/controls/OrbitControls.js"></script>
<script>
var renderer;
var rainSpeed ; //雨下的速度
var rainQuaX; //雨滴X方向
var rainQuaZ; //雨滴Z方向
var rainRange; //雨滴范围
var snowSpeed; //雪花速度
var snowQuaX; //雪花方向X
var snowQuaZ; //雪花方向Z
var snowRange; //雪花范围
var camPosVec = new THREE.Vector3();
var enableView = 0; //场景设置模式,默认0为自由观察下雨下雪场景,1为固定一小块在摄像头前
function initRender(){
//this.render = function ( scene, camera, renderTarget, forceClear )
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
}
var camera;
function initCamera() { //初始化相机
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,1,200);
camera.position.set(0,20,120);
camPosVec.set(0,0,0);
camera.lookAt(new THREE.Vector3(0,30,0));
}
var scene;
function initScene() { //初始化场景
scene = new THREE.Scene();
}
var light;
function initLight(){ //初始化光
scene.add(new THREE.AmbientLight(0x404040));
light = new THREE.DirectionalLight(0xffffff);
light.position.set(1,1,1);
scene.add(light)
}
function initModel(){ //初始化轴辅助
var object = new THREE.AxesHelper(500);
scene.add(object);
}
var stats;
function initStats(){ //初始化性能插件
stats = new Stats();
document.body.appendChild(stats.dom);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls(camera,renderer.domElement);
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = false;
controls.enablePan = true;
}
var rainConGui;
var snowConGui;
var cloudRain;
var cloudSnow;
var disRain;
var disSnow;
function initGuiRain() { //初始化gui
rainConGui = {
"开启下雨" : true,
"雨滴尺寸" : 2,
"背景透明" : true,
"不透明度" : 0.6,
//"vertexColor" : true,
"雨滴速度" : 8,
"雨滴方向X" : 0,
"雨滴方向Z" : 0,
"雨滴颜色" : 0Xffffff,
"雨滴距离" : 90,
//"sizeAttenuation" : true,
//"rotateSystem" : false,
rainRedraw : function () {
if (cloudRain) {
if(enableView ==1 ) {
camera.remove(cloudRain);
}
else{
scene.remove(cloudRain);
}
}
createParticlesRain(rainConGui.开启下雨,rainConGui.雨滴速度, rainConGui.雨滴尺寸, rainConGui.背景透明, rainConGui.不透明度, rainConGui.vertexColors, rainConGui.sizeAttenuation, rainConGui.雨滴方向X, rainConGui.雨滴方向Z, rainConGui.雨滴颜色,rainConGui.雨滴距离);
}
};
var rainDatGui = new dat.GUI();
//将设置属性添加到 rainConGui当中, rainConGui.add(对象,属性,最小值,最大值)
rainDatGui.add( rainConGui,'开启下雨').onChange( rainConGui.rainRedraw);
rainDatGui.add( rainConGui,'雨滴速度',8,20).onChange( rainConGui.rainRedraw);
//datGui.add( rainConGui,'雨滴尺寸',1,10).onChange( rainConGui.redraw);
//datGui.add( rainConGui,'背景透明').onChange( rainConGui.redraw);
//datGui.add( rainConGui,'不透明度',0,1).onChange( rainConGui.redraw);
//datGui.add( rainConGui,'vertexColor').onChange( rainConGui.redraw);
rainDatGui.add( rainConGui,'雨滴方向X',-1,1).onChange( rainConGui.rainRedraw);
rainDatGui.add( rainConGui,'雨滴方向Z',-1,1).onChange( rainConGui.rainRedraw);
rainDatGui.add( rainConGui,'雨滴距离',50,150).onChange( rainConGui.rainRedraw);
//datGui.addColor( rainConGui,'雨滴颜色').onChange( rainConGui.redraw);
//datGui.add( rainConGui,'sizeAttenuation').onChange( rainConGui.redraw);
//datGui.add( rainConGui,'rotateSystem').onChange( rainConGui.redraw);
rainConGui.rainRedraw();
}
function initGuiSnow() { //初始化雪gui
snowConGui = {
"开启下雪" : true,
"雪花尺寸" : 2,
"背景透明" : true,
"不透明度" : 0.6,
//"vertexColor" : true,
"雪花速度" : 0.5,
"雪花方向X" : 0,
"雪花方向Z" : 0,
"雪花颜色" : 0Xffffff,
"雪花距离" : 90,
//"sizeAttenuation" : true,
//"rotateSystem" : false,
snowRedraw : function () {
if (cloudSnow) {
if(enableView == 1) {
camera.remove(cloudSnow);
}else
{
scene.remove(cloudSnow)
}
}
createParticlesSnow(snowConGui.开启下雪,snowConGui.雪花速度, snowConGui.雪花尺寸, snowConGui.背景透明, snowConGui.不透明度, snowConGui.vertexColors, snowConGui.sizeAttenuation, snowConGui.雪花方向X, snowConGui.雪花方向Z, snowConGui.雪花颜色,snowConGui.雪花距离);
}
};
var snowDatGui = new dat.GUI();
//将设置属性添加到 snowConGui当中, snowConGui.add(对象,属性,最小值,最大值)
snowDatGui.add( snowConGui,'开启下雪').onChange( snowConGui.snowRedraw);
snowDatGui.add( snowConGui,'雪花速度',0.5,10).onChange( snowConGui.snowRedraw);
//datGui.add( snowConGui,'雪花尺寸',0.1,10).onChange( snowConGui.redraw);
//datGui.add( snowConGui,'背景透明').onChange( snowConGui.redraw);
//add( snowConGui,'不透明度',0,1).onChange( snowConGui.redraw);
//datGui.add( snowConGui,'vertexColor').onChange( snowConGui.redraw);
snowDatGui.add( snowConGui,'雪花方向X',-1,1).onChange( snowConGui.snowRedraw);
snowDatGui.add( snowConGui,'雪花方向Z',-1,1).onChange( snowConGui.snowRedraw);
snowDatGui.add( snowConGui,'雪花距离',50,150).onChange( snowConGui.snowRedraw);
//datGui.addColor( snowConGui,'雪花颜色').onChange( snowConGui.redraw);
//datGui.add( snowConGui,'sizeAttenuation').onChange( snowConGui.redraw);
//datGui.add( snowConGui,'rotateSystem').onChange( snowConGui.redraw);
snowConGui.snowRedraw();
}
//生成雨滴粒子的方法
function createParticlesRain(enableRain,speed,size, transparent, opacity, vertexColors, sizeAttenuation,quaX, quaZ,color,distanceRain) {
if(enableRain == true) {
rainQuaX = quaX * 5;
rainQuaZ = quaZ * 5;
var angleRain = Math.acos(rainQuaX / Math.sqrt(rainQuaX * rainQuaX + 0.2795850805518647*0.2795850805518647));
var textureRain = new THREE.TextureLoader().load("/example/textures/1rain.png"); //加载纹理贴图
//var texture = new THREE.TextureNode();
if(quaX||quaZ) {
textureRain.rotation = 1/angleRain;
textureRain.center.set(0.5, 0.5);
}
var geomRain = new THREE.Geometry(); //几何体;
var materialRain = new THREE.PointCloudMaterial({ //材质定义为点云
size: size * 2,
transparent: transparent,
opacity: opacity,
vertexColors: true,
sizeAttenuation: true,
color: color,
map: textureRain,
depthTest: false, //设置解决透明度有问题的情况
});
disRain = distanceRain;
rainSpeed = speed;
var range = 120;
rainRange = range / 2;
for (var i = 0; i < 1500; 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() / 5;
particle.velocityX = (Math.random() - 0.5) / 3;
particle.velocityZ = 0;
geomRain.vertices.push(particle);
var color = new THREE.Color(0Xffffff);
//color.setHSL(color.getHSL().h,color.getHSL().s,Math.random()* color.getHSL(),l);
geomRain.colors.push(color);
//geomRain.lookAt(0,0,0);
//geomRain.rotateY(Math.PI/6);
//geomRain.verticesNeedUpdate = true;
}
//生成模型,添加到场景当中
cloudRain = new THREE.Points(geomRain, materialRain);
//cloudRain.rotation.x= rainQuaX;
//cloud.position.set(96389.0-466.53, 2690779.0+23.26, 1000);
cloudRain.verticesNeedUpdate = true;
if (enableView == 1) {
camera.add(cloudRain);
scene.add(camera);
} else{
scene.add(cloudRain);
}
//geomRain.rotateZ(Math.PI/4);
}
}
//生成雪花粒子的方法
function createParticlesSnow(enableSnow,speed,size, transparent, opacity, vertexColors, sizeAttenuation,quaX, quaZ,color,distanceSnow) {
if(enableSnow == true) {
var textureSnow = new THREE.TextureLoader().load("/example/textures/snow.png"); //加载纹理贴图
var geomSnow = new THREE.Geometry(); //几何体;
var materialSnow = new THREE.PointCloudMaterial({ //材质定义为点云
size: size,
transparent: transparent,
opacity: opacity,
vertexColors: true,
sizeAttenuation: true,
color: color,
map: textureSnow,
depthTest: false, //设置解决透明度有问题的情况
});
disSnow = distanceSnow;
snowSpeed = speed;
snowQuaX = quaX;
snowQuaZ = quaZ;
var range = 120;
snowRange = range / 2;
for (var i = 0; i < 1500; 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() / 5;
particle.velocityX = (Math.random() - 0.5) / 3;
particle.velocityZ = 0;
geomSnow.vertices.push(particle);
var color = new THREE.Color(0Xffffff);
//color.setHSL(color.getHSL().h,color.getHSL().s,Math.random()* color.getHSL(),l);
geomSnow.colors.push(color);
}
//生成模型,添加到场景当中
cloudSnow = new THREE.Points(geomSnow, materialSnow);
//cloud.position.set(96389.0-466.53, 2690779.0+23.26, 1000);
cloudSnow.verticesNeedUpdate = true;
if(enableView ==1) {
camera.add(cloudSnow);
scene.add(camera);
}
else{
scene.add(cloudSnow);
}
}
}
function renderRain() {
//产生雨滴动画效果
var vertices = cloudRain.geometry.vertices;
vertices.forEach(function (v) {
//v.y = v.y - (v.velocityY) * rainSpeed ;//* speed;
//v.x = v.x - (v.velocityX) *.5;
//(v.y <= -60)v.y = 60;
//if(v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1;
v.y = v.y - (v.velocityY) * rainSpeed ;
if(v.y <= -rainRange)v.y = rainRange;
v.x = v.x-(v.velocityX+rainQuaX)*.5;
v.z = v.z-v.velocityZ+rainQuaZ;
if(v.x >= rainRange ) {
v.x = -rainRange;
}
else if(v.x <= -rainRange) {
v.x = rainRange;
}
if(v.z >= rainRange )
v.z = -rainRange;
else if(v.z <= -rainRange)
v.z = rainRange;
});
cloudRain.geometry.verticesNeedUpdate = true;
//distanceCamera = camera.position.distanceTo(camPosVec)
//cloudRain.position.set(camera.position.x+(camera.position.x-camPosVec.x)*distanceCamera,camera.position.y+(camera.position.y-camPosVec.y)*distanceCamera,camera.position.z+(camera.position.z-camPosVec.z)*distanceCamera);
//cloudRain.position.set(camera.position.x,camera.position.y,camera.position.z);
if(enableView ==1) {
cloudRain.position.set(0, 0, -disRain);
}
renderer.render(scene,camera);
}
function renderSnow() {
//产生雪花动画效果
var vertices = cloudSnow.geometry.vertices;
vertices.forEach(function (v) {
//v.y = v.y - (v.velocityY) * snowSpeed ;
//v.x = v.x - (v.velocityX) *.5;
//if(v.y <= -60)v.y = 60;
//if(v.x <= -60 || v.x >= 60) v.velocityX = v.velocityX * -1;
v.y = v.y - (v.velocityY) * snowSpeed;
if(v.y <= -snowRange)v.y = snowRange;
v.x = v.x-(v.velocityX+snowQuaX)*.5;
v.z = v.z-v.velocityZ+snowQuaZ;
if(v.x >= snowRange )
v.x = -snowRange;
else if(v.x <= -snowRange)
v.x = snowRange;
if(v.z >= snowRange )
v.z = -snowRange;
else if(v.z <= -snowRange)
v.z = snowRange;
});
cloudSnow.geometry.verticesNeedUpdate = true;
//cloudSnow.position.set(camera.position.x,camera.position.y,camera.position.z);
if(enableView ==1) {
cloudSnow.position.set(0, 0, -disSnow);
}
renderer.render(scene,camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderRain();
renderSnow();
renderer.setSize(window.innerWidth,window.innerHeight);
}
function animate() {
controls.update();
renderRain();
renderSnow();
stats.update();
requestAnimationFrame(animate);
}
function draw(){
//出口函数
initRender()
initScene();
initCamera();
initLight();
initModel();
initControls();
initStats();
initGuiRain();
initGuiSnow();
animate();
window.onresize = onWindowResize();
}
</script>
</html>
雨雪粒子特效(完整可用)
最新推荐文章于 2024-05-23 16:02:52 发布
该博客介绍了一个使用Three.js库实现实时三维雨雪效果的示例。通过加载纹理、创建粒子系统和调整参数,用户可以通过GUI控制雨滴和雪花的大小、速度、方向和透明度,实现交互式的雨雪动画。代码中包含了初始化渲染、相机、场景、光照、模型、性能监控、控制器以及GUI设置等关键部分。
摘要由CSDN通过智能技术生成