/Java-Rasterizer

This is a simple real-time software rasterizer

Primary LanguageJavaDo What The F*ck You Want To Public LicenseWTFPL

The Rasterizer

This is (an attempt at) a real-time software rasterizer. The graphics logic is mainly based on the renderer described in Tiny Renderer.

dragon

This project uses no dependencies other than the Java Class library.

How To Use

Simply run Main.java with your IDE of choice, or from a terminal, then import a .obj file using the import button. You can import the .obj file found inside the assets folder for a quick start.

You can also configure texture paths by accessing model/pipeline/programmable/PhongShader.java, which is the default shader.

Keep in mind that some .obj files may not load properly, as this engine uses a fairly primitive way of loading objects. Since we do not intend to develop this engine further, we are unlikely to fix this. Feel free to implement your own model loader ;).

Current status of Rasterizer agkj3-mf8w6-002 :

  • All testing done with a .PPM file.
  • Renderer has functions to draw lines, triangles, and set single pixels.
  • Renderer has depth testing.
  • Renderer displays to window.
  • Renderer has model loader.
  • Renderer can load textures and interpolate texture coordinates.
  • Window can display rendering output in real time
  • Renderer has transformations.
  • Shader can shade any number of directional light sources.
  • Renderer re-sizes object coordinates based on viewport dimensions, keeping the aspect ratio of the object intact.
  • Pipeline has programmable vertex and fragment shaders.
  • Shaders have specular mapping and Phong specular shading.
  • GUI now reflects shader state.
  • [More functionality will be appended here]

Development Diary :

The following is a diary of any intersting thoughts I had during the development of this rasterizer.

Converting C++ to Java is hell. Java doesn't let you do anything. I miss const vec2& T_T

october 9th

Note to future self and developers : when loading huge data into a string inside a for loop, please use stringBuilder or stringBuffer. I was copying the same string literally millions of times with megabytes worth of data.

october 10th

Finished setting up the basic model.renderer. Drawing 55 triangles took 7 seconds, seems kind of slow but won't know until we load actual model.

october 11th

Another one in the "typos that cost me hours" section

image

It should be if (std::abs(orthogonal.z)>1e-2)

Erratic depth map

image

This is 3 errors working all at once. One is the typo above, the other is multiplying vertices in the wrong order to determine barycentric coordinates (this is why it looks triangulated), and the final error is that I forgot to initialize my depth buffer with the negative maximum float value, instead leaving it to the default of 0.

Correct (I hope!) depth map image

october 12th

Cool bug.

image

october 14th

I would kill this typo if I could.

image

minY should obviously take the y value. I had to deal with this typo the day before presenting my code, and I troubleshot it for at least an hour. Nothing beats the frustration of "How could I miss this?"

When I said I would kill that typo I might've been exaggerating. But this bug I would actually kill if I could.

image

What you are looking at is the RGB map of surface normals.

The story of how I struggled for 5 hours with this bug shall remain undisclosed, but suffice it to say the problem was depth buffer testing. This might seem obvious to you but it stumped me. Until Agab suggested the genius idea that it could be triangles rendering in the back. Even then I doubted it, after all my cpp code worked perfectly without depth buffer testing. Later on we loaded a spherical model (thanks, MIT!) :

image

What a sickly ball!

Most importantly, I decided to test every axis separately.

image

The x-axis. Seems right.

image

Y. Seems right!

image

Curse you Z-axis.

After implementing depth testing :

image

What a healthy ball!

october 15th

In celebration of v0.1 of our rasterizer, here are some interesting images :

Ball image

Interpolated normals image

Non-interpolated normals image

Texture sampling

image

This one might also feature in my bug report, I still don't know if this is what it should look like.

It turns out I was wrong. Everything was right. The bug eludes me. I just used my map() function, instead of doing the operations directly, and the texture loaded perfectly. I don't understand, but this is no time for understanding. The code worked, hurrah!

image

For future reference the texture was loading all fucked up when I didn't use map().

october 16th

Finally! we have real-time rendering, but...at what cost? It's very slow. VERY. Currently only outputting about 0.5FPS with a single model loaded. I don't even have any ideas on how to make it faster anymore, other than multithreading.

october 17th

I am lucky that I worked with OpenGL before. I was wondering why my model wasn't rendering every frame (even though I was clearing the color buffer), and it just occured to me that we also clear the depth buffer in OpenGL every frame. Bless LearnOpenGL!

october 18th

No real updates today except some cool gifs :

ezgif-5-0261ae3332

ezgif-5-b3d88de14d

ezgif-5-713d5d5e29

Generally speaking, you get a lot of cool bugs in graphics, but this one really caught my eye. The most intentional looking bug I've had so far. I was forgetting to clear the color buffer every frame.

october 22nd

Long time no update! Let's get started with this funny bug :

changingCoordsEveryFrame

Instead of copying the vertex coordinates, I was changing them every frame, thus applying the same transform cumulatively.

Also, he's rotating.

rotate

october 23rd

More rotaty ones :

cube-rotate stanford-bunny-rotate-5x african-head-rotation x4

The cube gif is not sped up!

You can also notice that we have 2 light sources instead of the usual 1 + ambient.

november 3rd

I can't believe it's been that long. We have done some fundamental changing to the structure of the codebase. Modifiyng shaders and texturing have never been easier!

As usual here are the cool bugs and gifs :

Hmm, yes. Normal mapping.

so that's what a normal map is

Now this is real normal mapping

normalMapping

Okay, in this one I projected the normal map as a light source, and did some funky shading

normalMapProjection

november 20th

It's been a long time without an update. I don't have many interesting bugs this time around but here are some cool screenshots :

Specular

Screenshot from 2023-11-20 16-50-51 Screenshot from 2023-11-20 16-51-07

Note that the specular highlight changes according the angle we view the model from.

Specular + diffuse

Screenshot from 2023-11-20 16-57-42 Screenshot from 2023-11-20 16-54-24

(specular + diffuse) * texture

Screenshot from 2023-11-20 16-55-44 Screenshot from 2023-11-20 16-55-29