-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
WebGLRenderer: Support more than 8 morph targets. #22293
Conversation
Right now the new texture based implementation is always used with a WebGL2 context, Since at least on one system a problem with texture arrays was detected, it's probably more safe to: a) only use the new code path when a geometry holds more than eight morph targets. I favor option a) so far. |
Actually that is not a good idea. While implementing it I've realized that not the number of the geometry's morph targets is important but the number of active influences. However, it's not possible to compute this number just once. You have to do this per frame and thus switch between attributes and data textures if necessary. To simplify things it's probably better to use a flag for enabling the new code path or use the data texture approach by default with WebGL 2. |
If the cost is minimal why not always use the data textures. This is what babylon.js is doing. Any disadvantage of doing so ? |
This approach did not work on at least one system ( On the other hand this might be an issue only one a single system. It's hard to tell. I vote for a safe approach: Using it by default but allowing to disable the code path with a flag. |
makes sense |
07077a6
to
2457ea7
Compare
Updated the PR with the flag approach. If the new parameter |
@Mugen87 Do you get artifacts with babylon.js too? 🤔 |
No, it works fine there 😮 . It seems babylon.js generates the texture array differently. The sampling in the shader is also different. Notice that the initial commit of the PR did not show any artifacts. They were introduced with this commit a9f5cdc which avoided POT textures. I don't know yet why a NPOT texture breaks the sampling on my iMac. |
Using the babylon.js approach for computing the texture size fixed the bug on my iMac 🎉 . |
IMO, such user-set parameters are not appropriate. It is not the user's responsibility to specify -- or understand -- such implementation details. Given your success, I assume that parameter can be removed. Right? |
Yes, I wanted to suggest that after testing on some more devices. I'll update the PR soon with something that can be merged. |
Love the new screenshot for |
omg |
Not sure what's happening to |
Puppeteer has a smaller max texture size than my desktop and notebook. That revealed an error with the MMD asset. After fixing the texture sampling, things should work now as expected. Sorry for disintegrating Miku 😇 . |
I guess this PR is good to go now! |
I tested these updates with the model which has a lot of shapes and it doesn't work. Only 8 shapes can be applied at the same time on one mesh as it was before. Do I need to pass some additional parameters? |
Do you mind sharing the model in this thread? You can also test with the following example that more than eight morph targets can be applied now: https://threejs.org/examples/webgl_loader_mmd_pose. Just use the example code with the engine changes from the PR.
Nope. The new code is used by default assuming a WebGL 2 rendering context is available. |
Yes, it works! So what I was doing wrong is installing three.js as npm package likes this: |
@yaroslavnikiforov Thanks for testing! |
Hi @Mugen87! This works only with webgl2 right? Is there a way to enable the new code path with webgl1 as well? |
Correct!
No. The code relies on WebGL 2. |
In order to mae this work in WebGL 1 we would need to use a long DataTexture and do the "paging" in the shader, right? If so, do you know how big the texture would need to be? I'm on a Pixelbook Go right now and the max texture size is 16384. |
Besides, WebGL 1 does not have Considering these limitations, I think it's better to just support WebGL 2. |
Sounds good! 👍 |
Thanks! |
Awesome work guys! Is someone going to add a demo showing of this new capabilities? |
The Miku asset in https://threejs.org/examples/webgl_loader_mmd_pose already allows to configure more than 8 active morph targets (which is good for testing). However I was hoping to find a new asset with a complex facial animation clip but with no luck so far. |
Here's a model with an animation that has ~50 active morph targets, created using the iPhone Face Cap app. You can see it in action here (this is animated on the CPU). I reached out to the creator of the app, Niels Jansson, and he says it's fine to use the model as long as it's credited. |
I like this model especially since you can clearly see that it is not correctly animated with @looeee Are you interested in making a new example with this asset? Maybe |
Yeah sure, I'll do it tomorrow. |
The md2 example seems to be glitchy now. @Mugen87 any ideas? Screen.Recording.2021-09-22.at.10.15.03.PM.mov |
Found the issue. The alpha values were not set correctly for the RGBA texture. I'll file a PR 👍 . |
* WebGLRenderer: Support more than 8 morph targets. * WebGLProgram: Use mediump for sampler2DArray.
I've created a new issue related to this issue. tldr it sometimes uses gigantic amount of memory which have not seen in r132 |
Related issue: Fixed #21636.
Description
This PR adds support for using more than 8 morph targets/blend shapes.
The implementation utilizes
DataTexture2DArray
to encode each morph target into a separate layer of a texture array. This is more scalable than using just a single large texture however it requires WebGL 2. If no WebGL 2 is available, the previous code path is used.