Долгий импорт шейдера в Unity и магия чисел

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

Долгий импорт шейдера в Unity и магия чисел

Сообщение maewyn 21 май 2015, 02:01

Здравствуйте, появилась небольшая проблема. После сохранения кода шейдера в Monodevelop или VS я перехожу в окно Unity, в котором происходит загрузка новых, обновленных данных. Обычно по времени это занимало секунды, но теперь после каждого сохранения импорт растягивается на несколько минут. При добавлении всего одной строчки #pragma target 3.0 вообще эта операция длится бесконечно. А при завершении процесса Unity после нового запуска выдается предупреждение : Automatic import for '...Painter.shader' was disabled because the asset importer crashed on it last time.
Сам шейдер при запуске нисколько не тормозит. В чем может быть проблема, в количестве операторов или чем-то еще?

Еще есть один вопрос. Написал код, в котором есть переменная float direction. Она используется для рассчета смещение uv для каждой вершины. Если direction задается в шейдере числом, то все корректно работает при любых значениях. Но мне эту переменную нужно вытащить из данных вершины (а именно tangent). Нужное значение хранится в дробной части числа.

Синтаксис:
Используется csharp
float n = IN.tangent.x;        
float direction = floor((n - floor(n)) * 10);  
 


Скрытый текст:
Хотел это сделать функцией frac(n), но нее вообще выдается ошибка Emty string. Так должно быть !?


И вот при такой записи результатом выполнения кода становится розовый цвет текстуры, как-будто произошла ошибка. Может быть в direction в итоге null записывается? Более того, если уйти от всех вычислений и проверить результат таким образом

Синтаксис:
Используется csharp
float n = IN.tangent.x;
float direction = floor((n - floor(n)) * 10);

if (direction > 1)
o.Albedo = fixed4(0.0,0.0,0.0,1.0);
else
o.Albedo = fixed4(1.0,1.0,1.0,1.0);

 


