Материалы с типом рендера 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 шт):
Генерить для каждого типа свой объект не обязательно. Можно все делать одним используя сабмеши и лист материалов в рендере соответствующие каждому сабмешу по индексу. И при генерации создается какой-нибудь справочник для чанка какие материалы под каким индексом ставидь поскольку не у каждого чанка присудствуют те или иные.
_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 не отличая одного от другого.
Как комбинировать текстуры
Есть подход используемый к примеру в Warcraft III.
Каждый тайл это бинарное число выстраивающееся из того какие края задействованы.
В W3 один ассет по 16 тайлов, которые покрывает все возможные сочетания границ и 16 заполненных, которые рандомизируются, что-бы текстура не повторялась.
Все ассеты имеют строгий порядок наложения и в итоге все очень симпатично выглядело.
Обычно речь идет о генерации новой текстуры из набора ассетов на старте. Тоже самое можно сделать и для безконечных чанков, генерить и удалять, хотя для далекой прорисовки это вряд-ли подходит, память быстро закончится, по крайне мере если генерить в одном и том-же разрешении. Алгоритмы можно найти в интернете
Если говорить о постоянно изменяемой текстуры как у вас, можно конечно написать шейдер в который передается 2d массив бинарных чисел для каждого слоя, это 100% только Fragment шейдер, да и с ним я не знаю что будет с производительностью, тут нужно тестить. Плюс грамотно оптимизировать, учитывая что отличаются только передаваемые массивы, использовать не много инстантиейтов материала а один c PropertyBlock как тут.
Такой-же подход используют для смягчения миров сгенерированных из кубов, только числа 8-битные вместо 4, как в этом видео.








