Проблемы рендеринга спрайтов в point.js
В настоящее время я работаю над проектом, который будет визуализировать данные в браузере, визуализируя чрезмерное количество анимированных штрихов. Я начал оценивать 3D-библиотеки и попытался создать приложение для проверки концепции с Three.js. Он способен анимировать и отображать до 150 000 точечных спрайтов со скоростью 60 кадров в секунду на моем мониторе 1440p. Все выглядит отлично, пока вы не начнете смотреть на детали. У него есть две проблемы рендеринга:
- Он создает странные горизонтальные линии, даже когда вы выключаете анимацию
- Когда вы поворачиваете камеру, прозрачные области перекрывающихся точечных спрайтов будут показывать фон вместо базовых точечных спрайтов.
Вот подтверждение концепции приложения: 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 ответ
- Используя alphaTest со значением 0.5, обрезали углы окружностей, не влияя на рендеринг других окружностей.
- Установка прозрачного значения в false убрала ошибочный эффект исчезновения, который появился после установки alphaTest на 0.5
- Добавление затухания к самой текстуре сделало границы кругов гладкими даже при том, что прозрачная настройка, вызвавшая эффект затухания, была отключена
- Рандомизация положения по оси Y на 0,01 единицы убрала странные горизонтальные линии