то результат выдается правильный, судя по полученному цвету. Это значит, что в IN.tangent.x данные записаны, и именно те, которые планировалось записать((

Скрытый текст:
Конечно, я бы не стал писать сюда и продолжил бы искать ошибки сам, если бы уже ранее не сталкивался с нюансами связанными с шейдерами в Unity. Допустим, при сохранении переменной таким образом float x = tangent[3] ее нельзя использовать в качестве индекса tangent[x] и т. д.


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

Скрытый текст:
Shader "Custom/Painter"
{
Properties
{
_Atlas ("Base (RGB)", 2D) = "white" {}
_AtlasCount("Atlas count", Range (1, 10)) = 4

//размеры гекса
_HexSizeX("Hex Size X", Range (1, 100)) = 0
_HexSizeY("Hex Size Y", Range (1, 100)) = 0

_HexRadius("Hex Radius", Range (1, 100)) = 20


//размер стороны маски
_MaskSide("Mask side", Range (1, 100)) = 0
}

SubShader
{
Tags { "RenderType"="Opaque" }
//LOD 200

CGPROGRAM
#pragma target 3.0
#pragma surface surf Lambert vertex:vert
#include "UnityCG.cginc"

sampler2D _Atlas;
float _AtlasCount;

float _HexSizeX;
float _HexSizeY;

float _HexRadius;

float _MaskSide;

struct Input
{
float2 uv_Atlas;
float3 worldPos;

float4 tangent;

};

float2 getCoords(float n, float2 localPos)
{
//номер типа местности в атласе
float landType = floor(n);
float direction = floor((n - landType) * 10);

//позиция в атласе
int y_InAtlas = int(landType / _AtlasCount);
int x_InAtlas = landType - (y_InAtlas * _AtlasCount) - 1;

//координаты в атласе
float x_Coords = x_InAtlas / _AtlasCount;
float y_Coords = y_InAtlas / _AtlasCount;

//смещение центра этого гекса относительно главного в мировых координатах
float2 offset = float2(_HexRadius * rsqrt(3) / (float) 2, _HexRadius + (_HexRadius / (float) 2));

//для direction = 3 и 6 - offset.x *= 2, offset.y = 0;
float m = sign(fmod(direction, 3));

offset.y *= m;
offset.x *= ((m * -1) + 2);

//вычисление заков в зависимости от направления
float sign_x = (direction * 2) - 9;
sign_x = sign(sign_x) * -1;

float sign_y = fmod(direction + 3, 5) - 1;
sign_y = sign(sign_y) * -1;

offset.x *= sign_x;
offset.y *= sign_y;

//переводим в локальные коордианаты смещение
offset = offset / _MaskSide;

//для direction = 0 обнуляем offset
offset *= sign(direction - 1);


localPos = localPos - offset;
localPos = float2((localPos.x / 4) + x_Coords, (localPos.y / 4) + y_Coords);

return localPos;

}


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

o.tangent = v.tangent;
}

void surf (Input IN, inout SurfaceOutput o)
{

float2 localPos = IN.uv_Atlas;

float2 uv1 = getCoords(IN.tangent.x, localPos);

o.Albedo = tex2D(_Atlas, uv1).rgb;// * fixed4(1.0,0.0,0.0,1.0);

}

ENDCG
}
}
Последний раз редактировалось maewyn 21 май 2015, 13:39, всего редактировалось 2 раз(а).
maewyn
UNITрон
 
Сообщения: 159
Зарегистрирован: 06 сен 2013, 23:06

Re: Долгий импорт шейдера в Unity и магия чисел

Сообщение MF_Andreich 21 май 2015, 08:23

При компиляции шейдеров все циклы и ифы могут пытаться развернуться и выполнится, для гарантии исполнения кода за определенное количество итераций. Подозреваю, что у вас есть цикл с условием, которое не может отресолвится правильно. Ограничивайте итерации сверху строго захардкоденным числом.
По дирекшнам вашим... надо код шейдера смотреть.
Holly Shovel Team
Аватара пользователя
MF_Andreich
Старожил
 
Сообщения: 924
Зарегистрирован: 20 июн 2013, 10:09
Откуда: Барнаул
Skype: mf_andreich
  • ICQ

Re: Долгий импорт шейдера в Unity и магия чисел

Сообщение nipercop 21 май 2015, 08:51

Здрасте!
Ну у меня вроде чтото работает, компилится за пол секунды. с target 3.0 все норм.
Просто вначале ругался после вставки. У Вас функция getCoords принимает 2 параметра, а вы обращаетесь к ней с 3мя. Ну это так, к слову.
Так что на там счет дирекшиона?
Аватара пользователя
nipercop
UNец
 
Сообщения: 3
Зарегистрирован: 14 янв 2013, 05:12

Re: Долгий импорт шейдера в Unity и магия чисел

Сообщение maewyn 21 май 2015, 11:28

Насчет параметров - это опечатка уже входе вставки кода на форум, поправил)
Спасибо, буду пробовать if'ы обойти. Насчет direction'а все не так однозначно)))))
maewyn
UNITрон
 
Сообщения: 159
Зарегистрирован: 06 сен 2013, 23:06

Re: Долгий импорт шейдера в Unity и магия чисел

Сообщение maewyn 21 май 2015, 13:46

Добавил #pragma target 3.0, убрал все if'ы, исправил использование direction. Теперь текстура отображается корректно. Обновленный код шейдера в первом посте. Все работает, но при добавление строчек с какой-нибудь переменной опять очень долгий импорт. Если просто константу добавляю, то импорт в пару секунд. В чем может быть проблема?
А нельзя ли как-нибудь отключить эту процедуру, до того момента, как я напишу шейдер окончательно? Ведь ошибки, после сохранения, показываются в консоле за секунды (что мне и нужно), но если ошибок нет, он очень долго соображает((
maewyn
UNITрон
 
Сообщения: 159
Зарегистрирован: 06 сен 2013, 23:06

Re: Долгий импорт шейдера в Unity и магия чисел

Сообщение maewyn 22 май 2015, 00:56

Проблема решилась установкой последней версии Unity
maewyn
UNITрон
 
Сообщения: 159
Зарегистрирован: 06 сен 2013, 23:06


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

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

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