Материалы с типом рендера Fade работают не правильно друг с другом

У меня есть мир сгенерированный шумом перлина и разделенный на типы высот/биомы.

Мир Он состоит из скриптом сделанных мешей (чанков) 60 на 60 клеток каждый. Но так как я хочу в зависимости от поры года менять цвет каждого биома отдельно (например снег- белый, но гора должна остаться такой же), то я разделил каждый чанк на под-меши, и у каждого своя текстура. Таким образом каждый подмеш отвечает за свой биом.

Иерархия:

Иерархия

Чанк:

Чанк

Чанк без одного биома (для наглядности):

Чанк без одного биома (для наглядности)

У текстур, те пиксели которые находятся на месте где не подходящий биом - прозрачные. Чтоб это работало мне пришлось менять тип рендера материала каждого чанка на Fade таким вот образом:

Material material = new Material(Shader.Find("Standard"));
material.SetFloat("_Mode", 2);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = 3000;

Но если с тем чтобы эти материалы работали друг с другом нормально я поборолся, то вот есть еще меш воды который тоже должен быть полупрозрачным, как тут:

введите сюда описание изображения

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

А когда я включаю меш воды как Fade то он не работает с мешами чанков которые тоже Fade. И вода отрисовывается то выше чанков, то чанки отрисовываются выше воды. Точнее те чанки что ближе к камере отрисовываются выше воды, а те что дальше - ниже воды:

введите сюда описание изображения

Как мне правильно сделать? Или поменять структуру чанков, но как то так чтоб можно было цвет каждого биома менять отдельно, может есть у кого предположения?

Или подружить материалы чанков и воды, только как?

Может есть у кого идеи на этот счет?

PS: Есть вариант сделать материалы мешей как cutout тогда все работает как надо, НО, появляются на краях черные полосы, к тому же эти края совсем не так как хотелось бы работают со светом иногда, может это можно как то исправить?

Черные полосы:

введите сюда описание изображения

Выглядит как бордерлендс (может по этому он так и называется потому что там все нарисовано с этими границами? хд).


Ответы (2 шт):

Автор решения: Yaroslav

Генерить для каждого типа свой объект не обязательно. Можно все делать одним используя сабмеши и лист материалов в рендере соответствующие каждому сабмешу по индексу. И при генерации создается какой-нибудь справочник для чанка какие материалы под каким индексом ставидь поскольку не у каждого чанка присудствуют те или иные.

_mesh.subMeshCount = 3;
_mesh.SetTriangles(_mountainTriangles, 0);
_mesh.SetTriangles(_forestTriangles, 1);
_mesh.SetTriangles(_grassTriangles, 2);

На тему материалов Fade для таких объектов использовать крайне не рекомендуется и не понятно зачем.

По сути меняя времена года у вас все текстур это непрерывное переходное состояние из одной в другую, например из зеленой летней травы в пожелтевшую осеннюю. Напишите свой простенький Fragment шейдер интерполяции текстуры. Fragment самый легинький по нагрузке шейдер, документация в помощь, а Fade тяжелый.

fixed4 origin = tex2D(_OriginTex, i.uv);
fixed4 target = tex2D(_TargetTex, i.uv);
return origin+(target-origin)*_ProgressValue;

Либо в ShaderGraph.

И всего один какой-нибудь объект занимается обновлением _ProgressValue и сменой набора текстур при наступлении нового сезона, что тоже просто. ScroptableObject с ссылкой на материал и 4 текстуры, а вышеупомянутый объект работает с списком этих SO не отличая одного от другого.

→ Ссылка
Автор решения: Yaroslav

Как комбинировать текстуры

Есть подход используемый к примеру в Warcraft III.

введите сюда описание изображения

Каждый тайл это бинарное число выстраивающееся из того какие края задействованы.

В W3 один ассет по 16 тайлов, которые покрывает все возможные сочетания границ и 16 заполненных, которые рандомизируются, что-бы текстура не повторялась.

введите сюда описание изображения

Все ассеты имеют строгий порядок наложения и в итоге все очень симпатично выглядело.


Обычно речь идет о генерации новой текстуры из набора ассетов на старте. Тоже самое можно сделать и для безконечных чанков, генерить и удалять, хотя для далекой прорисовки это вряд-ли подходит, память быстро закончится, по крайне мере если генерить в одном и том-же разрешении. Алгоритмы можно найти в интернете

Если говорить о постоянно изменяемой текстуры как у вас, можно конечно написать шейдер в который передается 2d массив бинарных чисел для каждого слоя, это 100% только Fragment шейдер, да и с ним я не знаю что будет с производительностью, тут нужно тестить. Плюс грамотно оптимизировать, учитывая что отличаются только передаваемые массивы, использовать не много инстантиейтов материала а один c PropertyBlock как тут.


введите сюда описание изображения

Такой-же подход используют для смягчения миров сгенерированных из кубов, только числа 8-битные вместо 4, как в этом видео.

→ Ссылка