Работа c GPGPU (с шейдерами) в Unity3D

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Работа c GPGPU (с шейдерами) в Unity3D

Сообщение KoteKotovK 23 окт 2018, 15:18

Так как я ни черта не понимаю в шейдерах и отрисовке, то у меня назрел вопрос. Могу ли я как-нибудь узнать сработала ли никакая/частичная/полная отрисовка объекта на экране, как если бы он был бы чем-нибудь перекрыт? У меня есть шейдеры для спрайтов, которые позволяют мне делать такое -
Изображение
И было бы очень неплохо узнать о том, что сработала отрисовка красного перекрытия, в этом случае частичная. И как к этому обратиться я не понимаю, оч мало информации в интернете, а ведь кто-то игоры на видеокартах пишет. Если есть хотя бы что-то косвенно связанное с изучением написания шейдеров и работы с ними в моей стези, прошу поделитесь со мной.
KoteKotovK
UNITрон
 
Сообщения: 267
Зарегистрирован: 20 июн 2014, 06:41

Re: Работа c GPGPU (с шейдерами) в Unity3D

Сообщение jetyb 24 окт 2018, 07:48

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

Как получить текстуру:
- через стенсильный буфер. Задав Stencil параметры в шейдере пистолета. Требует отдельных танцев с выводом стенсильного буфера в текстуру. Правда в режиме Deferred стенсильный буфер не работает.
- рендерить один пистолет в таком же ракурсе в отдельную текстуру глубины, сравнить ее с обычной текстурой глубины.

Как анализировать текстуру:
- на CPU через GetPixels(). Просто и очень затратно.
- через ComputeShader. Идеально, но требует поддержки ComputeShader в системе.
- Последовательно рендерить текстуры в текстуры вдвое меньшего разрешения, пока не получится текстура из одной точки. В шейдере рейдера Проверять соседние пиксели и писать факт наличия особых пикселей.

Если что-то поняли, я вас поздравляю.
jetyb
Адепт
 
Сообщения: 1486
Зарегистрирован: 31 окт 2011, 17:21

Re: Работа c GPGPU (с шейдерами) в Unity3D

Сообщение KoteKotovK 24 окт 2018, 15:49

jetyb писал(а):Способ есть, только он завязан на неслабом таком уровне в шейдерах
В общем случае нужна текстура, в которой как-то выделены перекрывающиеся пиксели объекта или простые пиксели пистолета.
Потом нужно проверить все пиксели этой текстуры на наличие перекрывающихся.

Как получить текстуру:
- через стенсильный буфер. Задав Stencil параметры в шейдере пистолета. Требует отдельных танцев с выводом стенсильного буфера в текстуру. Правда в режиме Deferred стенсильный буфер не работает.
- рендерить один пистолет в таком же ракурсе в отдельную текстуру глубины, сравнить ее с обычной текстурой глубины.

Как анализировать текстуру:
- на CPU через GetPixels(). Просто и очень затратно.
- через ComputeShader. Идеально, но требует поддержки ComputeShader в системе.
- Последовательно рендерить текстуры в текстуры вдвое меньшего разрешения, пока не получится текстура из одной точки. В шейдере рейдера Проверять соседние пиксели и писать факт наличия особых пикселей.

Если что-то поняли, я вас поздравляю.

