0

我目前正在开发一个项目,它将通过渲染过量的动画描边圆来可视化浏览器上的数据。我开始评估3D库,最终尝试用three.js创建概念验证应用程序。它能够在我的1440p显示器上以60 fps的速度动画和渲染高达150 000个点的精灵。一切看起来都很棒,直到你开始看细节。它有两个渲染问题:使用three.js指向精灵渲染问题

  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

尝试一个具有完全透明背景的精灵,并在素材集中设置transparent:false,alphaTest:0.5'。 – WestLangley

+0

谢谢WestLangley!这个固定的问题#2。然而问题#1仍然存在。 – user1937459

回答

0
  1. 使用alphaTest与值0.5修剪掉圆的角部,而不会影响其他圆圈
  2. 透明值设置为false除去手推车淡入淡出效果的alphaTest设定为0.5
  3. 添加衰落到后哪个来渲染即使认为导致淡化效果的透明设置被禁用,纹理本身也使圆圈的边界平滑
  4. 随机化y轴上的位置减去0.01个单位的奇怪水平线