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

Наложение текстур по маске

СообщениеДобавлено: 17 ноя 2010, 09:35
Zaicheg
Нужно множить тайлы двух текстур по мешу в соответствии с чёрно-белой маской. Где чёрное -- тайлим первую, где белое -- тайлим вторую, где серое -- как-то смешиваем. Но хорошо будет даже и просто чёрно-белую маску без смешивания. Куда мне копать в шейдерах, чтобы это сделать?
Как дальнейшее развитие: держать на маске изображение в нескольких каналах и тайлить сразу несколько текстур в соответствии с каждым из этих каналов.

Гноблин согласился помочь мне :-bd , но так как самому всё равно надо в шейдерах разбираться помаленьку, то создаю тему.

Конечная цель: текстурировать ландшафт-меш (созданный в генераторе world machine) без создания для него огромной текстуры, полностью накрывающей его. Целевая платформа: iOS c нижним порогом на iPod Touch 2gen. Причина: текстуру 2048х2048 тот же айпод уже не съест (а даже на ландшафте 300х300м такой текстуры недостаточно для нормальной детализации).

Если я что непонятно спросил -- напишите, я разъясню хоть с картинками :)

Re: Наложение текстур по маске

СообщениеДобавлено: 17 ноя 2010, 10:24
Battle Angel Alita
А этот айПод 2Г умеет шэйдеры, или только FFP?

Re: Наложение текстур по маске

СообщениеДобавлено: 17 ноя 2010, 10:41
Zaicheg
Не нашёл пока точных сведений. По-моему, второе поколение не поддерживает, последующие -- поддерживают. У меня на руках как раз iPod Touch 2g, я могу провести какой-нибудь тест, только не знаю, что он из себя должен представлять

Re: Наложение текстур по маске

СообщениеДобавлено: 17 ноя 2010, 12:18
Battle Angel Alita
Посмотрела, в 2Г только FFP. Поэтому вот это вот
Как дальнейшее развитие: держать на маске изображение в нескольких каналах и тайлить сразу несколько текстур в соответствии с каждым из этих каналов.

будет сложновато сделать.

Для интерполяции п альфе есть команда lerp.
Выдержка из документации:
combine src1 lerp (src2) src3
Interpolates between src3 and src1, using the alpha of src2. Note that the interpolation is opposite direction: src1 is used when alpha is one, and src3 is used when alpha is zero.

Re: Наложение текстур по маске

СообщениеДобавлено: 17 ноя 2010, 14:09
Woolf
Вообще-то задача тривиальная для 4х текстур на земле. Используете текстуру с альфой, интенсивность канала - это интенсивность конкретной текстуры в данной точке. На шейдере считается простым умножением цвета текстуры на интенсивность канала. Код на юнити показать не могу, поскольку фреймворк юнити не знаю пока )

Если же задача стоит использовать больше 4 текстур на точку, то, возможно, вам лучше сделать многократный проход, каждый раз с конкретной текстурой. Это медленнее, зато гораздо универсальнее. Кроме того, можно использовать одну текстуру, которая содержит сразу много разных тайлов земли. Подобную технологию я использовал здесь:

http://forum.mirgames.ru/index.php?show ... imes&st=30

и шейдер там совсем не нужен, блендинг идёт по сетке ландшафта

Re: Наложение текстур по маске

СообщениеДобавлено: 17 ноя 2010, 14:17
Phoenics
Я себе для ланшафта примерно так делал смешивание, 4-х текстур с дополнительными коэфициентами

Синтаксис:
Используется glsl
PS_OUTPUT PSmain(in VS_OUTPUT IN)
{
        PS_OUTPUT psOut; // Выходная структура для G-Buffer-а
        psOut.Normal = IN.Normal; // Нормаль, ну это нам не нужно
        psOut.Normal.w = 20.0; // кажется тут был спекуляр
        float4 MaskSample = tex2Dlod(GCMMaskMap, float4(IN.TexCoord.x, IN.TexCoord.y, 0.0, IN.LodLevel-1)); // тут просто читаем маску. Через tex2Dlod у меня сделано потому что ланшафт сделан по технологии Geo-ClipMaps
        MaskSample = MaskSample * float4(10.0, 1.0, 1.0, 100.0); // это мы задаём коэффициенты разных текстур. Например у снега тут максимальный коэфициент (w), поэтому если где-то смешивается земля,трава и снег то будет виден снег восновном, а первый коэфициент вроде для камней или песка на них травы не будет видно. Короче этот вектор надо в параметры шейдера вынести
        float MaskDevisor = 1.0 / (MaskSample.x + MaskSample.y + MaskSample.z + MaskSample.w); // нормируем коэфициенты что бы сумма прочитанных из текстур значений не была больше 1, а то всё белым цветом зальёт
        MaskSample = MaskSample * MaskDevisor;// перемноажем коэфициенты
       
        float Multiplifer = 10.0;
       
        float4 SnowSample = MaskSample.r * tex2D(SnowMap, IN.TexCoord * Multiplifer * 8);// Делаем выборки из текстур, коэфициенты на окторые умножаем
        float4 GrassSample = MaskSample.g * tex2D(GrassMap, IN.TexCoord * Multiplifer * 8);// это скорее всего наскоро сляпаны для тайлинга. Не помню точно.
        float4 StoneSample = MaskSample.b * tex2D(StoneMap, IN.TexCoord * Multiplifer);// Их кароч в параметры шейдера надо выносить
        float4 SandSample = MaskSample.a * tex2D(SandMap, IN.TexCoord * Multiplifer * 8);//
       
        float4 Diffuse = SnowSample + GrassSample + StoneSample + SandSample; // собсно складываем и получаем смешивание по маске 4-х текстур с учётом коэфициентов приоритености текстур
        psOut.Diffuse = Diffuse; // запихитваем в g-buffer
        return psOut;
}


