Проблемы рендеринга спрайтов в point.js

В настоящее время я работаю над проектом, который будет визуализировать данные в браузере, визуализируя чрезмерное количество анимированных штрихов. Я начал оценивать 3D-библиотеки и попытался создать приложение для проверки концепции с Three.js. Он способен анимировать и отображать до 150 000 точечных спрайтов со скоростью 60 кадров в секунду на моем мониторе 1440p. Все выглядит отлично, пока вы не начнете смотреть на детали. У него есть две проблемы рендеринга:

  1. Он создает странные горизонтальные линии, даже когда вы выключаете анимацию
  2. Когда вы поворачиваете камеру, прозрачные области перекрывающихся точечных спрайтов будут показывать фон вместо базовых точечных спрайтов.

Вот подтверждение концепции приложения: https://jsfiddle.net/tcpvfbsd/1/

var renderer, scene, camera, controls;
var points;
var stats;
var controls;

var worldWidth = 200;
var worldRadius = worldWidth / 2;
var patchSize = 10;
var pointsAmount = 100000;

function init() {
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x1d252d);

  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
  camera.position.set(0, worldWidth * 1.5, 0);

  controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.minDistance = 100;
  controls.maxDistance = 1100;

  scene.add(new THREE.GridHelper(2 * worldRadius, 2 * worldWidth / patchSize, 0x444444, 0x444444));



  var geometry = new THREE.BufferGeometry();
  var positions = new Float32Array(pointsAmount * 3);
  var rotations = new Float32Array(pointsAmount * 1);

  for (var i = 0; i < pointsAmount; i++) {

    positions[i] = 0;
    positions[i + 1] = 0;
    positions[i + 2] = 0;
    rotations[i] = 2 * Math.PI * Math.random();

  }

  controls = new function() {
    this.speed = 10;
    this.amount = 10;
  };

  var gui = new dat.GUI();
  gui.add(controls, 'speed', 0, 100);
  //gui.add(controls, 'amount', 0, 10000).step(1);;

  geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
  geometry.addAttribute('rotation', new THREE.BufferAttribute(rotations, 1));

  var loader = new THREE.TextureLoader();
  loader.load('//i.imgur.com/AmQQnZc.png', function(texture) {
    var material = new THREE.PointsMaterial({
      size: 5,
      transparent: true,
      map: texture

    });

    points = new THREE.Points(geometry, material);
    scene.add(points);

    stats = new Stats();
    document.body.appendChild(stats.dom);
    animate();
  });

}

function animate() {

  requestAnimationFrame(animate);

  var position = points.geometry.attributes.position;
  var count = position.count;
  var rotation = points.geometry.attributes.rotation;
  var speed = patchSize * controls.speed / 100;
  if (speed > 0) {
    for (var i = 0; i < count; i++) {

      var wiggle = Math.random() > 0.9 ? THREE.Math.randFloat(-0.1, 0.1) : 0;
      var theta = rotation.getX(i) + wiggle;
      let dx = speed * Math.cos(theta);
      let dz = speed * Math.sin(theta);
      var x0 = position.getX(i);
      var z0 = position.getZ(i);
      var x = THREE.Math.clamp(x0 + dx, -worldRadius, worldRadius);
      var z = THREE.Math.clamp(z0 + dz, -worldRadius, worldRadius);
      if (Math.abs(x) === worldRadius) dx = -dx;
      if (Math.abs(z) === worldRadius) dz = -dz;
      position.setX(i, x);
      position.setZ(i, z);
      position.setY(i, 1);
      rotation.setX(i, Math.atan2(dz, dx));

    }
  }

  position.needsUpdate = true;

  stats.update();

  renderer.render(scene, camera);

}
init();

Лучший способ увидеть проблему - подождать пару секунд, пока точечные спрайты распространятся по области, использовать управление скоростью в верхнем правом углу, чтобы приостановить анимацию, и использовать левую кнопку мыши, чтобы повернуть и повернуть камеру.

1 ответ

Решение
  1. Используя alphaTest со значением 0.5, обрезали углы окружностей, не влияя на рендеринг других окружностей.
  2. Установка прозрачного значения в false убрала ошибочный эффект исчезновения, который появился после установки alphaTest на 0.5
  3. Добавление затухания к самой текстуре сделало границы кругов гладкими даже при том, что прозрачная настройка, вызвавшая эффект затухания, была отключена
  4. Рандомизация положения по оси Y на 0,01 единицы убрала странные горизонтальные линии
Другие вопросы по тегам