Войти
ПрограммированиеФорумГрафика

[hlsl] Найти 3 максимальных элемента в массиве на sm 3.0 (2 стр)

Страницы: 1 2
#15
(Правка: 4:35) 4:34, 12 июля 2018

Suslik
> как можно обойти проблему
Так?

uniform float4 values[32];
uniform int values_count;

float4 main(in float4 pos: POSITION) : COLOR
{
  float weights[3] = {0, 0, 0};
  [loop]
  for(int i = 0; i < values_count; i++)
  {
    float weight = SomeFunc(pos, values[i]);

    if (weight > weights[0]) weights[0] = weight;
    if (weights[0] > weights[1]) {
      float tmp = weights[1];
      weights[1] = weights[0];
      weights[0] = tmp;
    }
    if (weights[1] > weights[2]) {
      float tmp = weights[2];
      weights[2] = weights[1];
      weights[1] = tmp;
    }
  }

  //...дальше очень умный код с поиском 3 максимальных элементов в массиве weights[] - не нужен
}
#16
4:54, 12 июля 2018

MrShoor
да. я думал об этом, но боялся написать. спасибо, попробуем.

#17
(Правка: 5:25) 5:14, 12 июля 2018
int count;
float array[ 16 ];

float4 f_test() : COLOR0 {
  float a = 0;
  for( int i = 0; i < count; ++i )
  {
    a += array[ i ];
  }
  return float4( a, 0, 0, 1 );
}
+ fxc /T ps_3_0 /E f_test /Cc flow.hlsl

Лол. Однако, поддержал. :V
#18
5:24, 12 июля 2018

Приделал присваивание в массив, и тоже получил

warning X3550: array reference cannot be used as an l-value; not natively addressable, forcing loop to unroll

Судя по всему, проблема заключается в том, что sm3.0 не умеет в индирекцию. Соответственно, чтобы скомпилировать присваивание в массив, надо вычислить целевой регистр заранее, а для этого нужно развернуть цикл и проставить константы, а у Суслика цикл неразворотливый, вот и неудача.
Что-то мне кажется, что даже в случае успешной компиляции, шейдер всё равно будет непозволительно тормозным.

#19
(Правка: 5:35) 5:28, 12 июля 2018

Delfigamer
> Лол. Однако, поддержал. :V
Проблема не во flow control, а в том, что на ps_3_0 нет нативной адресации массивов. То есть нельзя взять array[ i ] по индексу.
Попробуй скомпилирвать такой код:

int count;

sampler2D s;

float4 main() : COLOR0 {
  float a = 0;
  for( int i = 0; i < count; ++i )
  {
    a += tex2D(s, float2(i,i)/16.0).x;
  }
  return float4( a, 0, 0, 1 );
}
#20
(Правка: 6:16) 6:16, 12 июля 2018

Suslik
На sm3.0 индексный регистр есть только в вершинных шейдерах. В пиксельных он отсутствует. Жги текстуру.

#21
(Правка: 7:33) 7:28, 12 июля 2018

MrShoor
> Проблема не во flow control, а в том, что на ps_3_0 нет нативной адресации
> массивов. То есть нельзя взять array[ i ] по индексу.
Я и говорю - цикл поддержал, а вот с индирекцией не справился, и в итоге скомпилировал дикий лол:

    float test0 = 0;
    float test1 = 1;
    float test2 = 2;
    <...>
    float test15 = 15;

    for( int i = 0; i < count; ++i )
    {
        test0 -= 1;
        test1 -= 1;
        <...>
        test15 -= 1;

        float value;

        value = ( abs( test0 ) > 0 ) ? array[ 0 ] : 0;
        value = ( abs( test1 ) > 0 ) ? array[ 1 ] : value;
        <...>
        value = ( abs( test15 ) > 0 ) ? array[ 15 ] : value;

        a += value;
    }
#22
8:32, 12 июля 2018

Delfigamer
> Я и говорю - цикл поддержал, а вот с индирекцией не справился, и в итоге
> скомпилировал дикий лол:
Не знаю что такое индирекция, но ты говорил:

Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры разворачиваются в одну длинную линию и замазываются условными присваиваниями.

и
и аналогично с циклами.
А если развернуть без переходов не получается - то компиляция проваливается, на что ты и попал.

Что как бы совсем не так. Цикл не получилось сделать динамическим, потому что нету array[], а есть array0, array1 и так далее. Поэтому твоя аналогия не верна. Представь, что у тебя есть:
int count;
float array0;
float array1;
float array2;
<...>
float array15;

float4 f_test() : COLOR0 {
   //а теперь тут ты можешь написать любой код, хоть с циклом, хоть без
   //понятное дело, что поскольку у тебя теперь нет array[]
   //то и цикл по нему ты написать не можешь, если компилятор не сможет его развернуть
}
#23
9:16, 12 июля 2018

MrShoor #15
сделал примерно так, работает. производительность устраивает. спасибо.

#24
9:20, 12 июля 2018

Suslik
пожалуйста ;)

#25
9:48, 12 июля 2018

Пока писал, MrShoor опередил.

+ Сделал вот такой пиксельный шейдер:

Текстура 1D шириной 32, это как бы массив. После выполнения в r4 находится индекс (в виде текстурной координаты) самого яркого по R пикселя.

#26
(Правка: 9:58) 9:52, 12 июля 2018

MrShoor
> Не знаю что такое индирекция, но ты говорил:
Ты оспорил. Я решил проверить и обнаружил, что да, ты прав,
> Однако, поддержал.
Но при этом вместо доступа по динамическому адресу получился
> Лол. :V
Что я и показал вольным переводом с ассемблера обратно на человеческий в #21.

#27
9:57, 12 июля 2018

Mikle
> Текстура 1D шириной 32,

помню, году в 2007 увидел в крайтековском коде такое ...

#28
10:03, 12 июля 2018

Delfigamer
> Ты оспорил. Я решил проверить и обнаружил, что да, ты прав,
А, ну ок. Я просто подумал, что ты этот лол приводишь как пруф того, что на sm3.0 нету динамического бранчинга.

#29
10:26, 12 июля 2018

Suslik

зачем Path of exile DX9 ?

Страницы: 1 2
ПрограммированиеФорумГрафика