Three.js окрашивает не ту сторону лица объекта VRML

Вот файл VRML, который я пытаюсь отобразить с помощью три.js. Когда я просматриваю этот файл в отдельном средстве просмотра, таком как view3dscene, он выглядит правильно:

3D-рендеринг болта

Однако в Three.js на примере VRMLLoader раскрашиваются внутренние стороны граней, а не внешние:

Визуализация того же болта, но прозрачная снаружи, открывающая вогнутую обратную сторону

Мне кажется очевидным, что three.js считывает правильную информацию о цвете, просто неправильно применяя ее к лицам. Но я очень новичок в работе с 3D, поэтому я не уверен, в чем заключается несоответствие или что я могу сделать, чтобы исправить это.

Я не делаю ничего особенного с загрузкой файла; это так же, как в примере кода:

loader.load('https://75thtrombone.com/links/stack-exchange/2016-09/' + model, function(geometry) {
    scene.add(geometry);
});

Вот скрипт с моим кодом и взглядом на проблему. (Увеличьте масштаб с помощью колесика мыши, перетащите, чтобы повернуть.) Любая помощь, понимание, указание на то, что нужно прочитать, чтобы узнать больше, или любые другие подсказки вообще были бы замечательными.


person 75th Trombone    schedule 15.09.2016    source источник
comment
Возможный дубликат Faces, невидимых с одной стороны, с использованием Three.js   -  person 75th Trombone    schedule 15.09.2016
comment
похоже, вы нашли ответ, я все равно настраивал скрипку.... jsfiddle.net/z92bx5ay проблема связана с порядком намотки лиц в webGL, который определяет направление лица. VRML предполагает, что все грани сплошные, если не указано иное. WebGL не делает такого предположения.   -  person Radio    schedule 15.09.2016
comment
Спасибо! Я знал о перекручивании чисел в 2D-векторной графике, не знал, что 3D-графика аналогична этому.   -  person 75th Trombone    schedule 15.09.2016


Ответы (1)


@Радио верно. Ваш порядок намотки обратный, из-за чего грани указывают в неправильном направлении. Это только кажется, что некоторые грани правильные из-за резьбы на объекте.

Вот скрипт (код ниже), демонстрирующий один из способов исправить порядок намотки без изменения исходного объекта: https://jsfiddle.net/TheJim01/3nr7rakk/

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

Чего я не делал (в качестве упражнения для спрашивающего), так это не проверял это с помощью последней версии THREE.js. JSFiddle использует очень старую версию THREE.js (JSFiddle использует r54, текущая r80). Я рекомендую либо настроить скрипт на использование последней версии и повторить попытку, либо разместить код локально с последней версией. В загрузчике VRML могут быть исправления, которые решают проблему, с которой вы столкнулись.

Вы можете использовать эту страницу в качестве примера того, как связать JSFiddle с последней версией THREE.js: http://jsfiddle.net/TheJim01/kb7e88vr/ Не стесняйтесь разветвлять и модифицировать его.

Обновленный код: мой код такой же, как у @75th Trombone, за исключением того, что я добавил/изменил следующее:

function sideReplacer(obj){
    if(obj.material){
        obj.material.side = THREE.DoubleSide;
    }
    if(obj.children && obj.children.length > 0){
        for(var i in obj.children){
            sideReplacer(obj.children[i]);
        }
    }
}

loader.load('https://75thtrombone.com/links/stack-exchange/2016-09/' + model, function(geometry) {
    sideReplacer(geometry);
    scene.add(geometry);
});
person TheJim01    schedule 15.09.2016
comment
Спасибо! Моя скрипка все равно ссылается на three.js извне, поэтому все здесь должно относиться к последней версии. - person 75th Trombone; 15.09.2016
comment
@ TheJim01 проверьте функцию перемещения в Three.js. Он работает как со сценами, так и с объектами. проверьте строку 48: jsfiddle.net/z92bx5ay Я только что заметил, что мы использовали геометрию имени переменной который в данном случае является неправильным, поскольку он не представляет объект класса Three.js Geometry, а является типом Object3d. Я бы изменил имя var для ясности. - person Radio; 15.09.2016