Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting a minimalist OpenSubDiv to JavaScript? #247

Closed
bhouston opened this issue Dec 19, 2013 · 11 comments
Closed

Porting a minimalist OpenSubDiv to JavaScript? #247

bhouston opened this issue Dec 19, 2013 · 11 comments
Assignees

Comments

@bhouston
Copy link

I would like to support OpenSubDiv in our web-based 3D modelling package http://clara.io We already have Catmull-Clark subdivision support but it isn't anywhere near the full set ( https://www.youtube.com/watch?v=Bn8bnE-tlyA ).

To fully support all the features of OpenSubDiv, I would like to have a JavaScript implementation of OpenSubDiv.

I did some Google searches and so far no one seems to have ported OpenSubDiv to JavaScript, or at least I couldn't find anything.

What is the minimal about of code that would need to be ported to JavaScript to have compatibility? Should one port the C++ core or try to port the shader code to WebGL GLSL? Or has any one tried emScripten (the C++ to JavaScript compiler) on OpenSubDiv?

Does this (getting OpenSubDiv in JavaScript) interest anyone else?

PS. Thanks for making this public, this is an awesome contribution to the community. Hopefully we can contribute a bit to it. :)

@bhouston
Copy link
Author

I did just notice this, but I am not sure what to make of it:

https://github.com/takahito-tejima/webgl/tree/master/opensubdiv

@takahito-tejima
Copy link
Contributor

Hi Ben, thank you for your interest in OpenSubdiv!
I know your awesome webgl 3d tool, and it would be great if it supports full feature catmark surface using OpenSubdiv. exciting.
My webgl code is just a proof of concept based on an early version of OpenSubdiv (not sure it still works), and it's actually not a JavaScript implementation at all. It takes serialized subdivision tables (generated by off-line tool) and applies them in GLSL(webgl context) in manner of old-school GPGPU then draws refined triangles.

I think porting OpenSubdiv to Javascript/WebGL environment can be split into two big chunks of work. (assuming only uniform subdivision will be used for this purpose. You don't need to port adaptive tess shader code unless doing something beyond my imagination).

  1. subdivision table generation in JS from arbitrary topology structure (Hbr / FarMeshFactory).
  2. compute kernels (osd/cpuKernel) in JS or GLSL

My prototype only covers 2, and there are a lot of questions how to get 1. If the application is kind of animation playback tool (including game), step 1 can be performed on server-side or at build time because subdivision tables only depend on topology, which is relatively fixed. But for the modeling applications like yours, it wouldn't work. I'm not sure how emScripten like solution can be applied here, but it definitely sounds an interesting approach.

There hasn't been a public port of OpenSubdiv into JavaScript, as far as I know. And yes I'm very interested in!

@ghost ghost assigned takahito-tejima Dec 19, 2013
@jcowles
Copy link
Contributor

jcowles commented Dec 19, 2013

I think I nearly have an OpenSubdiv emscripten build working: I have
hbr_baseline running in node.js and I have simpleCpu
compiling/running/crashing in the browser. Then I hit a wall with the
extremely limited glew stub in emscripten.

This pull request to emulate glew looks promising (
emscripten-core/emscripten#1878) and I hope to patch my
local emscripten environment in the next day or two and see how that goes.

Once the simpleCpu example runs (and I will likely hit more snags once I
get past glew), we would need to sanitize my build -- I'm doing some nasty
stuff right now to get it to compile. Then we would need to expose a
wrapper-API for javascript clients to call.

I suspect it will also be super slow, being single threaded, but perhaps
web workers would be a viable option to speed things up.

So, still quite a bit to do, but it seems within reach.

Jeremy

@bhouston
Copy link
Author

@takahito-tejima Interesting. Thanks for the explanation. I think we are most interested in a CPU-only implementation that we can just optimize (likely via web workers as @jcowles suggests.)

@jcowles Of course you are working on an enScripten build already. heh. How large is the enScripten build for simpleCPU even if it is crashing? I am always concerned about the size of enScripten results. In know that the Unreal Engine 3 demo was more than 23MB of enScriptened produced JavaScript, which is a pretty scary size.

Also, I am confused as to why glew is required for the CPU-only implementation. No possibility to comment out the GPU stuff completely? I'd just limit it to the CPU implementation and then save out a result to an OBJ and drag and drop it into Clara.io or the ThreeJS editor and see if it loads. I wouldn't even worry about display parts to start or porting the viewer, unless it was no work.

We might be able to help with a wrapper-API in January if you wanted to share in a PR or something like that.

@jcowles
Copy link
Contributor

jcowles commented Dec 19, 2013

On Thu, Dec 19, 2013 at 8:16 AM, Ben Houston [email protected]:

@takahito-tejima https://github.com/takahito-tejima Interesting. Thanks
for the explanation. I think we are most interested in a CPU-only
implementation that we can just optimize (likely via web workers as
@jcowles https://github.com/jcowles suggests.)

@jcowles https://github.com/jcowles Of course you are working on an
enScripten build already. heh. How large is the enScripten build for
simpleCPU even if it is crashing? I am always concerned about the size of
enScripten results. In know that the Unreal Engine 3 demo was more than
23MB of enScriptened produced JavaScript, which is a pretty scary size.

It's 4MB (700k gzipped) for a debug build and I'm not sure if that's
running through Closure or not. I think we can get that down.

Also, I am confused as to why glew is required for the CPU-only
implementation. No possibility to comment out the GPU stuff completely?

I disabled GPU & OpenGL 4+ support (via CMake), but my thinking is that
glew is "required" by OpenSubdiv, so removing the glew calls is cheating :)

Build hackery is fine, but I want to make as few source code changes as
possible.

I'd just limit it to the CPU implementation and then save out a result to

an OBJ and drag and drop it into Clara.io or the ThreeJS editor and see if
it loads. I wouldn't even worry about display parts to start or porting the
viewer, unless it was no work.

Yeah, I could construct an easier test, but want to see simpleCpu work...
maybe I'm just being stubborn.

We might be able to help with a wrapper-API in January if you wanted to
share in a PR or something like that.

That would be awesome. Also, I think helping out with the web worker
integration would be a huge contribution.

My time to work on this is super limited, so help would be great.

Jeremy

@bhouston
Copy link
Author

I had a look through the code and GLEW is only used if you want to run the viewer. :) I think few people want a non ThreeJS viewer these days, so I wouldn't spend too much time on it. Need to just save out as an OBJ. :)

@bhouston
Copy link
Author

ThreeJS is crazy easy to use for simple interactive viewers. One could modify one of these examples and just convert to the standard ThreeJS mesh / line format for viewing:

http://threejs.org/examples/#webgl_geometry_large_mesh

@jcowles
Copy link
Contributor

jcowles commented Dec 19, 2013

I agree (and I love three.js), but to run a three.js viewer right now, I would also need the OpenSubdiv binding/wrapper to JavaScript, so it's actually easier to just get simpleCpu demo working.

But yeah, the glew issue is secondary, I'll put it aside for the time being.

@jcowles
Copy link
Contributor

jcowles commented Dec 21, 2013

So I ended up going the minimal route and making a javascript binding that just takes an OBJ string, something like this:

var subdiv = OsdUtil.GetSubdiv(objString, refinementLevel)

and it works! I'll try to put something together that I can share over the break.

@jcowles
Copy link
Contributor

jcowles commented Dec 22, 2013

This pull request has the basic build support, but does not include the JavaScript bindings (which are still IP):
#250

@manuelk
Copy link

manuelk commented Apr 9, 2014

Duplicate of #250

Closing for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants