It is currently Mon Oct 20, 2014 4:49 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Mon Sep 21, 2009 9:46 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
ThomasHarte wrote:
Then you get a 16bit number, and you suggest that you can just pass the two bytes separately through the same 8bit multiplication table and also add/subtract the results normally. But that doesn't quite work.

a = +1 = 7f
b = -128/127 = ff80

a * b = ((7f * ff)*127) + (7f*00) = (+1 * -1/127)*127 + (+1 * 00) = -127/127 = -1

(applying the split as described in your post; low 6 bits to one multiplication, 7 bits on top of those 6 bits to the other)


Just to try and further explain things using one of your examples: In this instance, the value 'b' will be considered a 15-bit signed integer. It's not a fixed127. Therefore its value (FF80) is -128. Not -128/127ths. It's not a fixed127. This wouldn't be useful! The only useful meaning of a 2-byte long number is as a signed integer, which we can multiply by a fractional value between -1.0 and 1.0 (i.e. the fixed127).

So, when we split FF80 into the two chunks, we get:

bits 7-14: FF (as a signed integer, equivalent to -1)
bits 0-6: 0

Then, we multiply by components:

-1 * 1.0 = -1 * 127 / 127 = -1 (multiplied by 128)
+ 0 * 1.0 = 0 * 127 / 127 = 0
----------------
result = -128, which is the correct answer


Top
 
PostPosted: Tue Sep 22, 2009 3:04 pm 
Offline
 Profile

Joined: Mon Aug 04, 2008 1:54 pm
Posts: 55
Hi, sorry, on holiday and tapping this out on an iPhone.

See your point about the tables, but still concerned about big value multiplications: if you divide by 128 then you know exactly where the result will end in terms of binary digits after the decimal place. Obviously there's no such guarantee with dividing by 127. Would suggest that an 8.8 scheme for the lookup-table would be appropriate if sufficient memory is available.

Learnt on the Sam that even 2.8 precision produces poor precision on large 8.8 numbers re: the computed position of an object relative to the camera if you use the ordinary matrix stuff. Found it was much better to multiply 3x3s alone, work out offset as difference in global positions mapped forward once through the camera matrix (rather than, effectively, object position through composed matrix minus camera position through composed matrix). Limits you to exactly two matrices rather than a GL-style stack, but I think would probably be smart here too, as I think it's the only thing that involves big numbers.

Hoping to get some sort of simplistic 3d display going soon, will give fixed127s a shot, see how it looks.


Top
 
PostPosted: Tue Sep 22, 2009 3:44 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Quote:
See your point about the tables, but still concerned about big value multiplications: if you divide by 128 then you know exactly where the result will end in terms of binary digits after the decimal place. Obviously there's no such guarantee with dividing by 127. Would suggest that an 8.8 scheme for the lookup-table would be appropriate if sufficient memory is available.

The problem will be whether 128 discrete values representing the range of 0.0 to 1.0 inclusive is sufficient. The multiplication routine produces surprisingly accurate results, even for s15 * fixed127:

results accurate to within +/-1.0: 92%
results accurate to within +/-1.5: 99.5%

The lookup table already is 8.8 (i.e. each entry contains (x^2/4)/127, stored as an 8-bit integer part, and an 8-bit fractional part).

Quote:
Found it was much better to multiply 3x3s alone, work out offset as difference in global positions mapped forward once through the camera matrix (rather than, effectively, object position through composed matrix minus camera position through composed matrix).

Yeah, this is more or less what I proposed a little while ago I think... you transform model space coords through a unit 3x3 rotation matrix, and then add a global translation afterwards to get it into 15-bit coordinates. From an old post:
Code:
x' = x . LW . CW^-1
   = (x . LWr + LWt) . (CWr + CWt)^-1
   = (x . LWr + LWt) . CWr^-1 - CWt . CWr^-1
   = x . (LWr . CWr^-1) + [(LWt - CWt) . CWr^-1]
          ^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^^
         8-bit rotation     16-bit translation

This is in fact what the hardware of the original PlayStation did, and it worked well there! Is this the sort of thing you mean?

Look forward to seeing if this works ok or not... The nice thing about the fixed127s being only one byte in size is that they hugely simplify a matrix multiply, e.g.
Code:
; multiply X component
LDX vec+0:LDY matrix+0:JSR S8_x_Fixed
STA vecresult+0
LDX vec+1:LDY matrix+3:JSR S8_x_Fixed
CLC:ADC vecresult+0:STA vecresult+0
LDX vec+2:LDY matrix+6:JSR S8_x_Fixed
CLC:ADC vecresult+0:STA vecresult+0

; similar for the other two components

In the case where two fixed127s are multiplied, it'd perhaps be necessary to put in some extra checks to clamp the results of the adds to +/-1.0. Also, at a speed cost, it'd be possible to make the S8_x_Fixed multiply routine a little more accurate, which might also be necessary when composing matrices. We'll have to see...

Enjoy your holiday!


Top
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron