2015-03-09 2 views
0

Я пытаюсь реализовать обратный БПФ в вычислительном шейдере HLSL и не понимаю, как работает новая функция inversebits. Шейдер запускается под Unity3D, но это не должно иметь значения.Как работает функция обратных вызовов HLSL SM5?

Проблема заключается в том, что полученная текстура остается черной, за исключением крайнего левого или двух пикселей в каждой строке. Мне кажется, как будто функция reversebits не вернет правильные индексы.

Мой очень простой код выглядит следующим образом:

#pragma kernel BitReverseHorizontal 
 

 
Texture2D<float4> inTex; 
 
RWTexture2D<float4> outTex; 
 

 
uint2 getTextureThreadPosition(uint3 groupID, uint3 threadID) { 
 
\t uint2 pos; 
 
\t 
 
\t pos.x = (groupID.x * 16) + threadID.x; 
 
\t pos.y = (groupID.y * 16) + threadID.y; 
 
\t 
 
\t return pos; 
 
} 
 

 
[numthreads(16,16,1)] 
 
void BitReverseHorizontal (uint3 threadID : SV_GroupThreadID, uint3 groupID : SV_GroupID) 
 
{ 
 
    uint2 pos = getTextureThreadPosition(groupID, threadID); 
 
    uint xPos = reversebits(pos.x); 
 
    uint2 revPos = uint2(xPos, pos.y); 
 
    
 
    float4 values; 
 
    values.x = inTex[pos].x; 
 
    values.y = inTex[pos].y; 
 
    values.z = inTex[revPos].z; 
 
    values.w = 0.0f; 
 
    
 
    outTex[revPos] = values; 
 
}

Я играл с этим на некоторое время, и обнаружил, что если я заменить строку reversebits с этим один здесь:

uint xPos = reversebits(pos.x << 23); 

это работает. Хотя я понятия не имею, почему. Может быть, просто совпадение. Может кто-нибудь, пожалуйста, объясните мне, как я должен правильно использовать функцию reversebits?

+0

Не то, что он отвечает на ваш вопрос, но вы написали функцию, которая вычисляет SV_DispatchThreadID. –

ответ

0

Вы действительно хотите изменить бит?

х = 0: обратная: х = 0

х = 1: обратное: х = 2147483648

х = 2: обратная: х = 1073741824

и т.д ....

Если вы извлекаете тексели из текстуры, используя координаты, превышающие ширину текстуры, тогда вы будете черными. Если текстура не превышает> 1 млрд. Текселей (это не так), то вы хорошо заходите за границу.

0

Я делаю то же самое и приходил к одной и той же проблеме, и эти ответы на самом деле отвечали за нее, но я дам вам объяснение и целое решение.

Таким образом, решение с переменным буфером длиной в HLSL является:

uint reversedIndx; 
uint bits = 32 - log2(xLen); // sizeof(uint) - log2(numberOfIndices); 
for (uint j = 0; j < xLen; j ++) 
    reversedIndx = reversebits(j << bits); 

И что вы нашли/заметили по существу вытесняет все ведущие 0 Вашего индекс, так что вы просто реверсивные младшие или крайние правые биты вверх до тех пор, пока мы не достигнем максимальных бит.

, например:

int length = 8; 
int bits = 32 - 3; // because 1 << 3 is 0b1000 and we want the inverse like a mask 
int j = 6; 

и так как размер в Int, как правило, 32bits в двоичном J будет

j = 0b00000000000000000000000000000110; 

и обращенно было бы (AKA reversebits (J);)

j = 0b01100000000000000000000000000000; 

Какой была наша ошибка, поэтому J немного сдвинуты на бит будет

j = 0b11000000000000000000000000000000; 

, а затем отменено, и то, что мы хотим, чтобы бы

j = 0b00000000000000000000000000000011; 
Смежные вопросы