Hacker News new | past | comments | ask | show | jobs | submit login
Here be dragons: the same 3D scene implemented with 10 different 3D APIs (github.com/kosua20)
574 points by adamnemecek on July 25, 2017 | hide | past | favorite | 60 comments

This is a really useful codebase to compare what the code looks like for different APIs and the tooling around each (not so much for directly comparing the graphics, which should go without saying, but a lot of people seem to be missing the point here...)

It would be interesting to add an emscripten version, ie. slight modifications to the original C++/OpenGL code to make it compile with emscripten and run in the browser. After some fooling around I got that to work, however nothing shows up because the shaders need to be rewritten for WebGL. Looks like this was already done for the JS/WebGL version, but the shaders are less fancy and clearly don't map 1-to-1 to those in the C++/OpenGL version, so the code will need to be modified a bit either way.

If you target WebGL2 you can likely do it without hand modifying the shaders. In a small test I did I just patched the emscripten library_gl.js to do a very simple search and replace of the version string of shaders and stuff just worked.

code: https://github.com/greggman/doodles/tree/master/glfw-imgui

demo: https://greggman.github.io/doodles/glfw-imgui/out/glfw-imgui...

You do have to decide if you want to restructure you code to be event based or if you want it leave it as is and set emscripten to generate really slow code for your main loop


very cool to see ImGui used in webgl!

I think ImGui is amazing but just be aware it's non-English hostile (arabic? thai?).

It can display other languages but uses a static font glpyh texture instead of using a font cache (there are too many characters to use a static texture).

It can't take input from an IME so no CJK input or other IME languages.

Very interesting. What's striking is how much better the OpenGL version looks than everything else. Not sure if it's because that was the reference version or if some of the other APIs require more work or the dev is simply unfamiliar with them. The Cycles renderer creates some really cool looking materials on the dragon, but the terrain doesn't look great.

The Metal version in particular looks terrible, but then again low level APIs like Metal, Vulkan and whatever subset of Direct X are all meant for vendors, not individual developers.

Theoretically, the OpenGL, WebGL, Vulkan, Metal, and Unity implementations can all have comparable quality with enough dev work. From a quick glance through the README, it doesn't seem like the OpenGL implementation is relying on any cutting-edge features of the specification, so everything can be ported to WebGL as well. If anything, the Vulkan and Metal versions have higher "potential" when compared to older APIs like OpenGL because if you optimize with the lower level primitives, you'll have more cycles for complex rendering techniques. Also, I'd argue that Vulkan can be used by individual developers because there are already a bunch of games that have Vulkan support: https://en.wikipedia.org/wiki/List_of_games_with_Vulkan_supp...

Actually, if continue under this world with unlimited developer resources, the Cycles version should look the most realistic. It's markedly different than any of the other renderers included in this list because it's an offline path tracer whereas Unity and friends are for real-time rendering. We rely on a lot of hacks (Phong shading, FXAA, normal mapping) to produce an interactive 3D scene at 30+ FPS, but once you remove the real-time constraint, we can apply a lot of very fancy algorithms to more realistically render your scene. Cycles might take minutes or even hours to render a single frame, but it spends this time on a whole host of involved computation (physically-based BSDFs, Monte Carlo integration, Metropolis light transport, etc) that more accurately model how light interacts with materials.

OpenGL has a ton of implicit state. This makes the code look simple, but it's actually very hard to work with, as you always have to be aware of what the current state is. Other APIs are require explicit handling of state (Vulkan takes this to an extreme) which is more verbose, but actually easier to work with.

> the terrain

The OpenGL version looks really aggressively bump mapped. The Cycle's version doesn't appear to have any bump mapping enabled.

Edit: The depth of field in the Cycle's version also looks a bit weird, and blurs away most of the terrain's detail.

The OpenGL version is using parallax mapping, where the pixels of the flat plane are rendered by ray-marching into a depth map:


The cycles version, on the other hand, is actually using the depth map to displace a high-res mesh -- a more general technique that should yield results as good or better than parallax mapping. I'd chalk up any perceived differences to lighting and material parameters.

> Not sure if it's because that was the reference version or if some of the other APIs require more work or the dev is simply unfamiliar with them.

I would say the later, either unfamiliarity with the hardware/software or time constraints because the PS2 is capable of much better than what is shown here.

Do you think it's better than Unity's codeless solution?

Unity has a rendering pipeline coded for you, using DirectX or OpenGL, depending on platform and settings.

Isn't the point of this repo to compare the usability of different developer tools?

Not really. The Readme says this:

"This repository contains multiple implementations of the same 3D scene, using different APIs and frameworks on various platforms. The goal is to provide a comparison between multiple rendering methods. This is inherently biased due to the variety of algorithms used and available CPU/GPU configurations, but can hopefully still provide interesting insights on 3D rendering."

