
Show HN: 3D Renderer Built using 2D HTML Canvas - vivekseth
http://vivekseth.com/canvas-3d-renderer/
======
badsectoracula
Neat, although the fun begins when you try to fill them since you cannot just
ignore the primitives anymore if a vertex touches the near plane but instead
you have to clip the primitive :-). Also without a z-buffer hidden surface
removal becomes tricky if you want to avoid bad overlaps.

For fun i made a 3D thing a few years ago, you can check it here:

[http://runtimeterror.com/pages/badsector/nyan/test.html](http://runtimeterror.com/pages/badsector/nyan/test.html)

The code does the clipping part (triRender function) although HSR is painter's
algorithm with a simple sorting (triSort) with a heuristic (triCompare) that i
came out through trial and error (because of the distortion introduced by the
perspective projection this doesn't always work and IIRC i'd need to actually
split the polygons for better result but i was too lazy for that :-P).

Note that i wrote this for fun a few years ago, i am not a web dev nor really
follow web tech. This is the biggest block of JavaScript code i've written for
years :-P.

~~~
cr0sh
For something you wrote for fun, this particular engine is pretty impressive.
It was reminiscent of the old PC virtual reality software engine, REND386 (by
Bernie Roehl and Dave Stampe):

[http://buter.software/rend386/](http://buter.software/rend386/)

I played around a lot with that engine "back in the day". Modded a Power Glove
to hook up to the parallel port (I also did the same for the Amiga), and I
used a slightly modified VictorMaxx Stuntmaster for an HMD when it became
available.

I had fun playing the little game you made in this engine. I think its very
impressive (heck, you should throw it up on github). There used to be a thing
in the late 1990s and early 2000s of something called the "3D Engine List"
that listed all the 3D engines in various languages and whatnot (both open
source and commercial). Eventually, that all went away for one reason or
another. I kinda wish it still existed. When someone shares such work, it
always brings a smile to my face. So thank you for sharing your work with us!

~~~
badsectoracula
I actually had 3D Construction Kit and Freescape engine in mind when i made
this. I've heard of REND386 before, but i had forgotten about it until you
mentioned it. I never managed to use it though. I downloaded the code from the
site, but it seems to require a version of Borland C++ i do not have. I might
try to "port" it to BC5 at some point.

EDIT: i forgot. The 3D Engines List (i suspect you mean [1]) lives in
DevMaster's DevDb [2]. DevDb was originally just engines and IIRC its initial
data was from another database site "3dengines.net" from around 2004, which
itself sourced the 3D Engines List.

[1]
[http://web.archive.org/web/20060107015234if_/http://cg.cs.tu...](http://web.archive.org/web/20060107015234if_/http://cg.cs.tu-
berlin.de:80/~ki/engines.html)

[2] [http://devmaster.net/devdb](http://devmaster.net/devdb)

------
themadcreator
I'll also plug my own canvas rendering 3d library:
[http://seenjs.io/](http://seenjs.io/)

~~~
52-6F-62
This is seriously cool! Do you know if anybody has used your library
(especially SVG masking) in production?

You should pump that website up a bit and make sure to name drop people who
use it, though I appreciate your humility in that way.

Anyway, awesome work

------
mrspeaker
I wish there was some details around this! Recently I've been getting into
writing a software 3D renderer thanks to this fantastic set of tutorials:
[https://github.com/ssloy/tinyrenderer/wiki](https://github.com/ssloy/tinyrenderer/wiki).

Here's my creepy 3D rendering:
[http://mrspeaker.net/dev/head2/](http://mrspeaker.net/dev/head2/) It's not
using a real z-buffer (just canvas's path rendering for triangles, and sorted
back-to-front) but it's still pretty cool!

~~~
pjmlp
A very good book for graphics programming, covering all kinds of algorithms is

"Computer Graphics: Principles and Practice" from Foley and van Dam.

The 1st edition used Pascal, the 2dn C and now the third one uses C++ and C#
on their examples.

------
bbales
I did something similar to this
[https://github.com/bbales/Simple3DCanvas](https://github.com/bbales/Simple3DCanvas)

Its a great exercise, and I found that rendering basic .obj files was a great
place to start - the spec is quite easy to follow:
[https://en.wikipedia.org/wiki/Wavefront_.obj_file](https://en.wikipedia.org/wiki/Wavefront_.obj_file)

------
onion2k
three.js has a canvas renderer that doesn't require WebGL -
[https://threejs.org/examples/?q=canvas#canvas_materials](https://threejs.org/examples/?q=canvas#canvas_materials)

------
JasonSage
Worth mentioning that the page takes keyboard arrow input to move around.

Very smooth, thanks for sharing!

------
iverjo
A friend of mine once wrote a 3D effect in a 2D canvas in only 130 bytes of
JavaScript code:
[https://www.dwitter.net/d/914](https://www.dwitter.net/d/914)

------
cr0sh
I have to say, as simplistic as it is, I like this renderer. I am curious,
though why an orthographic projection (?) is being used, instead of a
perspective one? From the code, it looks like it could support a perspective
projection; I'm not sure if there is code in there to do it, or if you'd have
to add it in (it's been ages since I messed around with my own 3D software
engine stuff - and that was mostly in QB and VB)...

~~~
arnioxux
I didn't look at the code, but canvas only supports 3x3 transforms and you
need 4x4 to do perspective: [https://developer.mozilla.org/en-
US/docs/Web/API/CanvasRende...](https://developer.mozilla.org/en-
US/docs/Web/API/CanvasRenderingContext2D/transform)

So if those cubes are textured, you'd need to subdivide the texture and
approximate each with affine transforms. Here's an example of this hack (which
was only necessary years ago before webgl existed):
[https://acko.net/blog/projective-texturing-with-
canvas/](https://acko.net/blog/projective-texturing-with-canvas/)

~~~
Matheus28
For wireframe objects like the one in the OP (which actually does use a
perspective projection it seems), that's not really a problem. Just have your
own code that does all the matrix multiplication, and you get a point you can
plug right into moveTo/lineTo

------
kosua20
Shameless plug for my own attempt at writing a software renderer in swift...
[https://github.com/kosua20/PtahRenderer](https://github.com/kosua20/PtahRenderer)

The readme lists a few useful resources; in my opinion the most difficult part
was implementing clipping.

------
donatj
I have been working on this thing on and off for six+ years, I know almost
nothing about graphics so this has just been a fun little exploration for my
and probably nothing to base anything on:

[https://github.com/donatj/3D-Package-
JS](https://github.com/donatj/3D-Package-JS)

~~~
vivekseth
One of the other commenters mentioned this:
[https://github.com/ssloy/tinyrenderer/wiki](https://github.com/ssloy/tinyrenderer/wiki)

If you’re interested in learning graphics, this is a great place to start!

------
catshirt
maybe i'm a little crazy (doesn't get much more generic than 3d cubes...) but
the demo visualization brought me back to 3d animation in Flash. interesting
peek/reminder of how our tooling contributes to our outputs. (or maybe i'm
just crazy).

awesome work!

------
fogleman
Here's my software renderer...
[https://github.com/fogleman/fauxgl](https://github.com/fogleman/fauxgl) :)

------
pedalpete
Can somebody please comment on why using a 2d canvas is a better solution than
webgl? Or is it?

I was under the impression that to get the best GPU performance, webgl is the
answer.

~~~
vivekseth
From a performance standpoint it’s definitely not better. I just built this
for fun.

