Ошибка в просчете палитры?
|
|
moroz1999 | Дата: Воскресенье, 2009-08-02, 13:55:11 | Сообщение # 1 |
Юзер
Группа: Человеки
Сообщений: 2
Статус: Offline
| В общем, если я не ошибаюсь, то в процедуре расчета палитры закралась ошибка. При расчете палитры результат делится не на 255, а на 256, из-за чего реальные RGB цвета высчитываются с небольшой погрешностью. Экспериментальным путём подтвердил, что, например, при выставленной в настройках палитре от pulsar, ярко-красный цвет получается #FE0000 вместо #FF0000. Вот формула из конфига: ; Rnn - matrix for post-processing: ; real_Red = (Red*R11 + Green*R12 + Blue*R13) / 0x100 ; real_Green = (Red*R21 + Green*R22 + Blue*R23) / 0x100 ; real_Blue = (Red*R31 + Green*R32 + Blue*R33) / 0x100 Вот палитра от Pulsar: pulsar=00,76,CD,E9,FF,9F:FF,00,00;00,FF,00;00,00,FF По формуле для ярко-красного выходит следующее: real_Red = (0xFF*0xFF + 0*0 + 0*0) / 0x100 = 0xFE И это более чем логично - деля 0xFF*0xFF на 0x100, мы никогда не получим 0xFF. Следовательно, в формуле - логическая ошибка и 0x100 должно быть поменяно на 0xFF. Я никогда не писал на C++, поэтому проверить свои измышления не смогу, но, руководствуясь своей интуицией, могу сказать, что изменения надо вносить в draw.cpp, линии 220, 221, 222. Исходники брал us0.37.3-src.rar
|
|
| |
deathsoft | Дата: Понедельник, 2009-08-03, 00:38:05 | Сообщение # 2 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 1587
Статус: Offline
| Ошибки там никаокй нету, это обычное математическое нормирование, делится на размер диапазона 0-255 (всего целых чисел там 256). А FF там не получить из за погрешности расчета в 8битной арифметике, более того - там еще и переполнение возможно, когда все коэффициенты FF. От этого никуда не дется, либо надо считать не целочисленно и не в 8бит. Коэффициент 255 в матрице не соответствует единице, для единицы в матрице должно быть 256. [Ro] [R11 R12 R13] [Ri] [Go]=[R21 R22 R23]*[Gi] [Bo] [R31 R32 R33] [Bi] В случае преоразования 1 в 1 матрица должна состоять из чисел [0x100 0 0] I=[0 0x100 0] [0 0 0x100] 8-битный цап никогда не дает единицу на выходе, он дает значения от 0 до 255/256 P.S. Тут еще и арифметику с насыщением надо использовать, если результат превышает 255, то нужно брать 255.
Сообщение отредактировал deathsoft - Понедельник, 2009-08-03, 12:37:39 |
|
| |
lvd | Дата: Понедельник, 2009-08-03, 15:02:11 | Сообщение # 3 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 2528
Статус: Offline
| А что мешает считать единицей 0xFF, кроме предрассудков?
Многого нет здесь: http://lvd.nedopc.com
|
|
| |
deathsoft | Дата: Понедельник, 2009-08-03, 16:14:27 | Сообщение # 4 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 1587
Статус: Offline
| Quote (lvd) А что мешает считать единицей 0xFF, кроме предрассудков? Тогда нуля не будет и будет неточно, надо просто в матрицу записывать коэффициенты 0..256 и все, а в унриале исправить расчет, чтобы внутринние вычисления были int а на байт, и будет все как надо, т.е. результирующий цвет будет 0..255. Еще сделать проверку на насыщение (не знаю сделано ли сейчас). P.S. Ну и все палитры в ини файле надо будет поправить, чтобы где 1 было 0x100.
Сообщение отредактировал deathsoft - Понедельник, 2009-08-03, 16:16:30 |
|
| |
lvd | Дата: Понедельник, 2009-08-03, 20:22:41 | Сообщение # 5 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 2528
Статус: Offline
| Quote (deathsoft) Тогда нуля не будет и будет неточно, Ты шо, тормоз? 0 это ноль 255 это 1 ff*ff/ff === ff Quote (deathsoft) надо просто в матрицу записывать коэффициенты 0..256 и все, а в унриале исправить расчет, чтобы внутринние вычисления были int а на байт, и будет все как надо, т.е. результирующий цвет будет 0..255. Еще сделать проверку на насыщение (не знаю сделано ли сейчас). Ну или так сделай, но 1 хуй получишь ты 0x100, и куды ты будешь пихать это в РГБ? Проще сделать 1===0xFF и не епсть мозг. Делить придётся на 255, а не сдвигать на 256, вот и всё.
Многого нет здесь: http://lvd.nedopc.com
|
|
| |
deathsoft | Дата: Понедельник, 2009-08-03, 23:27:13 | Сообщение # 6 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 1587
Статус: Offline
| Quote (lvd) Ну или так сделай, но 1 хуй получишь ты 0x100, и куды ты будешь пихать это в РГБ? Там же написано - арифметика с насыщением если > 255 то записывается 255. Посмотри любые алгоритмы преобразования цветов (в MMX даже спец команды есть для сложения с насыщением).
|
|
| |
lvd | Дата: Вторник, 2009-08-04, 20:09:46 | Сообщение # 7 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 2528
Статус: Offline
| Quote (deathsoft) Там же написано - арифметика с насыщением если > 255 то записывается 255. Какая должна быть матрица, чтобы тройку RGB тождественно перевести в её же саму? Для случая 1===0xFF матрица ff 0 0;0 ff 0;0 0 ff. Для случая 1===0x100 в студию. Используй любые насыщения в процессе расчёта, матрицу в студию и алгоритм пост-обработки.
Многого нет здесь: http://lvd.nedopc.com
|
|
| |
deathsoft | Дата: Среда, 2009-08-05, 01:10:01 | Сообщение # 8 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 1587
Статус: Offline
| Quote (lvd) Какая должна быть матрица, чтобы тройку RGB тождественно перевести в её же саму? Quote (deathsoft) В случае преоразования 1 в 1 матрица должна состоять из чисел [0x100 0 0] I=[0 0x100 0] [0 0 0x100] Ro=(Ri*0x100+Gi*0+Bi*0)/0x100 Go=(Ri*0+Gi*0x100+Bi*0)/0x100 Bo=(Ri*0+Gi*0+Bi*0x100)/0x100 Собственно все уже сделано в унриале, только коэффициенты в матрице неверные. Вместо 1.0 там 255/256
Сообщение отредактировал deathsoft - Среда, 2009-08-05, 01:12:56 |
|
| |
lvd | Дата: Среда, 2009-08-05, 07:23:40 | Сообщение # 9 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 2528
Статус: Offline
| Quote (deathsoft) Ro=(Ri*0x100+Gi*0+Bi*0)/0x100 Go=(Ri*0+Gi*0x100+Bi*0)/0x100 Bo=(Ri*0+Gi*0+Bi*0x100)/0x100 Это выходит за пределы 8*8->16 умножения и за пределы 8-битной матрицы. Если это приемлемо, то да, всё ОК.
Многого нет здесь: http://lvd.nedopc.com
|
|
| |
deathsoft | Дата: Среда, 2009-08-05, 12:07:54 | Сообщение # 10 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 1587
Статус: Offline
| Quote (lvd) Это выходит за пределы 8*8->16 умножения и за пределы 8-битной матрицы. Если это приемлемо, то да, всё ОК. Приемлемо, промежуточные расчеты просто int, а результат char, если бы были ограничения с разрядностью - то пришлось бы извращатся.
Сообщение отредактировал deathsoft - Среда, 2009-08-05, 12:08:22 |
|
| |
deathsoft | Дата: Четверг, 2009-09-17, 23:53:34 | Сообщение # 11 |
Retry, Abort, Ignore?
Группа: Человеки
Сообщений: 1587
Статус: Offline
| Quote (deathsoft) Коэффициент 255 в матрице не соответствует единице, для единицы в матрице должно быть 256. [Ro] [R11 R12 R13] [Ri] [Go]=[R21 R22 R23]*[Gi] [Bo] [R31 R32 R33] [Bi] В случае преоразования 1 в 1 матрица должна состоять из чисел [0x100 0 0] I=[0 0x100 0] [0 0 0x100] Сделал в соответствии с формулой, теперь белый 255,255,255 а не 254,254,254
Сообщение отредактировал deathsoft - Четверг, 2009-09-17, 23:54:22 |
|
| |
|
|