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個單位的奇怪水平線