PeterLemon / PSX

PlayStation Bare Metal Mips Assembly Programming
115 stars 8 forks source link

How to render 3D triangles, prisms, and more complex 3D objects? #1

Open andrigamerita opened 10 months ago

andrigamerita commented 10 months ago

Hello, your repo is really useful, and I'm finding it the best way for learning about pure assembly development on the PSX. I was able to modify the code part of some examples to do a bit of practice, but I'm currently struggling to understand something that's probably very trivial: how would I render triangles in 3D space (not in 2D), instead of the quads that are used in the Cube example; first to display very simple objects like a prism, and then possibly much more complex models, using the included ASM functions?

Looking in the .asm and .inc files, I found a function apparently analogous to ShadeTexQuadCullBackZSort but for triangles, ShadeTexTriCullBackZSort. If I understood correctly by reading the code, it should work with a data structure similar to the cube one, but without the attributes related to point 4 (since we're dealing with triangles and not rectangles)... however, no matter what I've tried, I can never display even a single triangular face correctly, and always have either glitches or nothing at all on screen. I don't really have code to post, because what I did is swap the macro call in the cube demo for the other one, modify the cube data structure to omit every segment that relates to the 4th point, leaving only the first 3, and then attempting (many, many times) to write multiple 3-point coordinates that I would think make sense for a triangle face.

On the Internet, many materials can be found about rendering complex 3D objects on the PSX, but they all relate to C development with various SDKs and not pure ASM development. If possible, it would be nice to get some example code for drawing a simple triangle-based 3D object, like a pyramid or a prism as I said. Having that hard part as a base, it will be really easy to convert and draw any complex 3D object. I would really appreciate it. Thank you for your time.

PeterLemon commented 10 months ago

Hi thanks for your kind words, yep you are def on the right track, the way I learned to display GPU triangles was going through each GPU command & making tests for each one in my "GPU" directory. My 3D tests are not using the GTE for transformations (I am using the CPU) so I will need to make a cube/pyramid demo using the GTE as a next step on my GitHub. In my Cube test I hope you can see how I use a matrix to transform the vertex points, then convert those 3D points to 2D screen space using a perspective transform. Anyway here is where I got up to with my (CPU) 3D engine, it is a 3D Mario head example using triangles I hope it can help you further: 3DEngine.zip

andrigamerita commented 10 months ago

Hi again, your 3DEngine example is useful, indeed I'm seeing how my initial intuition was correct, but also that even after this rendering a textured triangle, instead of a flat colored one, is still not so obvious. However, after noticing these differences in the code and your suggestion, I'm guessing that the issue probably has something more to do with the GPU command used for rendering, and while I'm reading up on https://psx-spx.consoledev.net/graphicsprocessingunitgpu the information available there doesn't seem to be extremely comprehensive and so I will probably need to try and test different commands, and see if I can land somewhere. With what I've tried at the moment to render textured triangles I'm still having glitches, but different. By the way, did you use some kind of program to convert the Mario head model to the binary format used by the PSX GPU, or did you assemble it manually? I imagine it wouldn't be hard, but I will probably have to write a small script to convert models from OBJ (or other standard formats) to that binary format, if it doesn't already exist.

PeterLemon commented 10 months ago

Yep I made a Blender exporter for the Mario head (to get the data), I think the object is just ripped from the N64 game Mario64 intro. Yep as for docs, I got all my information for my 3D stuff on PS1 from NO$PSX documentation here: https://problemkaputt.de/psx-spx.htm especially the GPU section: https://problemkaputt.de/psx-spx.htm#graphicsprocessingunitgpu I hope this helps =D