Страница 1 из 2

наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 24 апр 2017, 11:11
tgk
Доброго всем. Такая проблема: не получается сабж. Точнее получается, но криво. Задавал этот вопрос на геймдев http://www.gamedev.ru/code/forum/?id=225440&page=2#m25, пока ответа нет. Надеюсь что тут поможете. Суть такая - есть пазлы в неопределенном количестве, надо их затекстурить общей текстурой и поверх положить частички другой текстуры которая собственно и представляет собой картинку собираемую игроком.
Мои действия:
1. Замоделил пазл.
Изображение
2. Создал для него развертку.
Изображение
3. Импортировал в юнити.
4. положил на объект два материала (grid - общий для всех, pieceMat - тоже общий, но согласно развертке задаваемой программно, назовем просто картинкой)
Изображение
5. написал такой скрипт (идея в том чтобы взять все UV и трансформировать их по координатам и скэйлу)
Синтаксис:
Используется csharp
public class UVTile : MonoBehaviour {

    public bool remap = false;

    public int cols, rows; //количество и строк в текстуре
    public Vector2 uvTilePos;//позиция текстурного тайла

    float textureSizeX, textureSizeY; //размеры текстуры
    Texture texture;// сама текстура
    Mesh originMesh;//оригинальный меш
    Mesh tmp_mesh;//инстанс оригинального меша
    bool prepared = false;

    void Start ()
    {
        if (!prepared)
            prepare();

    }

    void Update ()
    {
        if (remap)
        {
            remap = false;
            Remap();
        }
           
        }

    public void prepare()
    {
        texture = GetComponent<MeshRenderer>().materials[0].GetTexture("_MainTex");
        originMesh = GetComponent<MeshFilter>().mesh;
        prepared = true;
    }

