Текстура в шейдере

Шейдеры и все-все-все.

Текстура в шейдере

Сообщение Jarico 02 июн 2020, 15:09

Как рисовать в шейдере примитивную фигуру с наложением на неё текстуры?

Допустим нужно нарисовать круг и заполнить его внутри текстурой
Github: _https://github.com/redheadgektor
Discord: Конь! Чаю!#9382 (сижу редко)
YouTube: _https://www.youtube.com/channel/UCPQ04Xpbbw2uGc1gsZtO3HQ
Telegram: _https://t.me/redheadgektor
Аватара пользователя
Jarico
Адепт
 
Сообщения: 1084
Зарегистрирован: 06 янв 2019, 17:37
Откуда: 0xDEAD
Skype: none
  • Сайт

Re: Текстура в шейдере

Сообщение waruiyume 02 июн 2020, 20:53

При традиционном подходе(пара: вершинный-пиксельный шейдер)- никак(я объясню ниже, что имел в виду). Есть экзотичные геометрические шейдеры- ими можно генерировать геометрию, ваш Кэп. Но они не популярны ввиду своей относительной тормознутости, удачи найти нормальные туторы по ним.
При традиционном подходе, пиксельный шейдер запускается для многих пикселей одновременно, свой пля каждого(в реальности для групп по несколько пикселей, но для нас это ничего не меняет). Ввиду параллельности, каждый пиксель знает только о себе и менять может только себя. По этому именно нарисовать что-то нельзя.
Можно посчитать какой должен быть цвет пикселя с помощью функции, которая принимает позицию(или, допустим, цвет текстуры в этом месте), и возращает цвет исходя из этого. Круг нарисовать будет довольно просто:
если дистанция от текущего пикселя до центра, допустим текстурных координат, чем радиус круга, то ничего не рисуется или пиксель рисуется чёрным.
Попробуйте начать с нодовых редакторов типа "Amplify shader editor", а когда немного разберётесь пробовать текстовые варианты, потому как текстовая кухня крайне сумбурна и в ней чёрт ногу сломит.

Несколько ссылок:
https://en.wikibooks.org/wiki/Cg_Programming //устаревшее, но поможет разобраться в принципах
https://en.wikibooks.org/wiki/GLSL_Programming/Unity //более актуальное, но есть не всё то, что в предыдущем

https://catlikecoding.com/unity/tutorials/rendering //годные уроки, но у автора есть склонность к оверинженерингу

Пример шейдера(материал нужно натянуть на объект у которого есть UV координаты(встроенный куб))
Синтаксис:
Используется glsl
Shader "Unlit/Circle"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                float dist = distance(0.5, i.uv);
                col*=step(dist, 0.5);

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

Re: Текстура в шейдере

Сообщение seaman 02 июн 2020, 20:59

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

Re: Текстура в шейдере

Сообщение waruiyume 02 июн 2020, 21:11

либо raymarch

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

Re: Текстура в шейдере

Сообщение seaman 02 июн 2020, 22:19

Raymarchin-ом можно отрисовать любую поверхность, уж круг то элементарно
http://jamie-wong.com/2016/07/15/ray-ma ... functions/
https://medium.com/@shahriyarshahrabi/r ... c72664252a

Вот сложный пример
https://www.shadertoy.com/view/MdX3Rr

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

Re: Текстура в шейдере

Сообщение Jarico 02 июн 2020, 23:20

waruiyume писал(а):потому как текстовая кухня крайне сумбурна и в ней чёрт ногу сломит.


Сделал смену дня и ночи на основе дефолтного процедурного скайбокса (из UnityBuildInShaders)
Есть небо голубое, ночное небо со звёздами, не хватает луны но вот как прилепить луну на внутреннюю половину сферы ума не приложу. Был вариант с наложением поверх звёзд еще одного слоя с кубической прозрачной текстурой и луной но фаз лун очень много и это уж думаю слишком будет занимать видео память ибо нужно ведь постоянно держать текстуры фаз в памяти + я учитываю долготу и широту, дату и время (http://www.stjarnhimlen.se/comp/ppcomp.html). Широта, долгота, дата и время всегда (почти) соответствуют реальным положениям небесных тел и на это идёт расчёт

Я использую URP и надумываю не использовать такой метод рисования фаз луны через шейдер а просто создать меш сферы с натянутой текстурой луны на сцене который будет висеть якобы в небе и уже шейдером для луны имитировать фазы луны
Github: _https://github.com/redheadgektor
Discord: Конь! Чаю!#9382 (сижу редко)
YouTube: _https://www.youtube.com/channel/UCPQ04Xpbbw2uGc1gsZtO3HQ
Telegram: _https://t.me/redheadgektor
Аватара пользователя
Jarico
Адепт
 
Сообщения: 1084
Зарегистрирован: 06 янв 2019, 17:37
Откуда: 0xDEAD
Skype: none
  • Сайт

Re: Текстура в шейдере

Сообщение iNji555 08 июн 2021, 07:49

waruiyume писал(а):При традиционном подходе(пара: вершинный-пиксельный шейдер)- никак(я объясню ниже, что имел в виду). Есть экзотичные геометрические шейдеры- ими можно генерировать геометрию, ваш Кэп. Но они не популярны ввиду своей относительной тормознутости, удачи найти нормальные туторы по ним.
При традиционном подходе, пиксельный шейдер запускается для многих пикселей одновременно, свой пля каждого(в реальности для групп по несколько пикселей, но для нас это ничего не меняет). Ввиду параллельности, каждый пиксель знает только о себе и менять может только себя. По этому именно нарисовать что-то нельзя.
Можно посчитать какой должен быть цвет пикселя с помощью функции, которая принимает позицию(или, допустим, цвет текстуры в этом месте), и возращает цвет исходя из этого. Круг нарисовать будет довольно просто:
если дистанция от текущего пикселя до центра, допустим текстурных координат, чем радиус круга, то ничего не рисуется или пиксель рисуется чёрным.
Попробуйте начать с нодовых редакторов типа "Amplify shader editor", а когда немного разберётесь пробовать текстовые варианты, потому как текстовая кухня крайне сумбурна и в ней чёрт ногу сломит.

Несколько ссылок:
https://en.wikibooks.org/wiki/Cg_Programming //устаревшее, но поможет разобраться в принципах
https://en.wikibooks.org/wiki/GLSL_Programming/Unity //более актуальное, но есть не всё то, что в предыдущем

https://catlikecoding.com/unity/tutorials/rendering //годные уроки, но у автора есть склонность к оверинженерингу

Пример шейдера(материал нужно натянуть на объект у которого есть UV координаты(встроенный куб))
Синтаксис:
Используется glsl
Shader "Unlit/Circle"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                float dist = distance(0.5, i.uv);
                col*=step(dist, 0.5);

                return col;
            }
            ENDCG
        }
    }
}
 


Подскажи, пожалуйста, такой момент. Можно этот код поменять так, чтобы рисовало квадрат заданного цвета в заданной координате? И можно ли как-то управлять этим процессом из скриптов юнити?
Цель сделать пиксельный экран заданного разрешения и отрисовывать там из кода разные фигуры попиксельно. Пока реализовал это через управление спрайтом, но оно тормозное (особенно на телефоне), и все говорят используй шейдеры, но никто не говорит как, и нагуглить эту магию тоже не получается. Этот пост и твой код, пока самое близкое что нашел.
iNji555
UNец
 
Сообщения: 15
Зарегистрирован: 07 фев 2020, 21:40

Re: Текстура в шейдере

Сообщение waruiyume 08 июн 2021, 10:15

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


Вернуться в Shader Lab

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

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