Найти угол в шейдере

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

Найти угол в шейдере

Сообщение Diab10 06 мар 2016, 11:31

Всем привет!
Пытаюсь написать шейдер, и мне нужно получить угол(от 0 до 360) вокруг оси Y.
Вот что я получил, но таким способом можно получить только угол от 0 до 180 и всегда положительный.

Синтаксис:
Используется csharp
float3 dir = normalize(_WorldSpaceCameraPos.xyz - v.vertex.xyz);
float _float = (atan(dir.x/dir.z)*180.0)/3.1415+90.0;
 

Шейдер этот будет висеть на многих больших объектах, поэтому нужна хорошая оптимизация.

Есть способ получить угол от 0 до 360 без использования if/else(слышал, что нужно избегать их в шейдерах)?
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3401
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023

Re: Найти угол в шейдере

Сообщение waruiyume 06 мар 2016, 11:57

При использовании "if", есть вероятность, что выполнятся даже те ветки, для которых условия были ложными (на результат это не влияет, а просто тратит ресурсы). По крайней мере, так было во вторых шейдерах, не могу гарантировать, но вроде, помимо настоящих циклов, в третьи шейдеры, за везли ещё и настоящие бранчи.
Если не использовать в "if" конструкции километровой длинны, а что-то в духе "Если А то В+=1", особой погоды это не сделает(если открыть инклуды из сорсов встроенных шейдеров, то там можно найти их, вагон и маленькую тележку).

угол(от 0 до 360)

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

Re: Найти угол в шейдере

Сообщение Diab10 06 мар 2016, 12:57

waruiyume писал(а):При использовании "if", есть вероятность, что выполнятся даже те ветки, для которых условия были ложными (на результат это не влияет, а просто тратит ресурсы). По крайней мере, так было во вторых шейдерах, не могу гарантировать, но вроде, помимо настоящих циклов, в третьи шейдеры, за везли ещё и настоящие бранчи.
Если не использовать в "if" конструкции километровой длинны, а что-то в духе "Если А то В+=1", особой погоды это не сделает(если открыть инклуды из сорсов встроенных шейдеров, то там можно найти их, вагон и маленькую тележку).


Т.е. в данном случае делать через if и не париться?

waruiyume писал(а):
угол(от 0 до 360)

Если не секрет, зачем?


Делаю биллбоард. На текстуре 9 снимков объекта, нужно выбрать нужный в зависимости с какой стороны от объекта находится камера
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3401
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023

Re: Найти угол в шейдере

Сообщение jetyb 06 мар 2016, 23:16

jetyb
Адепт
 
Сообщения: 1486
Зарегистрирован: 31 окт 2011, 17:21

Re: Найти угол в шейдере

Сообщение Diab10 07 мар 2016, 09:58

jetyb писал(а):http://http.developer.nvidia.com/Cg/atan2.html


Спасибо! То что нужно :ymparty:

Ещё подскажите, как шейдеры можно дебажить?
Сейчас делаю всё в C# с выводом в инспектор результатов, а потом переношу в шейдер. Но сейчас столкнулся с тем, что результаты отличаются, и я не понимаю почему
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3401
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023

Re: Найти угол в шейдере

Сообщение seaman 07 мар 2016, 13:59

seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Найти угол в шейдере

Сообщение Diab10 07 мар 2016, 19:06

seaman писал(а):https://docs.unity3d.com/ru/current/Manual/SL-DebuggingD3D11ShadersWithVS.html


Спасибо. Жаль, что у меня комп не поддерживает 11 DX :(
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3401
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023

Re: Найти угол в шейдере

Сообщение artk 11 мар 2016, 18:50

зачем вам угол, да еще и не в радианах?
У вас же все равно билдорд, значит у вас уже есть матрица. Из этой матрицы вы можете взять готовые синусы и косинусы
Аватара пользователя
artk
Старожил
 
Сообщения: 749
Зарегистрирован: 22 май 2011, 12:22

Re: Найти угол в шейдере

Сообщение Diab10 11 мар 2016, 21:13

artk писал(а):зачем вам угол, да еще и не в радианах?
У вас же все равно билдорд, значит у вас уже есть матрица. Из этой матрицы вы можете взять готовые синусы и косинусы


Знал бы ещё я как это сделать :)
У меня биллбоард "разворачивается" из 4 точек, которые расположены в 1 точке. Делал на основе шейдера Neyl'a : viewtopic.php?f=35&t=24903

