Двумерный массив float в surface шейдере

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

Двумерный массив float в surface шейдере

Сообщение Diab10 31 авг 2016, 09:56

Всем привет! В фрагментном шейдере массив нормально объявляется, а в surfece юнити пишет ошибку:
Shader error in 'Custom/NewSurfaceShader': Syntax error at line 30 (on )


Вот строка, которая барахлит:
Синтаксис:
Используется csharp
float textur[5][5] = {{0.99f, 0.81f, 0.48f, 0.75f, 0.95f}, {0.82f, 0.65f, 0.25f, 0.47f, 0.78f}, {0.53f, 0.35f, 0.00f, 0.28f, 0.60f}, {0.88f, 0.65f, 0.22f, 0.56f, 0.73f}, {0.97f, 0.71f, 0.50f, 0.85f, 0.92f}};


Если делаю одномерный массив, то всё нормально:
Синтаксис:
Используется csharp
float textur[5] = {0.99f, 0.81f, 0.48f, 0.75f, 0.95f};


Вот код surface шейдера, он выдаёт ошибку:

Синтаксис:
Используется csharp
Shader "Custom/NewSurfaceShader" {
        Properties {
                _Color ("Color", Color) = (1,1,1,1)
                _MainTex ("Albedo (RGB)", 2D) = "white" {}
                _Glossiness ("Smoothness", Range(0,1)) = 0.5
                _Metallic ("Metallic", Range(0,1)) = 0.0
        }
        SubShader {
                Tags { "RenderType"="Opaque" }
                LOD 200
               
                CGPROGRAM
                // Physically based Standard lighting model, and enable shadows on all light types
                #pragma surface surf Standard fullforwardshadows

                // Use shader model 3.0 target, to get nicer looking lighting
                #pragma target 3.0

                sampler2D _MainTex;

                struct Input {
                        float2 uv_MainTex;
                };

                half _Glossiness;
                half _Metallic;
                fixed4 _Color;

                void surf (Input IN, inout SurfaceOutputStandard o) {
            float textur[5][5] = {{0.99f, 0.81f, 0.48f, 0.75f, 0.95f}, {0.82f, 0.65f, 0.25f, 0.47f, 0.78f}, {0.53f, 0.35f, 0.00f, 0.28f, 0.60f}, {0.88f, 0.65f, 0.22f, 0.56f, 0.73f}, {0.97f, 0.71f, 0.50f, 0.85f, 0.92f}};

                        // Albedo comes from a texture tinted by color
                        fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
                        o.Albedo = c.rgb;
                        // Metallic and smoothness come from slider variables
                        o.Metallic = _Metallic;
                        o.Smoothness = _Glossiness;
                        o.Alpha = c.a;
                }
                ENDCG
        }
        FallBack "Diffuse"
}
 


А вот с фрагментным, всё работает:
Синтаксис:
Используется csharp
Shader "Unlit/NewUnlitShader"
{
        Properties
        {
                _MainTex ("Texture", 2D) = "white" {}
        }
        SubShader
        {
                Tags { "RenderType"="Opaque" }
                LOD 100

                Pass
                {
                        CGPROGRAM
                        #pragma vertex vert
                        #pragma fragment frag
                        // make fog work
                        #pragma multi_compile_fog
                       
                        #include "UnityCG.cginc"

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

                        struct v2f
                        {
                                float2 uv : TEXCOORD0;
                                UNITY_FOG_COORDS(1)
                                float4 vertex : SV_POSITION;
                        };

                        sampler2D _MainTex;
                        float4 _MainTex_ST;
                       
                        v2f vert (appdata v)
                        {
                                v2f o;
                                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                                UNITY_TRANSFER_FOG(o,o.vertex);
                                return o;
                        }
                       
                        fixed4 frag (v2f i) : SV_Target
                        {float textur[5][5] = {{0.99f, 0.81f, 0.48f, 0.75f, 0.95f}, {0.82f, 0.65f, 0.25f, 0.47f, 0.78f}, {0.53f, 0.35f, 0.00f, 0.28f, 0.60f}, {0.88f, 0.65f, 0.22f, 0.56f, 0.73f}, {0.97f, 0.71f, 0.50f, 0.85f, 0.92f}};

                                // sample the texture
                                fixed4 col = tex2D(_MainTex, i.uv);
                                // apply fog
                                UNITY_APPLY_FOG(i.fogCoord, col);                              
                                return col;
                        }
                        ENDCG
                }
        }
}
 


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

