<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>火焰和烟雾效果</title>
<script src="https://s1.pstatp.com/cdn/expire-1-M/three.js/104/three.min.js"></script>
<script type="text/javascript" src="js/OrbitControls.js" ></script>
<script type="text/javascript" src="js/Stats.js" ></script>
<script type="text/javascript" src="js/dat.gui.min.js" ></script>
<script type="text/javascript" src="js/Fire.js" ></script>
<script type="text/javascript" src="js/tween.min.js" ></script>
<script type="text/javascript" src="js/physi.js" ></script>
<style>
body{
background: url(img/bg.jpg) no-repeat top center fixed; overflow: hidden;
background-size: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script>
// 实际代码
var scene, renderer, camera; // 三大件
var controls, stats, clock; // 辅助组件
var arrowBodyMesh, smokeParticles = []; // 箭体网格对象和烟雾数组
// 箭体图片路径
var arrowPath = "img/arrow.png";
// 烟雾图片路径
var smokePath = "img/cloud.png";
function init() {
// 创建clock
clock = new THREE.Clock();
// 创建场景
scene=new THREE.Scene();
// 创建渲染器
renderer=new THREE.WebGLRenderer({
antialias:true,
alpha:true
});
renderer.setClearColor(0x000000, 0.0);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// 创建透视相机
camera=new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,1000);
camera.position.set(0,0,30);
// 辅助移动视角
// controls=new THREE.OrbitControls(camera,renderer.domElement);
// controls.enableDamping=true;
// controls.minDistance=1;
// controls.maxDistance=500;
scene.add(new THREE.AmbientLight(0XCCCCCC, 0.5));
var pointLight=new THREE.PointLight(0xffffff, 0.8);
pointLight.position.set(0, 10, 40);
scene.add(pointLight);
}
var fire, fire1;
function initModel(){
// var helper = new THREE.GridHelper(1000, 50);
// scene.add(helper);
// 尾焰
var plane=new THREE.PlaneBufferGeometry(15,30,1);
fire = new THREE.Fire(plane,{
textureWidth:1024,
textureHeight:1024,
debug:false,
color1: new THREE.Color(0xffffff),
color2: new THREE.Color(0xffc159),
color3: new THREE.Color(0xe69bb1),
windVector: new THREE.Vector2(0, -1.2),
colorBias: 0.92,
burnRate: 1.19,
diffuse: 5,
viscosity: 0.2,
expansion: -3,
swirl: 8,
drag: 0.17,
airSpeed: 23,
speed: 390,
massConservation: false
});
// fire = new THREE.Fire(plane,{
// textureWidth:512,
// textureHeight:512,
// debug:false,
// color1: new THREE.Color(0xffffff),
// color2: new THREE.Color(0xffc159),
// color3: new THREE.Color(0xe69bb1),
// windVector: new THREE.Vector2(0, -2),
// colorBias: 0.61,
// burnRate: 1.73,
// diffuse: 1.3,
// viscosity: 0.25,
// expansion: 0,
// swirl: 50,
// drag: 0.35,
// airSpeed: 11,
// speed: 531,
// massConservation: false
// });
fire.addSource(0.5, 0.6, 0.1, 1.0, 0.0, -2.0);
fire.addSource(0.62, 0.6, 0.1, 1.0, 0.0, -2.0);
fire.addSource(0.38, 0.6, 0.1, 1.0, 0.0, -2.0);
fire.position.y = firePosition;
fire.position.z = -10;
// fire.rotateX(Math.PI);//绕x轴旋转π/4
scene.add(fire);
// 烟雾
var smokeTexture = THREE.ImageUtils.loadTexture(smokePath);
var smokeMaterial = new THREE.MeshLambertMaterial({
map: smokeTexture,
transparent: true
});
var smokeGeo = new THREE.PlaneGeometry(30, 30);
for (p = 0; p < smokeCount; p++) {
var particle = new THREE.Mesh(smokeGeo, smokeMaterial);
// particle.position.set((p-10)*5, -28+Math.abs(p-10)*2, -5);
particle.position.set(0, firePosition-8, -5);
// particle.position.set((p-10)*5, -28+Math.abs(p-10)*3, -5);
particle.rotation.z = Math.random() * 360;
// particle.rotateX(Math.PI);//绕x轴旋转π/4
scene.add(particle);
smokeParticles.push(particle);
}
// 箭体
var arrowPlane=new THREE.PlaneBufferGeometry(10,25,1);
// var geometry = new THREE.CubeGeometry( 10, 10, 10);
var material = new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture(arrowPath),
transparent: true
});
arrowBodyMesh = new THREE.Mesh(arrowPlane, material);
arrowBodyMesh.position.y = (firePosition + 18.7);
arrowBodyMesh.position.z = -10;
scene.add(arrowBodyMesh);
}
var smokeCount = 20; // 组成烟雾的对象数量
var firePosition = -30; // 尾焰y轴位置
/**
* 飞行动画
*/
var tweenFireFlySlow, tweenArrowFlySlow, tweenFireFlyFast, tweenArrowFlyFast;
function initTween(distance) {
// // 尾焰起飞-慢
// tweenFireFlySlow = new TWEEN.Tween(fire.position)
// .to( { y: (firePosition + 28.7) }, 2500 ).repeat(0).start();
// tweenFireFlySlow.easing(TWEEN.Easing.Quadratic.In);
// // 箭体起飞-慢
// tweenArrowFlySlow = new TWEEN.Tween(arrowBodyMesh.position)
// .to( { y: (47.4 + firePosition) }, 2500 ).repeat(0).start();
// tweenArrowFlySlow.easing(TWEEN.Easing.Quadratic.In);
// // 尾焰起飞-快
// tweenFireFlyFast = new TWEEN.Tween(fire.position)
// .to( { y: (firePosition + 68.7) }, 1000 ).repeat(0);
// tweenFireFlyFast.easing(TWEEN.Easing.Elastic.In);
// // 箭体起飞-快
// tweenArrowFlyFast = new TWEEN.Tween(arrowBodyMesh.position)
// .to( { y: (87.4 + firePosition) }, 1000 ).repeat(0);
// tweenArrowFlyFast.easing(TWEEN.Easing.Elastic.In);
// 尾焰起飞-慢
tweenFireFlySlow = new TWEEN.Tween(fire.position)
.to( { y: (firePosition + 68.7) }, 5500 ).repeat(0).start();
tweenFireFlySlow.easing(TWEEN.Easing.Quadratic.In);
// 箭体起飞-慢
tweenArrowFlySlow = new TWEEN.Tween(arrowBodyMesh.position)
.to( { y: (87.4 + firePosition) }, 5500 ).repeat(0).start();
tweenArrowFlySlow.easing(TWEEN.Easing.Quadratic.In);
// 烟雾运动
for (var p = 0; p < smokeCount; p++) {
new TWEEN.Tween(smokeParticles[p].position)
.to( { x: (p-10)*5 }, 3000 ).repeat(0).start()
.easing(TWEEN.Easing.Quadratic.Out);
new TWEEN.Tween(smokeParticles[p].position)
.to( { y: -26+Math.abs(p-10)*3 }, 2000 ).repeat(0).start()
.easing(TWEEN.Easing.Quadratic.Out);
new TWEEN.Tween(smokeParticles[p].position)
.to( { z: Math.abs(p-10)*3 }, 2000 ).repeat(0).start()
.easing(TWEEN.Easing.Quadratic.Out);
}
// tweenFireFlySlow.chain(tweenFireFlyFast);
// tweenArrowFlySlow.chain(tweenArrowFlyFast);
}
window.onresize = function (){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
function render(){
renderer.render(scene,camera);
}
function animate(){
if (!isStop) {
// controls.update();
TWEEN.update();
delta = clock.getDelta();
evolveSmoke();
requestAnimationFrame(animate);
render();
}
}
// 烟雾旋转
function evolveSmoke() {
var sp = smokeParticles.length;
while (sp--) {
if (sp%2==0) { // 偶数逆时针旋转
smokeParticles[sp].rotation.z += (delta * 0.1);
} else { // 奇数顺
- 1
- 2
- 3
- 4
- 5
- 6
前往页