three.js прогрессивный рендеринг большой сетки - PullRequest
0 голосов
/ 23 мая 2018

Я хотел бы сделать статическую сетку произвольно большого размера, используя three.js.Размер сетки может составлять 2 ГБ с десятками миллионов полигонов.

Я хочу направить буферы геометрии сетки в indexedDB, постепенно считывать их и отображать на экране, сохраняя при этом интерактивную частоту кадров.Я создам класс MemoryManager, который гарантирует, что мы не прервем работу браузера, загрузив данные в буфер фиксированного размера из indexedDB.В моем цикле анимации я буду рендерить как можно больше геометрических фигур в течение 16 мс, пока пользователь не перестанет взаимодействовать, а затем непрерывно рендерить сетки, пока их больше не будет.

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

Мой вопрос такой: Есть ли лучший способ сделать это, и было ли это сделано раньше? (я знаю, что с WebGL1 запросы окклюзии WebGL2 намного упростят эту задачу)

Кроме того, каков наилучший способ настройки класса Three.js WebGLRenderer?Существуют частные закрывающие переменные (например, WebGLState), к которым мне потребуется доступ для настройки производительности в моем случае использования.

1 Ответ

0 голосов
/ 24 мая 2018

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

Если вы хотите постепенно рендерить в геометрии, когда пользователь перестал взаимодействовать, тоВы можете просто прекратить очищать буфер рендеринга.С THREE.js вы можете сделать это, включив preserveDrawingBuffer в рендере и установив autoClear в false.

Если камера перемещается или сцена меняется, и вам нужно начать все сначала, вы можетеочистите представление снова, вызвав renderer.clear().

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

Пример

Сцена перерисовывается на одном и том же кадре снова и снова.Нажмите на сцену, чтобы очистить ее и начать рисовать снова.Важные линии JS NOTE 'd

// NOT: enabling preserveDrawingBuffer
const renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
renderer.setClearColor(0x263238);
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.clear();
document.body.appendChild( renderer.domElement );

// NOTE: disabling autoclear
renderer.autoClear = false;

// Scene setup
const scene = new THREE.Scene();
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(.4, 1, .1);
scene.add(dirLight);

// Camera setup
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000)
camera.position.z = 10;

const geom = new THREE.TorusKnotGeometry(.5, .2, 200, 100);
const mesh = new THREE.Mesh(geom, new THREE.MeshPhongMaterial({ color: 0xE91E63 }));
scene.add(mesh);


// NOTE: Clearing on user interaction
renderer.domElement.addEventListener('click', () => renderer.clear());

(function renderLoop() {
    mesh.position.y = Math.sin(performance.now() * 0.001);
    renderer.render( scene, camera );
    requestAnimationFrame( renderLoop );
})();
<script type="text/javascript" src="https://rawgit.com/mrdoob/three.js/r92/build/three.js"></script>

<style>
  canvas {
    width: 100%;
    height: 100%;
  }

  * {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
  }

  div {
    color: white;
    position: absolute;
    text-align: center;
    width: 100%;
  }
</style>

<div>Click to clear</div>

Надеюсь, это поможет!

...