Re: Двумерный массив float в surface шейдере

Сообщение jetyb 31 авг 2016, 19:56

Скорее всего из-за разных платформ и компиляторов (например dx11 поддерживает буферы, но не поддерживает безразмерные массивы, а dx9 наоборот):
surface - шейдер ведь расписывается в несколько автосгенеренных проходов. Вот в них что-то интересное и прописано. Попробуйте получившеся автосгенеренные проходы попотрошить.

А вообще код очень странный. Декларация массива и меня озадачила.
И зачем нужен двумерный массив в шейдере, тем более объявляющийся в коде функции?
jetyb
Адепт
 
Сообщения: 1368
Зарегистрирован: 31 окт 2011, 17:21

Re: Двумерный массив float в surface шейдере

Сообщение Diab10 01 сен 2016, 07:55

jetyb писал(а):Скорее всего из-за разных платформ и компиляторов (например dx11 поддерживает буферы, но не поддерживает безразмерные массивы, а dx9 наоборот):
surface - шейдер ведь расписывается в несколько автосгенеренных проходов. Вот в них что-то интересное и прописано. Попробуйте получившеся автосгенеренные проходы попотрошить.

А вообще код очень странный. Декларация массива и меня озадачила.
И зачем нужен двумерный массив в шейдере, тем более объявляющийся в коде функции?


Экономлю текстуры. Вместо текстуры-маски занёс нужные значения в массив. Глупо? :)
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3399
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023

Re: Двумерный массив float в surface шейдере

Сообщение jetyb 01 сен 2016, 09:15

Любой двумерный массив можно и нужно заменить одномерным массивом. Любой ступенчатый массив массивов можно заменить 2 массивами. Юзайте простые массивы, они быстрее и к устройству ближе.
Новое API 5.4 кстати позволяет передавать массивы чисел, векторов и матриц в шейдер.
jetyb
Адепт
 
Сообщения: 1368
Зарегистрирован: 31 окт 2011, 17:21

Re: Двумерный массив float в surface шейдере

Сообщение Diab10 04 сен 2016, 19:37

jetyb писал(а):Любой двумерный массив можно и нужно заменить одномерным массивом. Любой ступенчатый массив массивов можно заменить 2 массивами. Юзайте простые массивы, они быстрее и к устройству ближе.
Новое API 5.4 кстати позволяет передавать массивы чисел, векторов и матриц в шейдер.


Спасибо, так и сделал, полёт нормальный)
Аватара пользователя
Diab10
Адепт
 
Сообщения: 3399
Зарегистрирован: 17 мар 2011, 20:42
Откуда: 123 RUS
Skype: diab1023

Re: Двумерный массив float в surface шейдере

Сообщение jetyb 15 сен 2016, 11:50

Случайно наткнулся. Юнити компилирует surface шейдер другим компилятором CG:
https://docs.unity3d.com/Manual/SL-ShadingLanguage.html
Если в surface шейдере написать вот так
Синтаксис:
Используется csharp
#ifndef UNITY_COMPILER_CG              
        float textur[5][5] = { { 0.99f, 0.81f, 0.48f, 0.75f, 0.95f },{ 0.82f, 0.65f, 0.25f, 0.47f, 0.78f },{ 0.53f, 0.35f, 0.00f, 0.28f, 0.60f },{ 0.88f, 0.65f, 0.22f, 0.56f, 0.73f },{ 0.97f, 0.71f, 0.50f, 0.85f, 0.92f } };
#endif
 

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


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

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

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