私は現在、アニメーション化されたストロークの円を過剰にレンダリングすることにより、ブラウザーでデータを視覚化するプロジェクトに取り組んでいます。私は 3D ライブラリの評価を開始し、three.js を使用して概念実証アプリケーションを作成しようとしました。私の 1440p モニターでは、最大 150,000 ポイントのスプライトを 60 fps でアニメーション化およびレンダリングできます。詳細を見始めるまで、すべてが見栄えがします。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();
問題を確認する最善の方法は、ポイント スプライトが領域全体に広がるのを数秒待ち、右上隅の速度コントロールを使用してアニメーションを一時停止し、マウスの左ボタンを使用してカメラを回転させて回転させることです。