-
-
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
Nodes: Add VelocityNode
and MotionBlurNode
.
#29058
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
For some reason |
FWIW, I am getting something reasonable by making these two changes: webgpu_mrt.html: comment out the background texture. Otherwise, the model always shows zero velocity. scene.background = texture;
//scene.background = texture; VelocityNode.js: amplify the velocity //let velocity = sub( ndcPositionCurrent, ndcPositionPrevious ).mul( 0.5 );
let velocity = sub( ndcPositionCurrent, ndcPositionPrevious ).mul( 100 ); |
This was also responsible for no velocity when panning the camera. I have updated the example by retaining the background but using selective velocity. So the default value for the scene and thus the background is "no velocity". Objects that should receive a motion blur like the helmet write motion vectors. This setup is required for per-object motion blur anyway. When adding an example for per-object motion blur, I'll revert the changes in |
I've added One open issue is motion blur with animated models. In-place animations do not change the world position of the model so without further enhancements it would not be possible to detect velocity changes with |
VelocityNode
.VelocityNode
and MotionBlurNode
.
It seems that if we have the |
That sounds good!
If we have a separate export for |
I think interessing we have support for alternating textures through an API, I'll try to create something along those lines. |
It's work :), will test now with skinning |
It's impressive how the amount of code was reduced with this new approach 😳. |
It seems the motion blur effect does not work with animated models, yet. I'm also not sure if the current setup is appropriate for per-object motion blur. The entire scene is effected but sometimes you want to only specific objects have a motion blur or with different intensity. |
TBH, I found the previous setup a bit more natural. Meaning you configure a velocity output via MRT and then assign the color and velocity node to the motion blur pass. It would be nice if we could hide the "previous data" step somehow in |
I had noticed some problems, then I don't merge this, it seems that the problem now is that we are comparing the NDC position, but it is the difference between the matrices that makes the NDC position calculation correct, perhaps storing the matrix values in MRT texture should solve it. |
If we just store the matrices, it seems we need a special solution for skinned meshes again, correct? In this case, I would suggest to revert to the original version which provided the previous world matrix as a uniform. If skinning is used, the previous bone matrices can be shared as a uniform as well. I was not able to finish this bit but I guess it's worth giving it a shot. |
The idea is provide an automated solution for this. I think skinned would be just one of many other implementations that should be done like morph, instances, batch and custom positionNode with the previous approach. If MRT works it would still be the best path in terms of performance and maintenance, but if it doesn't work I'll revert it. I may need a few more days to test these ideas 😇 |
No need to rush^^! We should take our time with this topic and explore the different options. |
@Mugen87 From what I understand, the comparison is made using MVP and then converted to NDC by dividing by w. The approach I took stores the const scenePass = pass( scene, camera );
const positionPrevious = scenePass.getPreviousTextureNode( 'position' );
scenePass.setMRT( mrt( {
output,
position: positionLocal,
velocity: velocity( positionPrevious.uv( viewportTopLeft ) ).xy
} ) );
const beauty = scenePass.getTextureNode();
const vel = scenePass.getTextureNode( 'velocity' ).mul( blurAmount );
const mBlur = motionBlur( beauty, vel ); |
This reverts commit 5b39722.
Sounds fine! The implementation is definitely a good start. |
This reverts commit 213bf02.
I had to go back closer to where it was, the approach wouldn't work for skinned since I couldn't access exactly the previous pixel (at least not easily), so in order not to extend this feature too much I decided to go back. Anyway I'm happy with the tests, there were some important corrections and improvements made. @Mugen87 Thanks for the initiative, there are so many recent improvements, I've had problems before with |
Also thanks to @gkjohnson! #14510 was a good starting point. Glad to see the implementation finally landed in this repo. |
Related issue: -
Description
The PR ports VelocityShader to
WebGPURenderer
. The logic for producing velocity vectors can be moved into a single new moduleVelocityNode
.The ability for accessing motion vectors is important for stuff like motion blur or TRAA. Original PR #23784.
MotionBlurNode
is based on #14510.