Думал ранее ознакомиться с ComputeShader, но мои желания разбились об реальность =( Компьютер очень старый и не поддерживает OpenGL 4.3+ (Работаю под линухом), но как идея она великолепна, особенное интересно могу ли я переложить вычисления на видеоускоритель CPU, типа Intel Graphics'а и аналогичного у AMD, он же вроде практически не используется в играх, просто простаивает, а если бы я могу задействовать на нём вычисления через ComputeShader, было бы интересно переложить на него какие-нибудь небольшие плюшки-вычисления, да и на производительность это никак повлиять не должно.
KoteKotovK
UNITрон
 
Сообщения: 267
Зарегистрирован: 20 июн 2014, 06:41

Re: Работа c GPGPU (с шейдерами) в Unity3D

Сообщение Cyrix 30 ноя 2018, 12:26

Есть шейдер, который симулирует атмосферу:
Синтаксис:
Используется csharp
Shader "Atmosphere Inverted"
{
        Properties
        {
                _MainColor("_MainColor", Color) = (1,1,1,1)
                _SecondaryColor("_SecondaryColor", Color) = (1,1,1,1)
                _EdgeDensity("_EdgeDensity", Range(0.1,3) ) = 1.725506
                _Ramp("_Ramp", Range(0.1,3) ) = 1
                _MainTex("_MainTex", 2D) = "white" {}
        }
       
        SubShader
        {
                Tags
                {
                        "Queue"="Transparent+100"
                        "IgnoreProjector"="False"
                        "RenderType"="Transparent"
                }

                Cull Back
                ZWrite On
                ZTest LEqual
                ColorMask RGBA
                Blend SrcAlpha OneMinusSrcAlpha
                Fog{ Mode Off }


                CGPROGRAM
                #pragma surface surf BlinnPhongEditor  vertex:vert
                #pragma target 2.0

                float4 _MainColor;
                float4 _SecondaryColor;
                float _EdgeDensity;
                float _Ramp;
                sampler2D _MainTex;

                struct EditorSurfaceOutput {
                        half3 Albedo;
                        half3 Normal;
                        half3 Emission;
                        half3 Gloss;
                        half Specular;
                        half Alpha;
                        half4 Custom;
                };
                       
                inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
                {
                        float4 SmoothStep0= _MainColor * Luminance( light.xyz ) * _Ramp;
                        float4 Multiply0=SmoothStep0 * float4( s.Albedo.x, s.Albedo.y, s.Albedo.z, s.Alpha );
                        return Multiply0;
                }

                inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
                {
                        half3 h = normalize (lightDir + viewDir);
                       
                        half diff = max (0, dot ( lightDir, s.Normal ));
                       
                        half nh = max (0, dot (s.Normal, h));
                        half spec = pow (nh, s.Specular*128.0);
                       
                        half4 res;
                        res.rgb = _LightColor0.rgb * diff;
                        res.a = spec * Luminance (_LightColor0.rgb);
                        res *= atten * 2.0;
                        res = half4(1,1,1,1) - res;

                        return LightingBlinnPhongEditor_PrePass( s, res );
                }
               
                struct Input {
                        float2 uv_MainTex;
                        float3 viewDir;
                };

                void vert (inout appdata_full v, out Input o) {
                UNITY_INITIALIZE_OUTPUT(Input,o);
                }
               

                void surf (Input IN, inout EditorSurfaceOutput o) {
                        o.Normal = float3(0.0,0.0,1.0);
                        o.Alpha = 1.0;
                        o.Albedo = 0.0;
                        o.Emission = 0.0;
                        o.Gloss = 0.0;
                        o.Specular = 0.0;
                        o.Custom = 0.0;
                       
                        float4 Tex2D0=tex2D(_MainTex,(IN.uv_MainTex.xyxy).xy);
                        float4 Fresnel0_1_NoInput = float4(0,0,1,1);
                        float4 Fresnel0=(1.0f - dot(normalize( float4( IN.viewDir.x, IN.viewDir.y,IN.viewDir.z,1.0f ).xyz), normalize( Fresnel0_1_NoInput.xyz ) )).xxxx;
                        float4 Invert0= float4(1.0f, 1.0f, 1.0f, 1.0f) - Fresnel0;
                        float4 Pow0=pow(Invert0,_EdgeDensity.xxxx);
                        float4 Master0_1_NoInput = float4(0,0,1,1);
                        float4 Master0_2_NoInput = float4(0,0,0,0);
                        float4 Master0_3_NoInput = float4(0,0,0,0);
                        float4 Master0_4_NoInput = float4(0,0,0,0);
                        float4 Master0_7_NoInput = float4(0,0,0,0);
                        float4 Master0_6_NoInput = float4(1,1,1,1);
                        o.Albedo = Tex2D0;
                        o.Alpha = Pow0;

                        o.Normal = normalize(o.Normal);
                }
                ENDCG
        }
        Fallback "Diffuse"
}
 

и он отлично работает на Unity3d v4!
Изображение
Там где темно - шейдер делает сферу ПРОЗРАЧНОЙ!


НО!!! Этот же шейдер на Unity3d v5 выдаёт вот такую хреномуть:
Изображение
Там где темно - сфера не прозрачная совсем!!!


Ночью звёзд не видно, а только какой-то странный тёмно-красный не прозрачный фон!
Как его сделать прозрачным?
Последний раз редактировалось Cyrix 02 дек 2018, 02:34, всего редактировалось 1 раз.
Cyrix
UNIт
 
Сообщения: 116
Зарегистрирован: 16 сен 2009, 11:32

Re: Работа c GPGPU (с шейдерами) в Unity3D

Сообщение Saltant 30 ноя 2018, 17:26

Спасибо, передёрнул затвор.
Я на Google Play _https://play.google.com/store/apps/developer?id=Saltant
Аватара пользователя
Saltant
Адепт
 
Сообщения: 2235
Зарегистрирован: 09 окт 2018, 16:40
Откуда: Химки
  • Сайт


Вернуться в Почемучка

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

Сейчас этот форум просматривают: Yandex [Bot] и гости: 29