Show HN: Tiny PS1-like Renderer in 500 lines

(github.com)

141 points | by nkanaev 13 days ago

18 comments

  • ok_dad 12 days ago
    Linked in the README is the article this is probably based on, which explains the rendering for a PS1 and why it has certain behaviors, it's a great article: https://www.david-colson.com/2021/11/30/ps1-style-renderer.h...
    • Pulcinella 11 days ago
      This should be required reading for anyone that trying to emulate the PS1 rendering aesthetic. Too many developers seem to think that PS1 games probably looked worse than how they remember them and try to compensate for their nostalgia (or just want to heighten the aesthetic) by introducing far, far more wobbling and warping than there actually was!
  • ppeetteerr 12 days ago
    Love the project and the spirit of it. Brings be back to playing FFT.

    Question to all C/C++ programmers out there. Why are your variables so terse? I have no idea what td and dt mean and why they are both in the same function. I'm genuinely trying to read your code and have no idea what is happening because there is seemingly a desire by the author to keep variables as short as possible. Why?

    • Pulcinella 11 days ago
      Don’t go to ShaderToy. You will find a really cool shader and then be disappointed when the code is incomprehensible because whoever wrote it want used one letter variables (starting alphabetically! So x, y, and x coordinates might not even be “x, y, z” but “o, p, q”).
      • v3ss0n 11 days ago
        That's so legit.. I just spent 3 hr reading code of shader toy last night at 1 am, all I could do was changing color... And it was in a variable named c1
  • ptsneves 12 days ago
    Amazing. On the other hand it makes use of a graphics library that is way bigger than 500 lines. Regardless thank you for sharing but I get the feeling it was good fun.
  • glouwbug 12 days ago
    heh, I wrote an N64 one not too long ago with the exact same style:

    https://github.com/glouw/gel

    • SandmanDP 12 days ago
      You might notice that your project is already included in the Readme under credits.
      • glouwbug 12 days ago
        I did not notice. Neat. I appreciate the PS1 more. Remembering way back, N64 carts were 10 dollars or so more than PS1 discs, and as a result I had a stockpile of PS1 games. The texture popping of the PS1 I could never make sense of but it became an aesthetic of the era. Nice work OP, and thankyou for the credit
        • klodolph 12 days ago
          I know there’s another reply with videos here. I’m gonna put an explanation in text.

          The N64 had two things which made things smoother. It had sub-pixel precision for geometry after projection, and it had perspective-correct interpolation. This meant that moving objects looked smooth and didn’t “pop”. Games on the PS1 addressed the interpolation problem by subdividing, but you could sometimes see geometry suddenly move when you got closer and saw more subdivisions.

          The N64 also had texture interpolation (kind of like bilinear) and antialiasing, but those don’t make as big an impact.

          The N64 got all these things right, more or less, but had problems with memory bandwidth and small texture memory.

          • ace2358 12 days ago
            I was also under the impression the PS1 only had integer precision? Would that contribute to the wobbling and popping?
            • klodolph 11 days ago
              That’s the “subpixel” precision I’m talking about.
        • codetrotter 12 days ago
          > The texture popping of the PS1 I could never make sense of but it became an aesthetic of the era.

          The Truth About PS1 Graphics

          https://www.youtube.com/watch?v=ESXAxtdEkzY

          Why PlayStation 1 Graphics Warped and Wobbled so much

          https://www.youtube.com/watch?v=x8TO-nrUtSI

    • andrewmcwatters 12 days ago
      Very nicely written. Glad you shared this here, and that it was mentioned in the README.md.

      Edit: It looks like all of your C is actually very well written. What a pleasure to read!

      • glouwbug 12 days ago
        Why thank you. They've all been passion projects and they were all published only after numerous rewrites. Roman2 ended up being the pinnacle of my work. I sadly don't know to work on next. Never thought I'd run out of ideas, but I guess turning 30 does that
        • egypturnash 12 days ago
          Dig for that crazy pile of N64 game ideas Kid You drew out and start hacking on one, now that you have the renderer!
    • sitzkrieg 12 days ago
      i came across this a few days ago searching n64 style rendering, its awesome! i plan on trying to make a spiritual successor of sorts for blast corps using those techniques in another renderer
  • havercosine 12 days ago
    This looks nice! Great work.

    If anyone is interested in learning how graphics rendering works under the hood without too much scaffolding, there's a great course at https://pikuma.com/courses/learn-3d-computer-graphics-progra... (I'm no way associated with that website, just loved the course). That course starts from absolute basics: creating a colour buffer as in memory array and gradually covers lot of ground on 3D rendering: drawing pixels, lines, triangle fill rasterisation, texturing. The course uses minimal help: SDL is used for rendering on window and dynamic arrays are provided as a small C library. But everything else is coded from scratch in C by the instructor in the lecture, word by word.

  • crabbygrabby 12 days ago
    So cool. Took me back to my childhood instantly. You nailed it
    • angarg12 12 days ago
      My first reaction was "damn that looks good!". I guess it was the nostalgia taking over.
  • confident_inept 12 days ago
    Glad to see PS1 style rendering that simulates the affine texture warping side effects of the console. The original Playstation was very much not designed with 3D in mind, lack of perspective correction on textures lead to the aforementioned warping.

    Vertex coordinates were rounded to whole integers, giving that hallmark polygon jiggle effect from the rounding that 'snapped' them in place. The complete lack of a z-buffer also lead to lots of z fighting, as the system rendered polygons strictly in the order they were calculated.

  • 0xf00ff00f 12 days ago
    Looks great!

    I couldn't help noticing that it tests every pixel on the "screen" to see whether it's inside a face. Back in the software renderer days we'd run the inner loop just for the pixels that fell inside a triangle. But then you'd need to explicitly handle polygon clipping and it would greatly complicate the code. I guess 320*240 tests is nothing these days.

    Anyway, great job!

  • herpderperator 12 days ago
    I thought this was referring to Prompt Shell 1 :')
  • yomkippur 12 days ago
    would love to see this run inside a browser. how do you create ps1 texture and lo-poly models like this? I so badly want to create a PS1 style game in the browser.

    For lot of us, our childhood was defined by this console. N64 as well but just something about the PS1 graphic that really speaks to me. Anybody else feel the same?

    • jasonwatkinspdx 12 days ago
      No clue what people use today, but when I worked on a psx game 3D Studio Max was the the main choice, with Lightwave 3D having a lot of fans as well. Doing low poly modeling you basically just live between the edge split, rotate, merge, and vertex move tools, so it's incredibly important they have a low friction UI.
      • yomkippur 12 days ago
        omg what game
        • jasonwatkinspdx 11 days ago
          It was a never published port of Unreal to Playstation 1.

          Interestingly enough the renderer was up and running. It was a lot more limited in triangle count than the PC version, hence a lot of fiddling with models.

          In any case, the project fell apart for the usual disorganized management reasons.

    • BHSPitMonkey 12 days ago
      From a quick glance at the graphics library being used here[1], it doesn't seem like a terrible amount of work to add support for WebGL and then get this entire project compiled into wasm (at least for someone more comfortable working in C than myself!)

      [1] https://github.com/erkkah/tigr

  • doubled112 12 days ago
    Funny that my first thought was that the polygons better wobble and it's right there in the features list.
  • unwind 12 days ago
    Very cool and nostalgic! Had no idea the PS1 look was trending.

    Also, due to Stack Overflow conditioning: fgetc() does not return 'char', it returns 'int' else EOF won't fit.

    • st_goliath 12 days ago
      > fgetc() does not return 'char', it returns 'int' else EOF won't fit.

      Or more precisely: don't store the return value in a 'char' and check if it is EOF. On some platforms (e.g. gcc ARM eabi), regular 'char' is unsigned and the check fails.

  • aliswe 12 days ago
    WOW! Looks great! Definitely hit my nostalgia nerve!
  • LAC-Tech 12 days ago
    Have PS1 triangular graphics made a retro resurgence yet? Because I'm so down for that.
  • zem 12 days ago
    that was pretty prompt!
  • klipklop 12 days ago
    I was wondering how this was done in 500 lines...then I saw the 5000+ line library file borrowed from another project. I do enjoy the look of your results though.

    How long before somebody includes your library and says they created PSX graphics in 25 lines?

    • chii 12 days ago
      depends on how you look at things. The library is a rendering library (presumably for calling GL).

      And what about any of the operating system calls that might get used? It's also a library (despite the source code not being in the project).

      The actual code to compute the logic of the graphics PS1 style, is indeed around 500 lines.

  • angry-1 11 days ago
    undefined