106k, 2 byte per pixel, is it this

{ nextx, color }

the L register of the struct address is x, nextx - x gives the size of the span.

without z buffer byte I imagine the span logic a lot easier.

it is hassle enough to have all the x management.

4-5 cycles for external RAM,

it would be funny when nextx is in internal RAM and the rarely acessed color byte on the cartridge.

add 16k to the H register, offset to another 16k page.

but is this way just for making 3d objects or can you do a more world like gfx?

For perspective calculation I used a table with the perspective of a point at 256. ptable[z] = (256 * P)/(z + P) where P is the distance between the screen and the viewers eye in pixels. (You have to guesstimate that value.)

Then then perspective calculation is reduced to x * ptable[z] / 256.

A nice thing here is that skipping the lower byte of the multiplication introduces less than one LSB worth of error and it is in the other direction than the one introduced by the quantization in the table so in total the error is within +/-1 LSB

Since you only need to check the upper byte in the square table during the multiplication you can save a lot of cycles there.

Another way to check what way a surface is facing is to check the sign of its area.

For a triangle between the points A B C it would be ((By-Ay)*(Bx+Ax) + (Cy-By)*(Cx+Bx) + (Ay-Cy)*(Ax+Cx))/2, so three multiplications and the last shift can be omitted if you only care about the sign.

I've never tried this method so I don't know about the caveats.

I guess it should be possible to shift down x and y before the addition to avoid having to deal with overflow.

It will make things a bit "fuzzy" with areas close to 0 but as long as you consider those as visible it would probably be fine.

lord_zett yes, it could make some world, big polygons go very fast. and CLS goes very fast.

*hit9918*wrote:

106k, 2 byte per pixel, is it this

{ nextx, color }

the L register of the struct address is x, nextx - x gives the size of the span.

without z buffer byte I imagine the span logic a lot easier.

it is hassle enough to have all the x management.

Yeah, the logic definitely took some effort to write . Now that I have it, it’s such a shame to discard it .

*hit9918*wrote:

4-5 cycles for external RAM,

it would be funny when nextx is in internal RAM and the rarely acessed color byte on the cartridge.

add 16k to the H register, offset to another 16k page.

Interesting idea if the buffer does not fit in the internal memory!

*hit9918*wrote:

lord_zett yes, it could make some world, big polygons go very fast. and CLS goes very fast.

would be cool.

*bore*wrote:

For perspective calculation I used a table with the perspective of a point at 256. ptable[z] = (256 * P)/(z + P) where P is the distance between the screen and the viewers eye in pixels. (You have to guesstimate that value.)

Then then perspective calculation is reduced to x * ptable[z] / 256.

A while back I was looking at this, because why use a 4x4 perspective projection matrix when you could use 4x3 matrices and divide by z? But for correct perspective, you need to divide by the distance to the point, in other words sqrt(x*x + y*y + z*z).

So for a point in the center of your view, the z coordinate will be the correct distance, but for points closer to the edges of the screen the z distance will be too low, so it causes some perspective distortion. The amount of shearing would vary based on the view angle. It may be acceptable under certain conditions?

The perspective projection matrix does yield correct perspective whilst avoiding the square root, through the use of homogeneous coordinates. (To hazard a guess, I imagine the w is determined by rotating the z value to the center of the screen?)

p.s. I reckon the P value can be derived from the view angle and the near clipping plane.

Supposedly a view angle of 90º is a good choice, because the 45º half-angle means that the clipping planes lie directly on x=z and y=z, which makes it easier to do e.g. clipping in world space rather than view space. This can avoid matrix multiplications and the perspective divide for culled polygons.

Another way to check what way a surface is facing is to check the sign of its area. For a triangle between the points A B C it would be ((By-Ay)*(Bx+Ax) + (Cy-By)*(Cx+Bx) + (Ay-Cy)*(Ax+Cx))/2, so three multiplications and the last shift can be omitted if you only care about the sign. I've never tried this method so I don't know about the caveats.

That looks similar to backface culling based on the winding order of the polygons using a cross product, although that should require only two multiplications? (Bx-Ax)*(Cy-Ay) - (Cx-Ax)*(By-Ay)… Not sure what is different.

The one caveat that I can think of is that the polygon indices must have the correct winding order (CW or CCW, should be a simple checkbox in 3D modeling software).

---

To throw a link out here, in addition to Michael Abrash’s Graphics Programming Black Book which I think I mentioned earlier, the Hugi programming articles on 3D graphics are also interesting.

*Grauw*wrote:

For a point in the center of your view, the z coordinate will be the correct distance, but for points closer to the edges of the screen the z distance will be too low, so it causes some perspective distortion. The amount of shearing would vary based on the view angle. It may be acceptable under certain conditions?

No distortion. The function just maps 3D coordinates to the front of screen.

http://imgur.com/hoEof7V

It is simply the intersection between the screen and the pixel-eye line.