2016-01-31 5 views
0

У меня есть швы между горизонтальными гранями куба при использовании текстурного атласа в three.js.
Это демо: http://jsfiddle.net/rnix/gtxcj3qh/7/ или http://jsfiddle.net/gtxcj3qh/8/ (с комментариями)Швы на краях куба при использовании текстурного атласа с three.js

Скриншот проблемы: seams
Здесь я использую повторение и смещение:

var materials = []; 
    var t = []; 
    var imgData = document.getElementById("texture_atlas").src; 
    for (var i = 0; i < 6; i ++) { 
     t[i] = THREE.ImageUtils.loadTexture(imgData); //2048x256 
     t[i].repeat.x = 1/8; 
     t[i].offset.x = i/8; 
     //t[i].magFilter = THREE.NearestFilter; 
     t[i].minFilter = THREE.NearestFilter; 
     t[i].generateMipmaps = false; 
     materials.push(new THREE.MeshBasicMaterial({ map: t[i], overdraw: 0.5 })); 
    } 

    var skyBox = new THREE.Mesh(new THREE.CubeGeometry(1024, 1024, 1024), new THREE.MeshFaceMaterial(materials)); 
    skyBox.applyMatrix(new THREE.Matrix4().makeScale(1, 1, -1)); 
    scene.add(skyBox); 

Атласа имеет размер 2048x256 (двойки) , Я также попробовал ручной UV-mapping вместо повтора, но результат тот же. Я использую 8 плиток вместо 6, потому что я думал, что точность деления 1/6 вызывает проблему, но нет.

Пиксели на этой линии от следующей плитки в атласе. Я попробовал полностью белый атлас и не было никаких артефактов. Это объясняет, почему на вертикальных границах Z-граней нет швов. Я играл с фильтрами, wrapT, wrapS и mipmaps, но это не помогает. Увеличение разрешения не помогает. Существует 8192x1024 атлас http://s.getid.org/jsfiddle/atlas.png Я пробовал еще один атлас, результат тот же.

Я знаю, что я могу разделить атлас на отдельные файлы, и он отлично работает, но это не удобно.

Неправильно?

+0

Не ответ, но немного улучшил вашу скрипку: http://jsfiddle.net/gtxcj3qh/8/. – WestLangley

+1

Я расширил вашу скрипку и заставил ее работать, используя холст в качестве растрового источника вместо изображения (http://jsfiddle.net/gtxcj3qh/14/). Исходное изображение - это плитка, нарисованная на отдельном холсте, который затем используется для создания отдельной текстуры. Я задал очень похожий вопрос здесь (http://stackoverflow.com/questions/43401684/uv-mapping-a-cube-in-three-js-not-joining-faces-correctly) .. но вместо использования ваш подход Я создал пользовательскую UV-карту и единую текстуру ... однако результат был таким же, как ваш. –

ответ

1

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

Если вы должны использовать псевдоним текстуры, вам необходимо подделать поведение CLAMP_TO_EDGE, заполнив границы изображения. См. Этот ответ https://gamedev.stackexchange.com/questions/61796/sprite-sheet-textures-picking-up-edges-of-adjacent-texture. Это должно выглядеть примерно так: (преувеличенные границы для ясности)

enter image description here

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

+0

«Преувеличенные границы» - не идеальное решение. Наверное, нет идеального решения. – rNix

+0

Я согласен с тем, что преувеличенные края не являются хорошим решением, однако эта идея вдохновила нас найти решение этой проблемы. Решение состоит в том, чтобы расположить плитки таким образом, что они смежны с плитами, которые они будут смежными в 3D-объекте , Таким образом, их края будут касаться тех, которые они будут касаться в 3D-объекте. Более подробное описание этого решения можно найти здесь: http://stackoverflow.com/questions/43401684/uv-mapping-a-cube-in-three-js-not-joining-faces-correctly (это частично дублированный вопрос/answer, так как использовался другой метод применения текстуры) –

Смежные вопросы