Почему возникают артефакты при рендере сцены в Three.js?
Если при работе с Three.js вы столкнулись с различного рода артефактами, например, отображением частей объектов, которых видно быть не должно, появлением произвольных черных пятен или исчезанием/обрезанием частей объектов и т.д., то предлагаем несколько советов, как решить данную проблему.
Причины появления артефактов могут быть разные, наиболее частые из них следующие:
1. Максимальное расстояние, которое рендерит камера меньше, чем расположение некоторых объектов. В этом случае объекты или их части просто напросто будут обрезаться и возможно периодически появляться и исчезать.
Например, при инициализации камеры был указан параметр far = 1000, а объект или какая-либо его часть находится за заданными пределами.
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.001, 1000 );
...
obj = new THREE.Mesh( new THREE.BoxGeometry( 250, 250, 250 ), new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
obj.position.x = 900;
obj.position.y = 900;
obj.position.z = 900;
Проблема проиллюстрирована на картинках, представленных ниже.
2. Объекты находятся далеко от камеры, но относительно близко к друг к другу. В таком случае некоторые части объекта, расположенного на заднем плане могут в некоторые моменты времени оказаться спереди и наложиться на другой объект.
Наглядный пример такой проблемы и ее решение представлены в одном из примеров, опубликованных в разделе примеров на официальном сайте Three.js.
Проблема объясняется точностью буфера глубины — depth buffer, которой не хватает в данной ситуации. Общий эффект представляет собой попеременное отображение частей то одного объекта, то другого — происходит своеобразная «борьба» за пиксели. Устраняются такие артефакты путем увеличения глубины z-buffer.
Стандартное создание рендерера выглядит так:
renderer = new THREE.WebGLRenderer();
Чтобы увеличить точность следует указать при инициализации свойство logarithmicDepthBuffer со значением true:
renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true });
Однако следует отметить, что при этом снижается производительность рендера сцены, и потому не всегда такое решение может быть пригодным. Поэтому такие артефакты теоретически могут быть отчасти решены следующими методами:
- более удаленное размещение объектов между друг другом;
- если все объекты находятся в рамках единого диапазона координат, то как вариант попробовать уменьшить модель в несколько раз, переведя координаты объектов, например, из тысяч в десятки.
Добавить комментарий