Hi all,
@neobrain Did you manage to solve the problem with linear interpolation? I was reading through the thread and couldn't resist posting.
It seems to me that the stepdowns at places 20h, 60h, A0h and E0h are due to a rounding down. As you notices those values times 4 equal to 80h mod 100h. This is, if after multiplying c by 4 you divide by 100h you will get 0.8h at 0x20 (or analogues) and 0.7C at 0x21 (or analogues). If rounded to the closest integer, one would go up and the other one down hence creating a gap of 3 instead of 4. This suggest the denominator in the formula being 256 (100h).
In order to adapt to it, c should range from 0 to 256. And it seems there is a gap in 0x80. Hence the values of c could be interpreted as follows:
Values 00h - 7Fh correspond to 0-127
Values 80h - FFh correspond to 129-256
Since c indicates how close this number will be to a and b, it does not matter too much "jumping" one color.
Code doing this could go like this:
Works for the values in the pastebin, if I checked it alright. It will work for the rest of the cases if it is that rounding error that is making the flipper give those results. I am actually doing the same that what was proposed before, except I am handleing the error more generically.
@neobrain Did you manage to solve the problem with linear interpolation? I was reading through the thread and couldn't resist posting.
(03-09-2014, 06:48 AM)neobrain Wrote: Does anyone of you happen to be into linear interpolation algorithms?
The GC/Wii GPU provides a feature called color combiners, which essentially linearly interpolates between 3 input values and additionally scales them with some value. I've came across a fancy problem, if anyone of you is bored enough to make sense out of it, look here: http://pastie.org/private/qaohdkaqljvfsnog7xyzgg
Point is, I'm trying to understand how this lerp is implemented specifically so that I can fix Dolphin to use the same algorithm. I don't really get anything about it so far though, unfortunately...
I'm in fact currently running tests against real hardware which check all possible 16777216 inputs, because I don't quite know what else to do with this :/
It seems to me that the stepdowns at places 20h, 60h, A0h and E0h are due to a rounding down. As you notices those values times 4 equal to 80h mod 100h. This is, if after multiplying c by 4 you divide by 100h you will get 0.8h at 0x20 (or analogues) and 0.7C at 0x21 (or analogues). If rounded to the closest integer, one would go up and the other one down hence creating a gap of 3 instead of 4. This suggest the denominator in the formula being 256 (100h).
In order to adapt to it, c should range from 0 to 256. And it seems there is a gap in 0x80. Hence the values of c could be interpreted as follows:
Values 00h - 7Fh correspond to 0-127
Values 80h - FFh correspond to 129-256
Since c indicates how close this number will be to a and b, it does not matter too much "jumping" one color.
Code doing this could go like this:
Code:
int odd_lerp(int a, int b, int c)
{
if (c&0x80) c++; // Take the step for the highest values
int temp = a*(256-c) + b*c;
return ((temp >> 6) + ((temp&0x20)?1:0)&0xFF); // Divide by 256 multiply by 4 and round up or down depending on the most significant byte that was lost.
}
Works for the values in the pastebin, if I checked it alright. It will work for the rest of the cases if it is that rounding error that is making the flipper give those results. I am actually doing the same that what was proposed before, except I am handleing the error more generically.