Ошибка в просчете палитры?

Bugs (reports, fixes, etc.)

Postby moroz1999 » 02 Aug 2009, 12:55

В общем, если я не ошибаюсь, то в процедуре расчета палитры закралась ошибка.
При расчете палитры результат делится не на 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
User avatar
moroz1999
 
Posts: 368
Joined: 02 Aug 2009, 12:26
Group: Registered users

Postby deathsoft » 02 Aug 2009, 23:38

Ошибки там никаокй нету, это обычное математическое нормирование, делится на размер диапазона 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.
Last edited by deathsoft on 03 Aug 2009, 11:37, edited 1 time in total.
User avatar
deathsoft
 
Posts: 4635
Joined: 07 Apr 2007, 00:58
Group: Registered users

Postby lvd » 03 Aug 2009, 14:02

А что мешает считать единицей 0xFF, кроме предрассудков?
F̞͖̭̿̔ͯu̐̅cͬ̑ͩk̨̤̳͇̮̭̪̠̽̿̓̆ͭͩ ̷̩̰͎̩͓̘̾̀ͬ̊ͭ͛ͅda̝̺͙̬͎̝̾͟ ̰̜̝̯͉̯̖̓̎́ͨ̽ͫ͟f̟͇̭̀ͬͨͭ̐̚u̹̼̹̗̞͑̔͂͐̚cͭ̅̊̆̒̆ǩ̝̩̯́ͥ̔̍̑ḭ͓͍̳̬ͦ̽͂n͍͎͈̈̅ͩͬ ̊ͫ̂̾̑̈́f̲͚͉͓͗̋́ͧͦ̅ȗ͇̲̻͈̲̅̎͗͒ͭ͡c̬̟̠̹̯̈́ͩ͘ͅk̫̠̻̋͜a̲͒̾̇!͙͕̺͉̗̩̲̂̏̄̀
User avatar
lvd
 
Posts: 7158
Joined: 07 Apr 2007, 21:28
Group: Registered users

Postby deathsoft » 03 Aug 2009, 15:14

lvd wrote:А что мешает считать единицей 0xFF, кроме предрассудков?

Тогда нуля не будет и будет неточно, надо просто в матрицу записывать коэффициенты 0..256 и все, а в унриале исправить расчет, чтобы внутринние вычисления были int а на байт, и будет все как надо, т.е. результирующий цвет будет 0..255. Еще сделать проверку на насыщение (не знаю сделано ли сейчас).

P.S. Ну и все палитры в ини файле надо будет поправить, чтобы где 1 было 0x100.
Last edited by deathsoft on 03 Aug 2009, 15:16, edited 1 time in total.
User avatar
deathsoft
 
Posts: 4635
Joined: 07 Apr 2007, 00:58
Group: Registered users

Postby lvd » 03 Aug 2009, 19:22

deathsoft wrote:Тогда нуля не будет и будет неточно,

Ты шо, тормоз?
0 это ноль
255 это 1
ff*ff/ff === ff

deathsoft wrote:надо просто в матрицу записывать коэффициенты 0..256 и все, а в унриале исправить расчет, чтобы внутринние вычисления были int а на байт, и будет все как надо, т.е. результирующий цвет будет 0..255. Еще сделать проверку на насыщение (не знаю сделано ли сейчас).

Ну или так сделай, но 1 хуй получишь ты 0x100, и куды ты будешь пихать это в РГБ? Проще сделать 1===0xFF и не епсть мозг. Делить придётся на 255, а не сдвигать на 256, вот и всё.
F̞͖̭̿̔ͯu̐̅cͬ̑ͩk̨̤̳͇̮̭̪̠̽̿̓̆ͭͩ ̷̩̰͎̩͓̘̾̀ͬ̊ͭ͛ͅda̝̺͙̬͎̝̾͟ ̰̜̝̯͉̯̖̓̎́ͨ̽ͫ͟f̟͇̭̀ͬͨͭ̐̚u̹̼̹̗̞͑̔͂͐̚cͭ̅̊̆̒̆ǩ̝̩̯́ͥ̔̍̑ḭ͓͍̳̬ͦ̽͂n͍͎͈̈̅ͩͬ ̊ͫ̂̾̑̈́f̲͚͉͓͗̋́ͧͦ̅ȗ͇̲̻͈̲̅̎͗͒ͭ͡c̬̟̠̹̯̈́ͩ͘ͅk̫̠̻̋͜a̲͒̾̇!͙͕̺͉̗̩̲̂̏̄̀
User avatar
lvd
 
