2016-03-11 6 views
1

У меня есть следующий фрагмент кода в моей HLSL шейдер, который работает на Windows x64, но не запускается при развертывании на Android с помощью UE4:тип литья или массив индексации ошибка в HLSL (Unreal Engine 4)

// calcScale() returns a value between 0.0f and 7.0f, inclusive 
float Scale = calcScale(); 

const float3 Values[] = 
{ 
    { 0.0f, 0.0f, 0.0f }, 
    { 0.0f, 1.0f, 1.0f }, 
    { 0.0f, 0.0f, 1.0f }, 
    { 0.0f, 1.0f, 1.0f }, 
    { 1.0f, 1.0f, 0.0f }, 
    { 1.0f, 1.0f, 0.0f }, 
    { 1.0f, 0.0f, 1.0f }, 
    { 0.0f, 1.0f, 1.0f }, 
    { 1.0f, 1.0f, 1.0f } 
}; 

int index = int(Scale); 
OutDeviceColor = lerp(Values[index], Values[index + 1], Scale); 

Если я заменить последнюю строку с литералов, он работает:

OutDeviceColor = lerp(Values[0], Values[1], Scale); //works 

Я даже попытался установить:

int index = 0; // does not help 

I не получайте сообщений об ошибках в UE4Log. Я тоже попробовал беглый взгляд на logcat, но не нашел ничего подозрительного. Мой выход - это экран с нижней левой частью экрана, черный и зеленый, желтый и красный, интерполированные в верхней правой части экрана, что является тем, что я предполагаю, является признаком отсутствия шейдера во время выполнения.

+0

AFAIK вы можете использовать переменную с плавающей точкой 'Scale' непосредственно для доступа массива, без преобразования его в междунар. Вы пробовали это? Я просмотрел документацию HLSL, но, к сожалению, не нашел ссылки. Но я уверен, что в соответствии с прежней ссылкой DX9 HLSL был описан такой вариант. – Gnietschow

+0

Я думаю, что это было бы сильно зависящим от компилятора, если бы оно сработало. Чтобы быть в безопасности, было бы предпочтительнее использовать его для int или uint, прежде чем использовать его в качестве индекса. – shaveenk

ответ

0

Привет код путает: позволяет сказать, что масштаб дает 6,5, то ИНТ будет 6.

PS: литье в HLSL является:

int index = (int) Scale; 

Таким образом, вы получаете доступ элемент 6 и 7 , и lerp это с 6.5? Это действительно то, что вы хотите?

Может быть, вы хотите написать:

// calcScale() returns a value between 0.0f and 8.0f, inclusive 
float scale = calcScale(); 

const float3 Values[] = 
{ 
    { 0.0f, 0.0f, 0.0f }, 
    { 0.0f, 1.0f, 1.0f }, 
    { 0.0f, 0.0f, 1.0f }, 
    { 0.0f, 1.0f, 1.0f }, 
    { 1.0f, 1.0f, 0.0f }, 
    { 1.0f, 1.0f, 0.0f }, 
    { 1.0f, 0.0f, 1.0f }, 
    { 0.0f, 1.0f, 1.0f }, 
    { 1.0f, 1.0f, 1.0f } // YOU HAVE 9 ELEMENTS! Shouldn't scale be between 0-8??? 
}; 

int lowIndex = (int) floor(scale); 
int highIndex = (int) ceil(scale); 
float factor = frac(scale); //for 6.5 frac gives you 0.5 

OutDeviceColor = lerp(Values[lowIndex], Values[highIndex], factor); 

//or better all in one function 
OutDeviceColor = lerp(Values[floor(scale)], Values[ceil(scale)], frac(scale)); 

Одно дело сказать. Старайтесь избегать использования ints. HLSL может получить доступ к каждому массиву или вектору с поплавками. Графические устройства не очень хороши в работе с ints. Возможно, ваш компилятор оптимизирует это так или иначе, но вы этого не знаете точно.

Имейте в виду: все оптимизировано для использования поплавков.

Good Luck

+0

Ну, точка, которую я пыталась сделать, заключается в том, что код вообще не производит никакого вывода. Есть некоторые изменения в коде выше, как, например, lerp происходит для индекса Scale - (float) вместо Scale. В этом случае я не ищу помощи в логике. Я пытаюсь понять, почему компилятор вообще не принимает значение float. Опять же, это отлично работает в Windows. – shaveenk

+0

- это OutDeviceColor a float3? нормальный выходной цвет - float4, может быть, какая-то ошибка здесь? Вы уверены, что ваша функция масштаба находится в пределах диапазона? может быть, отрицательный? – kaiser