Раскраска меша

Раздел, посвящённый всему, что связано с программированием для Редактора Юнити. Скрипты Редактора, Wizards и прочее.

Раскраска меша

Сообщение AndreyMust19 07 ноя 2012, 18:53

Пришла мне такая мысль - задавать вершинам меша одинаковые UV-координаты текстуры, используемой в качестве палитры и тем самым раскрашивать трианглы разными цветами, обходясь одним материалом. Написал расширение редактора и выяснил что одни меши красятся как надо, а другие - неправильным способом.
Например, из стандартных примитивов правильно красится только Cube, у остальных изменение цвета вершины отражается на соседних трианглах.
Из своих 3-х мешей правильно красится только 1, причем из-за ошибки импорта:
ImportFBX Errors:
Unsupported wedge mapping mode type. Please report this bug.

На других 2-х мешах та же ошибка. Но разница в том что у "неправильных" мешей кол-во вершин и трианглов совпадает с изначальным в модели. А вот у первого меша после импорта вместо 17 вершин целых 40.
Нашел ObjExporter, сохранил Cube и первый меш в файл. Выяснилось что у куба каждая вершина дублируется 3 раза, а у меша b01 некоторые даже 4 раза. То есть получается что эти меши не представляют из себя целое тело, а "склеены" из отдельных треугольников так, что каждая вершина используется только одним полигоном.

Сейчас пытаюсь сделать функцию для дублирования вершин:
Синтаксис:
Используется csharp
        // дублируем вершины чтобы краска нормально легда
        void DuplicateV()
        {
                Debug.Log("Duplicate vertices");
                // старый меш
                Mesh oldMesh = mf.sharedMesh;
                int[] t = new int[oldMesh.triangles.Length];
                int numT = oldMesh.triangles.Length/3;
                int numV = oldMesh.triangles.Length; //2*oldMesh.vertices.Length;
                // новый меш
                Mesh newMesh = new Mesh();
                newMesh.Clear();
                newMesh.vertices = new Vector3[numV];
                newMesh.triangles = new int[numV];
                newMesh.uv = new Vector2[numV];
                // формируем новый меш
                int i, index, iv;
                i = iv = 0;
                while (i != numT) {
                        Debug.Log("i = "+i);
                        index = i*3;
                        newMesh.vertices[iv] = oldMesh.vertices[ oldMesh.triangles[index] ];
                        newMesh.triangles[index] = iv++;
                        newMesh.vertices[iv] = oldMesh.vertices[ oldMesh.triangles[index+1] ];
                        newMesh.triangles[index+1] = iv++;
                        newMesh.vertices[iv] = oldMesh.vertices[ oldMesh.triangles[index+2] ];
                        newMesh.triangles[index+2] = iv++;
                        ++i;
                }
                newMesh.tangents = oldMesh.tangents;
                //newMesh.normals = oldMesh.normals;
                newMesh.RecalculateNormals();
                newMesh.RecalculateBounds();
                //newMesh.Optimize();
                // записываем
                mf.sharedMesh = newMesh;
        }

но не выходит. Меш все равно красится неправильно, а после сохранения меша в obj дублирующихся вершин нет. Надо как-то преобразовать меш, чтобы раскраска выполнялась правильно, а также написать функцию оптимизации, чтобы убирать дублирующиеся вершины с одинаковыми цветами.

В архиве 3 меша зданий (b01 раскрашивается правильно).
Немного позже выложу скрипт раскраски меша и напишу как им пользоваться, чтобы попробовать.

Unity 3.3.0f4
У вас нет доступа для просмотра вложений в этом сообщении.
Нужна помощь? Сами, сами, сами, сами, сами... делаем все сами
AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Раскраска меша

Сообщение AndreyMust19 07 ноя 2012, 19:10

В этом приложении - скрипты для раскраски меша и немного ресурсов. Нужно:
1) Скопировать содержимое архива в проект
2) Добавить копию префаба на сцену
3) На объекте, к-й хочется раскрасить, должен быть MeshFilter и MeshCollider с одним и тем же мешем. Еще не забудьте диффузную текстуру у материала поменять на файл palette.jpg, иначе красок вы не увидите!
4) В меню нажать Component -> Switch Mesh Editor. Снимется выделение с текущего активного объекта, еще в консоли может появиться пара ошибок, но это не страшно.
5) Теперь при выборе объекта с MeshFilter в инспекторе должна появиться палитра (файл pallete.jpg).