ЗЫ. А синтаксис HLSL не поддерживается или что там ему вписать что бы он правильно отобразил?

Re: Наложение текстур по маске

СообщениеДобавлено: 18 ноя 2010, 14:39
Zaicheg
Через конструкции ffp пока организовать не получилось. Пилю ещё. Собственно, первое знакомство с шейдерами. Систему Woolf пока просто не понял.
Как ещё при таком раскладе можно затекстурить ландшафт? Сделать большую rgb-текстуру и порезать её и ландшафт на куски, подгружая по необходимости?

Re: Наложение текстур по маске

СообщениеДобавлено: 18 ноя 2010, 16:37
Phoenics
Zaicheg писал(а):Систему Woolf пока просто не понял.


А что конкретно непонятно? Если про смешивание 4 текстур по маске, то там всё очень просто в моём шейдере это как раз реализовано. Просто у тебя в первом посте чёрнобелая маска, т.е. с одним каналом, а у нас используется RGBA маска, с 4-мя каналами, каждый из окторых задаёт коэфициент видимости. Цвета прочитанные из тайловых своей текстур умножаем на соотвествующие им веса из маски и складываем - поулчаем итоговый смешанный цвет.

Re: Наложение текстур по маске

СообщениеДобавлено: 18 ноя 2010, 16:59
Battle Angel Alita
Phoenics
У человека в системных требованиях значится древний айФон, который не только про шейдеры не знает, но и с FFP туго дружит.

Zaicheg
Тут мне вспомнилось что на айФонах только два текстурных юнита, т.е. внутри пасса можно только два раза сказать SetTexture... Поэтому придётся делать либо классический многопроходный блендинг, либо маску запекать в цвет вертекса.

Re: Наложение текстур по маске

СообщениеДобавлено: 24 ноя 2010, 23:48
Zaicheg
На данный момент выглядит так. Почему и как это работает -- не понимаю, потому что делал методом тыканья всяких кусков кода в стандартный VertexLit. Но работает, в т.ч. и на упомянутом девайсе. Сейчас буду дотыкивать для того, чтобы корректно работал на террейне, сшитом из нескольких кусков (хотя тут скорее надо uv-раскладку моделей править).
Поправка: со сшитым террейном тоже заработало, uv просто поправил.

Синтаксис:
Используется glsl
Shader "TerrainBlendMask"
{
        Properties
        {
                _Color ("Main Color", Color) = (1,1,1,1)
               
                _Grass ("Grass", 2D) = ""
                _Dirt ("Dirt", 2D) = ""
                _Mask ("Mask (Alpha)", 2D) = ""
        }

        SubShader
        {
                Tags { "RenderType"="Opaque" }
                LOD 100

                Pass
                {
                        Tags { "LightMode" = "Vertex" }
                       
                        Material
                        {
                                Diffuse [_Color]
                                Ambient [_Color]
                        }
                        Lighting On
                       
                        SetTexture [_Grass]
                        {
                                Combine texture * primary DOUBLE, texture * primary
                        }
                }      

                Pass
                {
                        Tags { "LightMode" = "Vertex" }
                       
                        Material
                        {
                                Diffuse [_Color]
                                Ambient [_Color]
                        }
                        Lighting On
                       
                        Blend SrcAlpha OneMinusSrcAlpha
                        SetTexture[_Dirt] {Combine texture * primary DOUBLE, texture * primary}
                        SetTexture[_Mask] {Combine previous, texture}
                }
        }
}

Re: Наложение текстур по маске

СообщениеДобавлено: 30 ноя 2010, 12:04
Zaicheg
Теперь ещё нужно запечь тени в ландшафт. Куда пилить?
Объекты, отбрасывающие тени (деревья большей частью), расставляются непосредственно в Unity.

Re: Наложение текстур по маске

СообщениеДобавлено: 07 дек 2010, 04:30
gnoblin
я бы потренировался со стандартным лайтмапером и vertexlit, потом бы допилил vertexlit до нужного состояния :)

Re: Наложение текстур по маске

СообщениеДобавлено: 07 дек 2010, 21:51
Battle Angel Alita
А если захочется(а захочется точно) больше двух текстур, да ещё плюс лайтмап - жирный получится шейдер. Впору подумать о чём-то вроде мега-текстуры.

Re: Наложение текстур по маске

СообщениеДобавлено: 07 дек 2010, 22:29
Zaicheg
О суициде впору думать )

Re: Наложение текстур по маске

СообщениеДобавлено: 10 фев 2011, 20:21
Zaicheg
Zaicheg писал(а):Теперь ещё нужно запечь тени в ландшафт. Куда пилить?
Объекты, отбрасывающие тени (деревья большей частью), расставляются непосредственно в Unity.

Я просто апну. Потому что так и не справился, а надо бы.