Posts: 7158
Joined: 07 Apr 2007, 21:28
Group: Registered users

Postby deathsoft » 03 Aug 2009, 22:27

lvd wrote:Ну или так сделай, но 1 хуй получишь ты 0x100, и куды ты будешь пихать это в РГБ?

Там же написано - арифметика с насыщением если > 255 то записывается 255. Посмотри любые алгоритмы преобразования цветов (в MMX даже спец команды есть для сложения с насыщением).
User avatar
deathsoft
 
Posts: 4635
Joined: 07 Apr 2007, 00:58
Group: Registered users

Postby lvd » 04 Aug 2009, 19:09

deathsoft wrote:Там же написано - арифметика с насыщением если > 255 то записывается 255.

Какая должна быть матрица, чтобы тройку RGB тождественно перевести в её же саму? Для случая 1===0xFF матрица ff 0 0;0 ff 0;0 0 ff.
Для случая 1===0x100 в студию. Используй любые насыщения в процессе расчёта, матрицу в студию и алгоритм пост-обработки.
F̞͖̭̿̔ͯu̐̅cͬ̑ͩk̨̤̳͇̮̭̪̠̽̿̓̆ͭͩ ̷̩̰͎̩͓̘̾̀ͬ̊ͭ͛ͅda̝̺͙̬͎̝̾͟ ̰̜̝̯͉̯̖̓̎́ͨ̽ͫ͟f̟͇̭̀ͬͨͭ̐̚u̹̼̹̗̞͑̔͂͐̚cͭ̅̊̆̒̆ǩ̝̩̯́ͥ̔̍̑ḭ͓͍̳̬ͦ̽͂n͍͎͈̈̅ͩͬ ̊ͫ̂̾̑̈́f̲͚͉͓͗̋́ͧͦ̅ȗ͇̲̻͈̲̅̎͗͒ͭ͡c̬̟̠̹̯̈́ͩ͘ͅk̫̠̻̋͜a̲͒̾̇!͙͕̺͉̗̩̲̂̏̄̀
User avatar
lvd
 
Posts: 7158
Joined: 07 Apr 2007, 21:28
Group: Registered users

Postby deathsoft » 05 Aug 2009, 00:10

lvd wrote:Какая должна быть матрица, чтобы тройку RGB тождественно перевести в её же саму?

deathsoft wrote:В случае преоразования 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
Last edited by deathsoft on 05 Aug 2009, 00:12, edited 1 time in total.
User avatar
deathsoft
 
Posts: 4635
Joined: 07 Apr 2007, 00:58
Group: Registered users

Postby lvd » 05 Aug 2009, 06:23

deathsoft wrote: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-битной матрицы. Если это приемлемо, то да, всё ОК.
F̞͖̭̿̔ͯu̐̅cͬ̑ͩk̨̤̳͇̮̭̪̠̽̿̓̆ͭͩ ̷̩̰͎̩͓̘̾̀ͬ̊ͭ͛ͅda̝̺͙̬͎̝̾͟ ̰̜̝̯͉̯̖̓̎́ͨ̽ͫ͟f̟͇̭̀ͬͨͭ̐̚u̹̼̹̗̞͑̔͂͐̚cͭ̅̊̆̒̆ǩ̝̩̯́ͥ̔̍̑ḭ͓͍̳̬ͦ̽͂n͍͎͈̈̅ͩͬ ̊ͫ̂̾̑̈́f̲͚͉͓͗̋́ͧͦ̅ȗ͇̲̻͈̲̅̎͗͒ͭ͡c̬̟̠̹̯̈́ͩ͘ͅk̫̠̻̋͜a̲͒̾̇!͙͕̺͉̗̩̲̂̏̄̀
User avatar
lvd
 
Posts: 7158
Joined: 07 Apr 2007, 21:28
Group: Registered users

Postby deathsoft » 05 Aug 2009, 11:07

lvd wrote:Это выходит за пределы 8*8->16 умножения и за пределы 8-битной матрицы. Если это приемлемо, то да, всё ОК.

Приемлемо, промежуточные расчеты просто int, а результат char, если бы были ограничения с разрядностью - то пришлось бы извращатся.
Last edited by deathsoft on 05 Aug 2009, 11:08, edited 1 time in total.
User avatar
deathsoft
 
Posts: 4635
Joined: 07 Apr 2007, 00:58
Group: Registered users

Next

Return to Ошибки

Who is online

Users browsing this forum: No registered users and 1 guest

cron