Для выбора и снятия выделения с граней просто щелкаем по ним левой кнопкой мыши. У выбранных граней в центре появляется белый квадрат. Чтобы сменить UV вершин выбранных граней покрасить, просто выбираем другой цвет на палитре. Нажатие Enter применяет цвет первой выделенной грани, кнопка Esc снимает выделение.
Попробуйте Cube и b01 - цвет должен заполнять только выделенные грани, не отражаясь на соседних.
Если префаб у вас не загружается то:
1) Создаем пустой объект
2) Меняем тег на "GameController"
3) Добавляем скрипт GlobalMaterials_Container, затем в поля Palette и Cursor переносим одноименные файлы из каталога Textures. Параметр MaxSize делаем по своему вкусу (я ставлю 200).

Очень хочу чтобы вы помогли мне исправить функцию преобразования меша!
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось AndreyMust19 07 ноя 2012, 19:42, всего редактировалось 2 раз(а).
Нужна помощь? Сами, сами, сами, сами, сами... делаем все сами
AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Раскраска меша

Сообщение seaman 07 ноя 2012, 19:34

у "неправильных" мешей кол-во вершин и трианглов совпадает с изначальным в модели

Ну естественно - это неправильные меши. Вершины всегда дублируются если на развертке будет разрыв. Развертку без разрыва можно сделать только у плейна. Вершины дублируются у разных групп сглаживания. Возможно еще в каких то случаях.
Следовательно если вершины не дублировались - значит у них как минимум неправильно сделана развертка.
но это не страшно.

Терпеть не могу недоделанные скрипты. Разбираться что в них не так нет времени и желания.
Теперь при выборе объекта с MeshFilter в инспекторе должна появиться палитра (файл pallete.jpg).

Ничего не появляется.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Раскраска меша

Сообщение AndreyMust19 07 ноя 2012, 19:40

У всех трех мешей нет развертки, только материал. И как тогда объяснить что стандартный куб так разительно отличается в вершинах от других примитивов? Если я сделаю фейковую развертку моделей отдельно по одной грани, это сработает. И как быть если загруженный меш - самый обычный, без материала вообще. Все равно как-то надо создавать дубликаты прямо в Unity.

UPD: Ура, сделал развертку, работает. Вершин стало больше и цвет ложится только на выбранные грани. Осталось понять как сделать тоже самое в редакторе [unity 3D].
Последний раз редактировалось AndreyMust19 07 ноя 2012, 19:50, всего редактировалось 1 раз.
Нужна помощь? Сами, сами, сами, сами, сами... делаем все сами
AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Раскраска меша

Сообщение seaman 07 ноя 2012, 19:49

как тогда объяснить что стандартный куб так разительно отличается в вершинах от других примитивов

У него есть развертка. У остальных примитивов тоже. Сверить не могу - Ваш скрипт не работает.
как быть если загруженный меш - самый обычный, без материала вообще

самый обычный меш имеет развертку. Если не имеет - выбросите его нафиг. Он никому не нужен.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Раскраска меша

Сообщение AndreyMust19 07 ноя 2012, 21:41

Пока не разберусь со скриптом, решил делать в (blander_sm) так:
1) Выделяю все грани
2) Faces -> Quads to Tris
3) Unwrap
4) В окне развертки Pack Islands.
Но иногда все равно случается что у двух соседних граней есть вершина с одинаковыми координатами. Из-за этого приходится пересматривать все грани отдельно, очень геморойно.
Нужна помощь? Сами, сами, сами, сами, сами... делаем все сами
AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Раскраска меша

Сообщение waruiyume 08 ноя 2012, 01:41

А не зачем использовать ЮВишки, если есть цвета вершин?

Повесить на ГО с меш фильтром, вызвать "split" из контекстного меню компонента.
Синтаксис:
Используется csharp
//Создаёт массив вершин, равный количеству вершин во всех трисах, копирует (изменяя размер массивов) нормали и ЮВишки, переписывает индексы вершин в трисах.

using UnityEngine;

[ExecuteInEditMode]
public class NewBehaviourScript : MonoBehaviour
{

    Color[] colors;

    public Color[] pColors;


