Мне удалось получить рабочую версию для WebGL1, основанную на ответе TheJim01!
Сначала создайте вторую более простую сцену, чтобы использовать ее для расчетов:
pickingScene = new THREE.Scene();
pickingTextureOcclusion = new THREE.WebGLRenderTarget(window.innerWidth / 2, window.innerHeight / 2);
pickingMaterial = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors });
pickingScene.add(new THREE.Mesh(BufferGeometryUtils.mergeBufferGeometries([
createBuffer(geometry, mesh),
createBuffer(geometry2, mesh2)
]), pickingMaterial));
Воссоздайте ваши объекты как геометрию буфера ( быстрее для производительности):
function createBuffer(geometry, mesh) {
var buffer = new THREE.SphereBufferGeometry(geometry.parameters.radius, geometry.parameters.widthSegments, geometry.parameters.heightSegments);
quaternion.setFromEuler(mesh.rotation);
matrix.compose(mesh.position, quaternion, mesh.scale);
buffer.applyMatrix4(matrix);
applyVertexColors(buffer, color.setHex(mesh.name));
return buffer;
}
Добавить цвет, основанный на me sh .name, например, id 1, 2, 3, et c
function applyVertexColors(geometry, color) {
var position = geometry.attributes.position;
var colors = [];
for (var i = 0; i < position.count; i ++) {
colors.push(color.r, color.g, color.b);
}
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
}
Затем во время рендер l oop проверяет вторую сцену на эту текстуру и сопоставляет данные пикселей с именем me sh:
function isOccludedBuffer(object) {
renderer.setRenderTarget(pickingTextureOcclusion);
renderer.render(pickingScene, camera);
var pixelBuffer = new Uint8Array(window.innerWidth * window.innerHeight);
renderer.readRenderTargetPixels(pickingTextureOcclusion, 0, 0, window.innerWidth / 2, window.innerHeight / 2, pixelBuffer);
renderer.setRenderTarget(null);
return !pixelBuffer.includes(object.name);
}
Рабочую демонстрацию WebGL1 можно посмотреть здесь:
https://jsfiddle.net/kmturley/nb9f5gho/62/
Одно замечание, которое следует отметить при таком подходе, заключается в том, что ваша сцена выбора должна оставаться в курсе изменений в основной сцене . Так что, если ваши объекты перемещаются по положению / повороту и т. Д. c, их также необходимо обновить в сцене выбора. В моем примере камера движется, а не объекты, поэтому она не нуждается в обновлении.
Для WebGL2 у нас будет лучшее решение:
https://tsherif.github.io/webgl2examples/occlusion.html
Но это поддерживается не во всех браузерах:
https://www.caniuse.com/#search = webgl