three.js icon indicating copy to clipboard operation
three.js copied to clipboard

MeshVelocityMaterial: render a scene's velocity field to a buffer (useful for motion blur, TRAA post effects)

Open bhouston opened this issue 3 years ago • 3 comments

Related issue: #14050

Description

This adds a MeshVelocityMaterial to Three.js in the spirit of MeshNormalMaterial and MeshDepthMaterial. This enables one to render meshes into a velocity field buffer. This is useful for a number of advanced post effects including Motion Blur and Temporal Reprojection Anti-Aliasing.

This implementation only supports a few different methods of inducing velocity in the scene. Here is what it supports and what it doesn't:

  • camera movement changes - SUPPORTED.
  • node movement changes - SUPPORTED.
  • skinning changes - NOT SUPPORTED.
  • blend shape changes - NOT SUPPORTED.
  • displacement changes - NOT SUPPORTED.

I have added a "velocity" mode to the channel example to show this off.

This is what it looks like:

https://user-images.githubusercontent.com/588541/160016755-0b2b6f5e-ff99-4c08-b944-d6f9f85f7563.mp4

I have separated out this MeshVelocityMaterial into its own PR so that people can give feedback on this design in isolation rather than combining it with TRAA in general or a Motion Blur post effect.

This contribution is funded by Threekit.

bhouston avatar Mar 24 '22 21:03 bhouston

Setting material.needsUpdate = true; is not necessary when changing material.side.

However, toggling between BasicDepthPacking and RGBADepthPacking does not update the material.

EDiT: It appears the renderer treats parameters.depthPacking as a boolean, and it is not.

WestLangley avatar Mar 25 '22 14:03 WestLangley

I believe I have cleaned up this PR so that it meets the various suggestions made in its review. Let me know what else I should do.

I would like next to contribute a TRAA method that uses this material.

bhouston avatar Mar 31 '22 19:03 bhouston

There is an upcoming WebXR proposal, to allow fewer frames to be rendered, called space warp being lead by @cabanier this would be required for that to work https://twitter.com/rcabanier/status/1537210613318811648

AdaRoseCannon avatar Jun 16 '22 12:06 AdaRoseCannon

@bhouston I've updated the PR to remove the merge conflicts and to honor the remaining feedback. Just one question: Is it normal when the rendered velocity sometimes affects only parts of the mesh? This is a screenshot from the front:

image

I can see this behavior before my latest commits, too.

Mugen87 avatar Oct 22 '22 10:10 Mugen87

If parts of the mesh are not moving left or right, then yes, they will not have colors.

bhouston avatar Oct 25 '22 02:10 bhouston

Let's merge this! Having a velocity material in the examples is really useful. When the material is going be used in more and more components (like WebXR), we can still move MeshVelocityMaterial into the core.

Mugen87 avatar Oct 25 '22 08:10 Mugen87

If parts of the mesh are not moving left or right, then yes, they will not have colors.

@bhouston Since the whole mesh is moving when you rotate it, shouldn't it all light up?

cabanier avatar Jan 26 '23 22:01 cabanier

I think I understand now. If one of the colors/velocities goes negative, it gets clipped to black.

cabanier avatar Jan 27 '23 23:01 cabanier

Honestly, it all depends on how things are being visualized. If it is hard to tell if it is correct with the current visualization method, maybe we need to switch to a different one? Maybe we could draw little lines to indicate flow or something on screen?

bhouston avatar Jan 28 '23 17:01 bhouston

For visualization only, something along these lines... but better:

vec2 vel = ( ndcPositionCurrent - ndcPositionPrevious ) * 0.5;

vel *= 100.0; // values are too small to see

vel = vel * 0.5 + 0.5;

gl_FragColor = vec4( vel, 1.0, 1.0 );

Tip: Allowing panning in the example is illustrative.

WestLangley avatar Jan 28 '23 22:01 WestLangley

FYI I'm using your velocity shader to implement space warp on quest and it works great.

cabanier avatar Jan 29 '23 04:01 cabanier