Hacker News new | past | comments | ask | show | jobs | submit login
WebGL Tutorial: Rendering Wavefront 3D Models (chinedufn.com)
44 points by chinedufn on Dec 11, 2016 | hide | past | favorite | 17 comments

"Right now we have an f16-model.obj file. This file is a text file that contains data about our model’s vertices. In order to make use of this data, we parse it into more readily accessible structure and store it as JSON."

Wait what? This is completely redundant and will negatively impact performance and memory.

Hey thanks for pointing this out since I admittedly hadn't even really considered using anything other than JSON here.

It turns out that the files are roughly the same size since the parser just shuffles the data around to make it easier to pass to your uniforms later.

`f16-model.obj` -> 396.9 kB (396947 bytes)

`f16-model.json` -> 397.5 kB (397534 bytes)

Using pre-parsed `JSON` here helps you avoid needing to parse your `.obj` file during runtime. Plus, since JS runtimes are heavily optomized for JSON, this seemed like a good starting place.

Super open to better alternatives of course!

WebGL doesn't really understand "file formats", so you're left to load the file into a buffer yourself. JSON is a reasonable way to do that.

Once you hand off the vertices to the WebGL context, it's all the same bits; your file loading strategy has no performance or memory impact.

But a .json file surely will be 2x or even 3x as big as the .obj file, because of all the extra fluff the format adds. What is wrong with parsing an obj file, and building up your vertex and index buffer straight away? Parsing a .json file would also be like twice as slow. I'm not versed in WebGL but if you have to have .json in the middle of everything that seems like a really dumb decision by the designers, especially for the web.

Ordinarily I would agree with you except for what .json is: a JavaScript Object. Or, more correctly, its serialized-to-text form. Parsing it is a matter of invoking an extremely common function built into every JavaScript implementation in every browser, and likely optimized to death.

This is one of those weird cases where, despite obj being a simpler format on paper, it would likely be slower to parse due to having to hand-roll the parser in JavaScript and not use the browser's native built-in parser instead.

Yeah, but you still have to parse the .obj. What the article is doing is .obj -> .json -> WebGL arrays. There isn't really any reason to put the .json intermediary in the middle. Especially since you will only treat it as a blackbox to pass around.

JSON is nice as a hand-editable text format. It isn't designed to be fast to parse, or to produce small files.

Given that .OBJ is largely a text file which contains a vertex list and an element list. It seems like it would make more sense to store it as a binary in the format which is sent to the GL driver, especially given that WebGL requires typed array buffers anyhow. Just need the offset, extent, type, and number of axes of each buffer.

Sadly glTF is JSON, and not typed array buffers (as far as I can tell). I was going to mention it, but it seems like in terms of performance almost anything can be as good or better than glTF.

This is especially true for .obj -- that format is dead easy to parse.

They do need to parse the .obj and have the result in JS. And, this being JS, the parse result is a JS object. If they actually serialized to JSON (as, in text) in memory, that would be dumb.

Granted, you could say they could reduce total memory usage by not parsing it all at the same time or something, but one way or another, you'll have to parse it into JS.

Yeah that makes absolutely no sense. Either way they need to parse the obj, but then why convert the same data to a less efficient format for that data type that can now no longer be used directly by another application?

Sounds like they just liked json

obj is pretty inefficient, so depending on how it's stored in JSON I'd guess there's probably not much difference in terms of performance or size. At least now when accessing the model from Javascript in a browser.

If you're already familiar with Javascript, and you want to learn WebGL, I recommend just diving into THREE.js instead.

The problem with this tutorial is that almost all of it is hidden behind an opaque "loadWFObj", so you don't get the critical aha moments of "wait so the model is just a bunch of 3d triplets?", "whoa every camera is just a 4x4 matrix you multiply by", and "shaders are a C program that runs on a pixel".

I promise you'll pick up all of these things naturally by fiddling around with THREE.js. But, you probably won't get there by copying a WebGL context initialization example that does everything interesting inside an opaque library.

THREE.js is awesome but it is not WebGL. It's a 3D Library that happens to use WebGL (and can use other backends as well).

If you want to learn WebGL itself try http://webglfundamentals.org

If you just want to get 3D on your page without having to learn WebGL use THREE.js

Great points, along with greggman's http://webglfundamentals.org I'd also recommend http://http://learningwebgl.com/blog/?page_id=1217


So I'm fond of the idea of being able to quickly get up and running with small modules, hence me working on things like this. Totally hear and agree with you on most of the WebGL being "hidden" here.

I hope to work on more tutorials that dive into how the sausage is made, but for now you can look at the implementation on GitHub -> https://github.com/chinedufn/load-wavefront-obj

This might be useful for people who want to get started with WebGL and web-based 3D engines:

https://playcanvas.com/ http://babylonjs.com/ https://threejs.org/ https://github.com/GooTechnologies/goojs https://whsjs.io/#/

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