It's a mixed bag of APIs, software, hardware and tools, approaching the rendering in very different ways. There's even an offline renderer (Blender Cycles) and a software real time renderer in the repo.

> The goal is to provide a comparison between multiple rendering methods.

Well, isn't usability the most important criteria to compare it on?

No, one of these methods takes seconds to minutes for a frame to render. One takes a lot of CPU and a bunch are letting the GPU doing the work. Not to mention that a few examples run och very specific hardware only (PS2, GBA etc).

It seems like they actually

I someone has time, could you record each one of these, splice the videos together and upload it, so we can compare them, without actually installing each one?

There are static images available in the README in each subdirectory. Not as good as video of course, but still gives a decent sense of the quality of each implementation.

There are screenshots in each of the directories in the project.

Laziness squared... got it.

(lazy they didnt have a gallery already ready... lazy that (we) the readers dont ant to click through to each pic..

Some people went and created the same in multiple different languages/environments. Not sure you should be throwing around the word lazy.

Not to accuse anyone of laziness, but on mobile the UI is clearly not optimized to see the comparisons, assuming that wandering the directories is the intended method.

The Vulkan version will really add a lot I think. I would guess most people are most interested in an OpenGL to Vulkan comparison. Similarly (possibly more interesting to people, I don't know?) the DirectX version.

Nice comparison.

Shouldn't it be fairly similar to the Metal version, which is basically Apple's Vulkan/Dx12? (IIRC Metal is more between OGL and Vulkan, it does more hand-holding and implicit than Vulkan, but way less than OGL)

Yeah, more or less, but a project this size (small) would really bear those differences out, I think.

In particular, resource binding is very different between Metal and Vulkan. Metal's resource binding is more simple/traditional. Vulkans is... sensible, but substantially more complex.

Caveat: haven't used either professionally, read the code in the repo, or had my morning coffee. I've also never touched Dx12, but I've heard it basically works the same as Vulkan here.

Will it? Vulkan is meant as a low-level version of OpenGL for vendors who want to optimise their engines and have more control over draw calls and whatnot. Does it actually add any features that will be noticeable in a small, static scene?

The difference between a moving and a static scene is surprisingly small: in one case you render a slightly different scene every frame, and in the other you re-render the same scene every frame. But the pipeline is set up the same, with the same shaders, the same rendering passes, etc.

So, in practice, if they are noticeably different in the dynamic case, you'll see those differences in the "as if it were dynamic" case, which is most graphics demos of this sort.

No, but quite a few people who are familiar with OpenGL are interested in learning Vulkan, and it's really educational to have a side-by-side comparison of the same scene.

Visually, no - it should look the same. For comparison of the code, it will be interesting, even if it doesn't necessarily show everything you can do with Vulkan and DirectX (which has some similar low-level features in recent/latest? version).

Neat. Always interesting to be reminded how far the capabilities have come in so short a time. The PS2 really wasn't all that long ago in the grand scheme of things.

Would be intriguing to see how far older architectures like ps2dev can be pushed on modern hardware.

Or even how far the PS2 could be pushed with modern software. Just look at the C64 demoscene, that machine is doing things it's designers could never have hoped for.

I am not an expert in some of these, but I CAN tell you that both GBA and DS can do much better than the author has done here.

The PS2 is, by far, done the worst disservice in this repo.

The GBA could definitely do a real 3D engine but it wouldn't look very good at the low resolution anyway. I remember a demo from back in the day of a Quake-like 3D engine on the GBA but it really didn't look good.

For the DS, note that he seems to be targeting the original DS (e.g. not DSi OR 3DS). I remember there being some slightly better stuff but not significantly better than what he made.

I just ran the DS version on my DS lite, it looks pretty good - definitely comparable to games on the system, and the models seems more detailed then most of what you see on the system. The screenshots just make it look horrible because it's a fairly low-res screen, when you blow it up that big it looks a lot worse then you'd expect. The monkey shadow is definitely iffy looking, but I don't think any games ever did 3D shadows that detailed - there's probably a reason for that. It is worth keeping in mind that the original DS is weak (especial 3D wise), but it's not really that bad considering the low resolution it has to render for. That low resolution is the main reason why it looks so bad in the screenshot though.

The GBA version also looks pretty good on my DS lite (compared to games on the system). You can't rotate the camera though, so the dragon doesn't rotate. The monkey-head rotates on it's own though and looks pretty good. You're right that there are a few games that do 3D on the GBA, but I can't imagine it's fun coding wise since it the hardware support is basically zero in that regard. But there are some weird ones out there - Banjo Pilot comes to mind, which is a weird mode-7 3Dish flying game. Not exactly a great game, but pretty cool to see. Even with that game though, they have to sacrifice basically all terrain to be able to render the other characters at a decent speed IIRC, so the entire game is just flat.

And if you want to get really obscure, there is Faceball 2000 on the GB, which is a "FPS" and is 3D (And runs at like 15 FPS IIRC). There's no way you could render this scene on it though besides just pre-rendered sprites like was done with the GBA.

There's also a high-res DS render from an emulator here: http://i.imgur.com/d52hfEr.png

part of this album http://imgur.com/a/XQCEJ

It looks much worse than my imagination accredited for - but Metroid Prime Hunters was a beautiful DS game:



Artistically, yes, but I don't think the DS can pump out much more in terms of raw polygonal and texture load.

Definitely looks helpful as someone starting to get into Graphics Programming, but I can't wait for the Vulkan version!

A nice project, but I didn't find the license for the source code. As without one no-one can really legally use parts of it for anything that can become serious.

Of course it might be that I have missed it or it is hidden somewhere. I hope it really exists somewhere in the repository, but I didn't find it. I might be too tired to find it and someone else has better luck.

After a quick search, there is no license file in this project. Whether that was done intentionally or unintentionally has yet to be determined.

It's worth noting that the author just added a license (MIT) to the repo.

I would be interested in seeing a version of this, where a pixel-identical scene is created using different toolkits.

Why is one of the examples called "Unity"? Doesn't Unity just use the lower level rendering APIs or am I missing something?[1][2][3]

[1] https://docs.unity3d.com/Manual/UsingDX11GL3Features.html

[2] https://blogs.unity3d.com/2016/09/29/introducing-the-vulkan-...

[3] https://blogs.unity3d.com/2015/02/19/unity-4-6-3-metal-rende...

WebGL is ultimately translated into OpenGL calls. OpenGL calls are ultimately translated into bytes sent over the bus to the graphics card. It takes a lot of level descending before you reach the ground floor :-)

Unity is there, I imagine, because it's interesting to see how it translates code that expresses high level concepts like "meshes" and "materials" into code for to the backend, compared to the hand-written OpenGL or DX or Metal or whatever calls.

How do I view them? Maybe it's because I'm on mobile, but I'm having trouble navigating to the actual images.

Edit: ok if I understand correctly, you need to visit the linked web site, visit each linked repo, and pull each one down? Could you provide a web page with previews, or would the resolution lose all visual differences?

I just clicked on each directory, the images are linked to the READMEs.

If you just want to check out a couple static images, check out the author's site [0].

I must be getting into my nostalgic period - I love the GBA version.

[0]: http://simonrodriguez.fr/dragon/

It would have been cool if there was a single page with a screenshot of each version to compare

How about a pico-8 version?

It seems it's in the works: http://simonrodriguez.fr/dragon/

Would love to see how Glide stands up against this.

No POVRay?

When I was in school, I had an assignment to make the same super simple scene in OpenGL and DirectX.

That was when I learned I didn't want to be in a career field that would have me using DirectX.

Would you mind explaining in more detail why you didn't like using DirectX? When I was reading up for some games if they would get an OpenGL version, I was reading more than once that OpenGL were a mess.

It was a really simple project, like a couple of colored rotating triangles. I think it was like... maybe 10 short lines of code for OpenGL, and over 50 to do it with DirectX.

Of course, I can't speak for how hairy OpenGL might get at doing more advanced features, and of course, in a lot of cases games are built on established game engines which do most of the DirectX and/or OpenGL coding for them.

You've hit the nerve there.

OpenGL has so much implicit state and "defaults" set for you that you can get a "hello world" -style app done really quickly, but then it all falls apart.

And if I'm guessing correctly, you probably used legacy, fixed function OpenGL (ie. no shaders) with immediate mode rendering (glBegin/glEnd). Because you can't do anything in 10 lines with modern OpenGL.

As soon as you start doing something practical, you start fighting OpenGL all the time. It's a badly designed, very error prone API that requires much more developer effort than any of the competing APIs.

If you apply best practices to OpenGL code (don't rely on global, implicit state, use shaders/buffers/etc) , it's about on par with the "lower level" APIs.

My OpenGL boilerplate code and my Vulkan boilerplate code have about the same number of lines of code in them while they do about the same things (create rendertarget, framebuffer, clear the screen, draw some text, draw a triangle, blit to screen, measure performance counters). OpenGL is a bit less by a small margin, but the difference is only in the verbosity of Vulkan code (ie. you have to explicitly type every single pipeline state, even if it doesn't matter, e.g. depth test mode when depth test is disabled).

In my opinion the bottom line is this: Vulkan is verbose but OpenGL is complex. I'll take verbosity over hidden complexity any time.


You've got something wrong with your server...

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact