Упакуйте четыре байта в число с плавающей запятой - PullRequest
9 голосов
/ 27 января 2011

Я пишу шейдер (HLSL), и мне нужно упаковать значение цвета в формат R32.Я нашел различные фрагменты кода для упаковки поплавка в формат R8G8B8A8, но ни один из них, похоже, не работает в обратном порядке.Я нацеливаюсь на SM3.0, поэтому (afaik) битовые операции не подходят.

Подводя итог, я должен быть в состоянии сделать это:

float4 color = ...; // Where color ranges from 0 -> 1
float packedValue = pack(color);

Кто-нибудь знаеткак это сделать?

ОБНОВЛЕНИЕ
Я получил некоторый прогресс ... возможно, это поможет прояснить вопрос.
Мой временныйРешение таково:

const int PRECISION = 64;

float4 unpack(float value)
{   
    float4 color;

    color.a = value % PRECISION;
    value = floor(value / PRECISION);

    color.b = value % PRECISION;
    value = floor(value / PRECISION);

    color.g = value % PRECISION;
    value = floor(value / PRECISION);

    color.r = value;

    return color / (PRECISION - 1);
}

float pack(float4 color)
{   
    int4 iVal = floor(color * (PRECISION - 1));

    float output = 0;

    output += iVal.r * PRECISION * PRECISION * PRECISION;
    output += iVal.g * PRECISION * PRECISION;
    output += iVal.b * PRECISION;
    output += iVal.a;

    return output;
}

Я в основном ... притворяюсь, что использую целочисленные типы: s
Через догадки и проверки 64 было наибольшим числом, которое я мог использовать, сохраняя при этомДиапазон [0 ... 1].К сожалению, это также означает, что я теряю некоторую точность - 6 бит вместо 8.

Ответы [ 2 ]

1 голос
/ 05 февраля 2011

Сделайте так, как ваш пример кода для 3 компонентов, чтобы упаковать их в символ s =, и выполните exp2 (color.g) (1 + s), чтобы упаковать другой компонент в экспоненту. Вы все равно потеряете точность, но это не будет так плохо, как если бы вы попытались упаковать все в значимое, как вы это делаете.

К сожалению, нет способа избежать потери точности, поскольку существует множество значений с плавающей запятой NaN и Inf, которые не отличаются друг от друга и с которыми трудно работать (и, возможно, даже не поддерживаются вашим графическим процессором, в зависимости от того, сколько ему лет). есть).

1 голос
/ 29 января 2011

Посмотрите на: http://diaryofagraphicsprogrammer.blogspot.com/2009/10/bitmasks-packing-data-into-fp-render.html

Краткий ответ: невозможно сделать упаковку без потерь по 4 поплавка в 1 поплавок.

Даже если вы найдете способ упаковать 4 поплавка, сохраняя их экспоненту и значение, процесс упаковки и распаковки может быть слишком дорогим.

...