【问题标题】:Different Sprites for Particles in Three JS三种 JS 中粒子的不同 Sprite
【发布时间】:2019-02-19 18:18:19
【问题描述】:

想法是将图像分割成小图块,这应该通过始终使用相同的图像但更改每个精灵所使用图像的偏移量来实现。以下代码有效,但速度很慢。

好的,我更新代码如下:

camera = new THREE.PerspectiveCamera( 85, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 100;
camera.position.x = 40;
camera.position.y = 30;

scene = new THREE.Scene();


var textureLoader = new THREE.TextureLoader();
var rowCount= 73;
var columnCount=83;

var material = {};
var particles = {};
var geometry = {};
var texture = {};

imageCount = 0;

// DOES NOT WORK
// var originalTexture = textureLoader.load('textures/sprites/full-size.png');

for(i=0;i<rowCount;i++){
  for(j=0;j<columnCount;j++){

    // DOES NOT WORK
    // texture[imageCount] = originalTexture.clone();
    texture[imageCount] = textureLoader.load('textures/sprites/full-size.png');
    texture[imageCount].repeat.set(1/columnCount, 1/rowCount);
    texture[imageCount].offset.y = 1/rowCount * i;
    texture[imageCount].offset.x = 1/columnCount * j;

    geometry[imageCount] = new THREE.BufferGeometry();

    var x = j*2;
    var y = i*2;
    var z = 1;
    vertices.push( x, y, z );
    vertice1 = [];
    geometry[imageCount].addAttribute( 'position', new THREE.Float32BufferAttribute([x, y, z], 3 ) );

    material = new THREE.PointsMaterial( { size: 2, map: texture[imageCount], depthTest: true, transparent: false } );
    particles = new THREE.Points( geometry[imageCount], material );
    scene.add(particles);
    imageCount++;

  }
}

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

这会将图像分割成块,在 rowCount 和 columnCount 中定义。这个解决方案的唯一问题是,它非常慢。我尝试克隆纹理的未注释行不起作用。

有什么建议吗?

这是一个工作演示:

https://jsfiddle.net/zy2rt9eg/

它适用于少量粒子。

【问题讨论】:

    标签: three.js particles


    【解决方案1】:

    看起来您为每种材质使用了相同的几何图形,这意味着您导致点重叠,因此只显示添加到场景中的最后一个。您应该为每个 THREE.Points 使用不同的几何图形,以便每个点都有自己独特的位置。

    另外,为避免为每个纹理调用.load(),您可以对第一个纹理之后的所有内容使用.clone() 方法:

    texture[0] = textureLoader.load('textures/sprites/256.png');
    texture[1] = texture[0].clone();
    texture[2] = texture[0].clone();
    texture[3] = texture[0].clone();
    

    【讨论】:

    • 这确实是问题所在。我更新了上面的代码。现在它很慢,我认为这种方法有些错误。
    • 啊,是的。您的 JSfiddle 正在尝试为 600 个不同的 Points 设置动画,这很慢,因为每个新的 Points 对象都需要更新其转换矩阵,然后一次渲染一个。您需要一种更高级的方法,它使用自定义属性创建单个 Points 对象来偏移单个纹理。不确定您是否知道如何编写自定义着色器,但这些示例通过自定义属性为数千个点设置动画:threejs.org/examples/?q=custom#webgl_custom_attributes_points
    猜你喜欢
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    相关资源
    最近更新 更多