Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / [hlsl] Найти 3 максимальных элемента в массиве на sm 3.0 (2 стр)

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

Страницы: 1 2
MrShoorУчастникwww12 июля 20184:34#15
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[] - не нужен
}

Правка: 12 июля 2018 4:35

SuslikМодераторwww12 июля 20184:54#16
MrShoor
да. я думал об этом, но боялся написать. спасибо, попробуем.
DelfigamerПостоялецwww12 июля 20185:14#17
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

Правка: 12 июля 2018 5:25

DelfigamerПостоялецwww12 июля 20185:24#18
Приделал присваивание в массив, и тоже получил
warning X3550: array reference cannot be used as an l-value; not natively addressable, forcing loop to unroll

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

MrShoorУчастникwww12 июля 20185:28#19
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 );
}

Правка: 12 июля 2018 5:35

WraithПостоялецwww12 июля 20186:16#20
Suslik
На sm3.0 индексный регистр есть только в вершинных шейдерах. В пиксельных он отсутствует. Жги текстуру.

Правка: 12 июля 2018 6:16

DelfigamerПостоялецwww12 июля 20187:28#21
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;
    }

Правка: 12 июля 2018 7:33

MrShoorУчастникwww12 июля 20188:32#22
Delfigamer
> Я и говорю - цикл поддержал, а вот с индирекцией не справился, и в итоге
> скомпилировал дикий лол:
Не знаю что такое индирекция, но ты говорил:
Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры разворачиваются в одну длинную линию и замазываются условными присваиваниями.

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

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

float4 f_test() : COLOR0 {
   //а теперь тут ты можешь написать любой код, хоть с циклом, хоть без
   //понятное дело, что поскольку у тебя теперь нет array[]
   //то и цикл по нему ты написать не можешь, если компилятор не сможет его развернуть
}
SuslikМодераторwww12 июля 20189:16#23
MrShoor #15
сделал примерно так, работает. производительность устраивает. спасибо.
MrShoorУчастникwww12 июля 20189:20#24
Suslik
пожалуйста ;)
MikleМодераторwww12 июля 20189:48#25
Пока писал, MrShoor опередил.
+ Сделал вот такой пиксельный шейдер:

Текстура 1D шириной 32, это как бы массив. После выполнения в r4 находится индекс (в виде текстурной координаты) самого яркого по R пикселя.
DelfigamerПостоялецwww12 июля 20189:52#26
MrShoor
> Не знаю что такое индирекция, но ты говорил:
Ты оспорил. Я решил проверить и обнаружил, что да, ты прав,
> Однако, поддержал.
Но при этом вместо доступа по динамическому адресу получился
> Лол. :V
Что я и показал вольным переводом с ассемблера обратно на человеческий в #21.

Правка: 12 июля 2018 9:58

innuendoПостоялецwww12 июля 20189:57#27
Mikle
> Текстура 1D шириной 32,

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

MrShoorУчастникwww12 июля 201810:03#28
Delfigamer
> Ты оспорил. Я решил проверить и обнаружил, что да, ты прав,
А, ну ок. Я просто подумал, что ты этот лол приводишь как пруф того, что на sm3.0 нету динамического бранчинга.
innuendoПостоялецwww12 июля 201810:26#29
Suslik

зачем Path of exile DX9 ?

Страницы: 1 2

/ Форум / Программирование игр / Графика

2001—2018 © GameDev.ru — Разработка игр