Three.js开发指南-阅读记录(第七章)

243 阅读3分钟

粒子、精灵和点云

1、理解粒子

//简单粒子例子
function createSprites(){
    let material = new THREE.SpriteMaterial(); //定义材质
    
    for(let x=-5; x<5; x++){
        for(let y=-5; y<5; y++){
            let sprite = new THREE.Sprite(material); //创建粒子
            sprite.position.set(x*10, y*10, 0); //设置位置
            scene.add(sprite);
        }
    }
};
  • 注意:在使用大量的THREE.Sprite 对象时,会有性能问题,这里可以使用THREE.PointCloud 来解决,同上面效果一样,代码如下:
function createParticles(){
    let geom = new THREE.Geometry();
    
    //材质
    let material = new THREE.PointCloudMaterial({
        size:4,
        vertexColors:true,
        color:0xffffff
    });
    
    for(let x=-5; x<5; x++){
        for(let y=-5; y<5; y++){
            let particles = new Vector3(x*10, y*10, 0); //顶点
            geom.vertices.push(particles);
            geom.colors.push(new THREE.Color(Math.random() * 0x0000ff));
        }
    }
}

let cloud = new THREE.PointCloud(geom, material); //创建云
scene.add(cloud);

2、粒子、THREE.PointCloud 和 THREE.PointCloudMaterial

  • THREE.PointCloudMaterial 可设置的属性:
属性描述
color颜色,默认0xffffff
map可以在粒子上应用某种属性,例如让粒子看起来更像雪花
size粒子大小。默认为1
sizeAnnutation设置为false表示每个粒子尺寸都一样,如果为true则大小受到离摄像机的距离影响,默认为true
vertexColors设置为THREE.VertexColors时,几何体的颜色数组也有值,默认所有粒子颜色都一样 THREE.NoColors
opacity透明度
transparent是否开启透明度影响
blending指定渲染粒子的融合模式
fogtrue 是雾化效果

3、使用 HTML5 画布样式化粒子

3.1 在 THREE.CanvasRenderder 中使用HTML5 画布

  • 使用方式:
//HTML5 canvas画布
let getTextrue = function(){
    let canvas = document.createElement('canvas');
    canvas.width = 32;
    canvas.height = 32;
    
    let ctx = canvas.getContext('2d');
    ...
    //draw the ghost
    ...
    ctx.fill();
    
    let texture = new THREE.Textrue(canvas);
    texture.needsUpdata = true;
    return texture;
};

function createPointCloud(size, transparent, opacity, sizeAnnutation, color){
    let geom = new THREE.Geometry();
    
    //材质
    let material = new THREE.PointCloudMaterial({
        size:size,
        transparent:transparent,
        opacity:opacity,
        map:getTextrue(), //引入的html5 canvas
        sizeAnnutation:sizeAnnutation,
        color:color
    });
    
    let range = 500;
    for(let i=0; i<5000; i++){
        let particles = new Vector3(Math.random()*range-range/2, Math.random()*range-range/2, Math.random()*range-range/2); //顶点
        geom.vertices.push(particles);
    }
    
    
    let cloud = new THREE.PointCloud(geom, material); //创建云
    cloud.sortParticles = true;
    scene.add(cloud);
}

3.2 在WebGLRenderer 中使用THML5画布

  • 方式一:
//3.1中方式一样,只是渲染函数的差别
//HTML5 canvas画布
let getTextrue = function(){
    let canvas = document.createElement('canvas');
    canvas.width = 32;
    canvas.height = 32;
    
    let ctx = canvas.getContext('2d');
    ...
    //draw the ghost
    ...
    ctx.fill();
    
    let texture = new THREE.Textrue(canvas);
    texture.needsUpdata = true;
    return texture;
};

function createPointCloud(size, transparent, opacity, sizeAnnutation, color){
    let geom = new THREE.Geometry();
    
    //材质
    let material = new THREE.PointCloudMaterial({
        size:size,
        transparent:transparent,
        opacity:opacity,
        map:getTextrue(), //引入的html5 canvas
        sizeAnnutation:sizeAnnutation,
        color:color
    });
    
    let range = 500;
    for(let i=0; i<5000; i++){
        let particles = new Vector3(Math.random()*range-range/2, Math.random()*range-range/2, Math.random()*range-range/2); //顶点
        geom.vertices.push(particles);
    }
    
    
    let cloud = new THREE.PointCloud(geom, material); //创建云
    cloud.sortParticles = true;
    scene.add(cloud);
}

  • 方式二:
function createSprites(){
    //定义材质
    let material = new THREE.SpriteMaterial({
        map:getTextrue(), //引入的html5 canvas
        size:3,
        transparent:true,
        opacity:true,
        blending:THREE.AdditiveBlending,//融合模式,THREE.AdditiveBlending 表示背景像素的颜色会添加到新画的像素上
        sizeAnnutation:ture,
        color:0xffffff
    }); 
    
    for(let x=-5; x<5; x++){
        for(let y=-5; y<5; y++){
            let sprite = new THREE.Sprite(material); //创建粒子
            sprite.position.set(x*10, y*10, 0); //设置位置
            scene.add(sprite);
        }
    }
};

4、使用纹理样式化粒子

  • 定义:加载外部图像作为粒子的纹理材质

  • 核心方法:THREE.ImageUtils.loadTexture(),该函数可以将图像加载为THREE.Texture,然后分配给map属性

  • 使用方式:

let texture = THREE.ImageUtils.loadTexture("../images/rain.png")

function createSprites(){
    //定义材质
    let material = new THREE.SpriteMaterial({
        map:texture, //引入的html5 canvas
        color:0xffffff
    }); 
    
    for(let x=-5; x<5; x++){
        for(let y=-5; y<5; y++){
            let sprite = new THREE.Sprite(material); //创建粒子
            sprite.position.set(x*10, y*10, 0); //设置位置
            scene.add(sprite);
        }
    }
};

5、使用精灵贴图

  • 定义:使用精灵图来作为纹理

  • 加载图像方法:THREE.ImageUtils.loadTexture(),该函数可以将图像加载为THREE.Texture,然后分配给map属性

  • 核心:对map属性的 offset和repeat属性进行设置

  • THREE.OrthographicCamera() 函数可以在三维场景下创建一个平视器

  • 注意在使用THREE.OrthographicCamera()是要在渲染前设置:webGLRenderer.autoClear = false ,避免渲染粒子前场景被清空

  • 使用方式:同上面一样