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

TSL: Add `mvpNode` to NodeMaterial for Custom Model-View-Projection

Open RenaudRohlinger opened this issue 1 year ago • 1 comments

Description Currently, the model-view-projection (MVP) of a mesh cannot be overridden in node materials. This PR introduces a new mvpNode, enabling the use of a custom MVP for any mesh.

For example, this allows for easily rendering a specific mesh with a different camera. Without this custom mvpNode, achieving this was challenging because the cameraProjectionMatrix and modelViewMatrix used in the MVP could not be overridden on a per-mesh basis.

This contribution is funded by Utsubo

RenaudRohlinger avatar Aug 28 '24 08:08 RenaudRohlinger

📦 Bundle size

Full ESM build, minified and gzipped.

Filesize dev Filesize PR Diff
685.4 kB (169.7 kB) 685.4 kB (169.7 kB) +0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Filesize dev Filesize PR Diff
462 kB (111.4 kB) 462 kB (111.4 kB) +0 B

github-actions[bot] avatar Aug 28 '24 08:08 github-actions[bot]

Is there another way of solving this? Adding more parameters like this to a material seems hacky.

mrdoob avatar Aug 28 '24 09:08 mrdoob

The alternative would be to completely override setupPosition I guess. (which is something I'm already doing on some of my projects).

Also the other issue I stumble upon regarding custom MVP in threejs on both WebGLRenderer and WebGPURenderer is that the sorting step of the RenderList wouldn't follow the shader. To do so we would need on both renderer a onBeforeSorting and onAfterSorting I guess. That would align the logic with custom hooks such as onBeforeRender or even onBeforeShadow.

if ( this.sortObjects === true ) {

 object.onBeforeSorting( _projScreenMatrix ) // update _projScreenMatrix with the custom MVP of the shader
  
  _vector3.setFromMatrixPosition( object.matrixWorld ).applyMatrix4( _projScreenMatrix );
  
  object.onAfterSorting( _projScreenMatrix ) // add a way to revert _projScreenMatrix for other. programs?

}

RenaudRohlinger avatar Aug 28 '24 10:08 RenaudRohlinger

I think this has already been implemented with material.vertexNode?

It is possible to use a custom MVP as in the example below.

https://github.com/mrdoob/three.js/blob/4116f8428173c4834a345efa2afa93c169c178ad/src/renderers/common/Background.js#L63-L74

sunag avatar Aug 28 '24 15:08 sunag