        [ContextMenu("split")]
        void SplitTris ()
        {
            MeshFilter filter = GetComponent<MeshFilter>();
            Mesh mesh = filter.mesh;


            int[] tris = mesh.triangles;

        Vector3[] oldVtx = mesh.vertices;
        Vector3[] newVtx = new Vector3[mesh.triangles.Length];

        int[] newTris = new int[newVtx.Length];

        Vector3[] normals = mesh.normals;
        Vector3[] newNormals = new Vector3[newVtx.Length];

            Vector2[] oldUV = mesh.uv;
        Vector2[] newUV = new Vector2[newVtx.Length];

            colors = new Color[newVtx.Length];
        pColors = new Color[tris.Length/3];

            for (int i = 0; i < pColors.Length; i++)
            {
                Vector3 rc = Random.insideUnitSphere*0.5f+Vector3.one*0.5f;
            pColors[i] = new Color(rc.x, rc.y, rc.z, 1f);
            }

            for (int i = 0; i < tris.Length; i ++)
        {
            newVtx[i] = oldVtx[tris[i]];
            newNormals[i] = normals[tris[i]];
            newUV[i] = oldUV[tris[i]];
        }


            for (int i = 0; i < newTris.Length; i++)
                newTris[i] = i;


            mesh.Clear();

            mesh.vertices = newVtx;
            mesh.uv = newUV;
            mesh.normals = newNormals;
            mesh.triangles = newTris;
        }


    void Update()
    {
        MeshFilter filter = GetComponent<MeshFilter>();
        Mesh mesh = filter.mesh;
        Vector3[] normals = mesh.normals;
        Vector3[] oldVtx = mesh.vertices;

        Matrix4x4 mat = transform.localToWorldMatrix;

        for (int n = 0; n < normals.Length; n++)
        {
            Vector3 normal = normals[n];
            Vector3 p = oldVtx[n];

            Debug.DrawRay(mat.MultiplyPoint3x4(p), mat.MultiplyVector(normal*0.05f));
        }

        if (colors==null)
        {
            return;
        }

        for (int i = 0; i < colors.Length; i++)
            colors[i] = pColors[i/3];

        mesh.colors = colors;

        filter.mesh = mesh;

    }
}
 


Синтаксис:
Используется glsl
Shader "Custom/VertexColor" {
        Properties {
                _MainTex ("Base (RGB)", 2D) = "white" {}
        }
        SubShader {
                Tags { "RenderType"="Opaque" }
                LOD 200
               
                CGPROGRAM
                #pragma surface surf Lambert

                sampler2D _MainTex;

                struct Input {
                        float2 uv_MainTex;
                        float4 color:COLOR;
                };

                void surf (Input IN, inout SurfaceOutput o) {
                        half4 c = tex2D (_MainTex, IN.uv_MainTex);
                        o.Albedo = c.rgb * IN.color.rgb;
                        o.Alpha = c.a * IN.color.a;
                }
                ENDCG
        }
        FallBack "Diffuse"
}

 
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Раскраска меша

Сообщение AndreyMust19 08 ноя 2012, 13:16

Спасибо, немного поправил и получилось как раз то, что нужно! :-bd

01.PNG
У вас нет доступа для просмотра вложений в этом сообщении.
Нужна помощь? Сами, сами, сами, сами, сами... делаем все сами
AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Раскраска меша

Сообщение jetyb 16 ноя 2012, 12:29

Дублировать необязательно.
Специально для вывода одного материала в разных цветах придумали цвета вершин.
Класс Mesh из unity не содержит цветов вершин(правда в шейдерах такое понятие есть), но цвета можно хранить в тангенсах вершин меша.
jetyb
Адепт
 
Сообщения: 1486
Зарегистрирован: 31 окт 2011, 17:21

Re: Раскраска меша

Сообщение waruiyume 16 ноя 2012, 13:01

jetyb писал(а):Дублировать необязательно.

И Вы, разумеется расскажите, как добиться эффекта чётких границ, без дублирования вершин?
jetyb писал(а):Класс Mesh из unity не содержит цветов вершин

Прям таки и не содержит?
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Раскраска меша

Сообщение AndreyMust19 30 мар 2013, 16:56

02.PNG
У вас нет доступа для просмотра вложений в этом сообщении.
Нужна помощь? Сами, сами, сами, сами, сами... делаем все сами
AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Раскраска меша

Сообщение alex4x 22 сен 2016, 15:29

Добрый день. Подскажите, а можно использовать цвет узлов с умножением на текстуру (рельеф текстурой сделать) ?
alex4x
UNец
 
Сообщения: 11
Зарегистрирован: 29 июн 2016, 15:12


Вернуться в Editor

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2