    public void Remap()
    {
        tmp_mesh = Mesh.Instantiate(originMesh); //создали новый меш из оригинального

        List<Vector2> UVs = new List<Vector2>();
        tmp_mesh.GetUVs(0, UVs); //забрали UV координаты

        //посчитали ширину и высоту тайла в текстурных координатах (0,1)
        float tileWidthInTextureCoordinates = (float)texture.width / cols / texture.width;
        float tileHeightInTextureCoordinates = (float)texture.height / rows / texture.height;

        List<Vector2> newUVs = new List<Vector2>();

        //задали новые координаты с учетом столбов, строк и позиции тайла
        foreach (Vector2 uv in UVs)
            newUVs.Add(new Vector2(uv.x * tileWidthInTextureCoordinates + uvTilePos.x * tileWidthInTextureCoordinates, uv.y * tileHeightInTextureCoordinates + uvTilePos.y * tileHeightInTextureCoordinates));

        tmp_mesh.SetUVs((0, newUVs);
        GetComponent<MeshFilter>().sharedMesh = tmp_mesh;//profit
    }
}
 

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

Вот у меня собственно два вопроса: 1. почему общий материал (grid) натягивается на весь объект игнорируя равертку? 2. Почему текстура-картинка (pieceMat) на некоторых пазлах
расползается?
PS Если создаю 3*3 то все идеально, если больше - верхняя текстурка расползается на некоторых пазлах.

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 24 апр 2017, 15:00
MANMANA
Ваша развертка - не развертка, а так себе..
Посмотрите, как разворачивается обычный куб в блендере.
Где швы на модели?
Создайте один кубический пазл, сделайте для него развертку, скопируйте столько паззл(икра), сколько нужно, объедините их в один объект, разместите верхние части развертки пазлов рядом друг с другом согласно их расположению в собранном виде, разместите их согласно собранному пазлы в 3д пространстве. Выделите каждый паззлик в отдельный объект. Наложите рисунок в гимпе или фотошопе на свою развертку. Загрузите все в Юнити.
Здесь все есть:
Статьи
даже про "ленивую" развертку есть

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 24 апр 2017, 19:39
tgk
В том и дело, что заранее не известно сколько паззликов нужно. Я писал об этом. Вы же предлагает намертво прибить текстуру к определенному количеству? Паззлы создаются динамически, динамически подставляется и текстура-картинка. По развертке я догадываюсь, что она не правильная, но моя цель указать конкретную часть объекта на котором будет отображаться часть текстуры, как это по другому сделать чего-то не допер.

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 24 апр 2017, 21:24
MANMANA
Тогда атласы текстур.
Какие-нибудь динамически создаваемые в процессе игры.
Верхняя часть одного паззла развернута, например, на все собственное uv-пространство, а другие поверхности - можно заливать/окрашивать одним цветом.
Комбинируем в атлас.
Вуаля!

Другое вариант - резать картинку и накладывать на вариант развертки, приведенный выше
Segmenting image (at runtime) for puzzle...

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 07:41
unregistered
MANMANA писал(а):Верхняя часть одного паззла развернута, например, на все собственное uv-пространство

Т.е. сделать составной пазл? И не совсем понял зачем тут объединять в атласы, по сути у меня всегда два материала - один для основы, второй - для "крышки"
со сдвинутыми UV? Кстати по ссылке тоже самое и делается, что и у меня в скрипте, ну почти. только там квад. И все-таки не понятно, почему мой вариант не работает как надо.В блендере все отлично, я свою развертку скайлю, поворачиваю как угодно и на модели четко только верхняя грань, а в юнити плывет, ладно бы все было криво, так нет же =( Ощущение что юнька сама додумывает развертку

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 09:02
Valentinus
может вам сделать проще- к верхней грани брусочка прикрепить спрайт или плайн , и в него закидывать нужный фрагмент?
при таком способе можно запросто запилить и пазлинки разной формы. :)

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 11:41
tgk
Вот похоже, что так делать и придется. в принципе уже и попробовал, но все это костыли имхо (

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 14:40
Valentinus
tgk писал(а):Вот похоже, что так делать и придется. в принципе уже и попробовал, но все это костыли имхо (

не нравится "наклейка" - сделайте пустую коробку без верха, и плайном закройте, разницы вообще никто не заметит:).

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 15:36
MANMANA
unregistered писал(а):И все-таки не понятно, почему мой вариант не работает как надо.В блендере все отлично, я свою развертку скайлю, поворачиваю как угодно и на модели четко только верхняя грань, а в юнити плывет, ладно бы все было криво, так нет же =( Ощущение что юнька сама додумывает развертку

У вас на скрине я увидел развертку только одной поверхности вашей модели.
Где развертка остальных сторон?

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 16:32
tgk
Valentinus писал(а):
tgk писал(а):Вот похоже, что так делать и придется. в принципе уже и попробовал, но все это костыли имхо (

не нравится "наклейка" - сделайте пустую коробку без верха, и плайном закройте, разницы вообще никто не заметит:).

Так я так уже и сделал но не нра.
MANMANA писал(а):У вас на скрине я увидел развертку только одной поверхности вашей модели.
Где развертка остальных сторон?

Все верно,я просто не соображу как сделать по феншую.
Как сделать чтоб одно на другое наложить в том месте в котором надо? Я только так и придумал и вижу что хреново придумал... Что можно сделать если не городить огород из мешей? :((

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 16:56
tgk
А можно сделать такое чудо как две развертки для разных материалов? =) Формат вроде этого не позволяет, ну а вдруг

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 17:03
tgk
Сделать полноценную развертку, как говорит manamana, а к текстуре-наклейке применять только те UV которые надо, но возможно ли это? просто на будущее я не хотел бы зависеть от геометрии поверхности, вот этого и добиваюсь.

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 25 апр 2017, 21:29
MANMANA
Можно использовать тайлинг и оффсет, но получится много материалов для многосоставных паззлов

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 26 апр 2017, 02:33
unregistered
MANMANA писал(а):Можно использовать тайлинг и оффсет, но получится много материалов для многосоставных паззлов

С самого начала так и хотел, ага ) Но прикинул 10*10 пазлов и 100 материалов явный перебор. Значит выхода нет кроме как два меша? Может есть вариант с шейдером? Типа рисовать только то что в заданных UV а остальное отсекать, но в шейдерах я даже не 0, а скорее -1

Re: наложить часть текстуры на определенный участок объекта

СообщениеДобавлено: 26 апр 2017, 03:16
DbIMok
tgk писал(а):Почему текстура-картинка (pieceMat) на некоторых пазлах расползается?

может быть из-за настроек импорта - скейлится в POT, включен мипмаппинг (берется уменьшенная текстура), билинейная фильтрация соседние пиксели усредняет, расчет uv не учитывает пиксели - любая из этих, если считать, что проблема не в развертке.
tgk писал(а):есть пазлы в неопределенном количестве, надо их затекстурить общей текстурой и поверх положить частички другой текстуры которая собственно и представляет собой картинку собираемую игроком.

самый простой выход из положения - на кубики натягиваем материал со сплошным цветом. дочерним объектом на крышку цепляем Quad, на него материал с пазлотекстуркой, расчитываем квадам УВ