Вообще, я сделал через atan2, работает, но если подскажите как сделать производительнее, то буду благодарен :)
Суть в том, что в текстуре у меня 9 снимков - сеткой 3 на 3, и нужно выбирать нужный в зависимости от стороны взгляда на объект, по оси Y

Вот что получилось:
Синтаксис:
Используется csharp
Shader "Custom/Tree Billboard"
{
        Properties
        {
            _Color ("Tint Color", Color) = (1,1,1,1)
            _MainTex ("Texture", 2D) = "white" { }
        }
         
         
        SubShader
        {
            Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="Opaque"}
            Pass
            {
                        AlphaTest Greater 0.25
                         
                        CGPROGRAM
                                #pragma vertex vert
                                #pragma fragment frag
                                 
                                #include "UnityCG.cginc"
                                 
                                float4 _Color;
                                sampler2D _MainTex;
                                fixed4 _LightColor0;
                                 
                                struct appdata
                                {
                                    float4 vertex : POSITION;
                                    float4 texcoord : TEXCOORD0;//texture - uv1
                                    float4 texcoord1 : TEXCOORD1;//billboard offset - uv2
                                    float4 color : COLOR;
                                };
                                 
                                struct v2f
                                {
                                    float4  pos : SV_POSITION;
                                    float2  uv : TEXCOORD0;
                                    float4 color : COLOR;
                                        float4 lightDirection : TEXCOORD1;
                                };
                                 
                                v2f vert (appdata v)
                                {
                                    v2f o;
                                   
                                    float3 eyeVector = ObjSpaceViewDir( v.vertex );
                                   
                                    float3 upVector = float3(0,1,0);
                                    float3 sideVector = normalize(cross(eyeVector,upVector));
                                 
                                    float3 finalposition = v.vertex.xyz;
                                    finalposition += (v.texcoord1.x) * sideVector;
                                    finalposition += (v.texcoord1.y) * upVector;
                                   
                                    float4 pos = float4(finalposition, 1);
                                               
                                    o.pos = mul( UNITY_MATRIX_MVP, pos );
                                 
                                    o.uv = v.texcoord.xy;
                                    o.color = v.color;
                                    o.color.a = 1;
                                       
                                       
                                        float3 dir = normalize(_WorldSpaceCameraPos.xyz - v.vertex.xyz);
                                        if(dir.z==0)
                                                dir.z=0.01;
                                        float _float = (atan2(dir.x,dir.z)*180.0)/3.1415+180.0;
                                       
                                               
                                        float _intY = 3.0-floor(_float/120.0);
                                        float _intX = floor((_float - 120.0*_intY)/40.0);
                                       
                                        o.uv.x += _intX * 1.0/3.0;
                                        o.uv.y += _intY * 1.0/3.0;
                                       
                                        float4 lightDir=_WorldSpaceLightPos0;
                                        o.lightDirection.xyz = normalize( mul(UNITY_MATRIX_VP,lightDir).xyz );
                                 
                                    return o;
                                }
                                 
                                half4 frag (v2f i) : COLOR
                                {
                                        fixed4 c = tex2D(_MainTex, i.uv) *  _Color;
                                        if(c.a<.4)
                                                discard;
                                       
                                        float att= (normalize(-i.lightDirection.xyz)+1)/2 ;
                                       
                                        c.rgb=float3(UNITY_LIGHTMODEL_AMBIENT.rgb)*c.rgb+c.rgb*att*_LightColor0.rgb;
                                       
                                    return c;
                                }
                        ENDCG
                }
        }
         
         
        Fallback "VertexLit"
}
 
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3401
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023


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

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

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