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

WebGPURenderer: Introduce NodeMaterialObserver and updates #29386

Merged
merged 10 commits into from
Sep 13, 2024

Conversation

sunag
Copy link
Collaborator

@sunag sunag commented Sep 11, 2024

Related issue: #29077 (comment), #29299

NodeMaterialObserver is responsible for checking if there are any changes in the materials, and if so, moving forward with the process of updating the nodes and bindings at the GPU level.

NodeMaterialObserver is an intermediate component between node updates that can be extended or manipulated using NodeMaterial.setupObserver().

List

  • Added NodeMaterialObserver
  • Move lights to renderGroup
  • Move camera to renderGroup
  • Move fog to renderGroup
  • Remove Proxies in updateBeforeNodes and updateAfterNodes
  • TSL Added Lights.js
  • RenderObjects: Reuse chainArray
  • Move tone mapping exposure to renderGroup

Performance

webgpu_performance_renderbundle

bundle = r168 bundle += viewMatrices GPU bundle += node observer
5.67ms 3.27ms 0.96ms
image image image
default = r168 default += viewMatrices GPU default += node observer
12.10ms 8.85ms 6.59ms
image image image

webgpu_performance

Screenshot Description
image WebGPU ~1026fps - mesh.static = true + non-string initial cacheKey in RenderObject - maybe we can some hash algorithm like crc32/64 for comparison in the rendering cycle - not available in this PR
image WebGPU ~870fps - mesh.static = true
image WebGPU ~717fps
image * WebGL ~640fps - reference
image WebGPU previous r168 ~299fps

Copy link

github-actions bot commented Sep 11, 2024

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 685.83
169.75
685.83
169.75
+0 B
+0 B
WebGPU 828.45
222.25
832.11
222.98
+3.66 kB
+729 B
WebGPU Nodes 828.03
222.16
831.62
222.86
+3.59 kB
+699 B

🌳 Bundle size after tree-shaking

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

Before After Diff
WebGL 462.42
111.53
462.42
111.53
+0 B
+0 B
WebGPU 526.43
141.9
529.89
142.75
+3.46 kB
+844 B
WebGPU Nodes 483.08
131.72
486.54
132.61
+3.46 kB
+890 B

@cmhhelgeson
Copy link
Contributor

cmhhelgeson commented Sep 11, 2024

I'm still trying to familiarize myself with the deeper workings of the API rather than just adding onto it, but is the monitor meant to simply just analyze whether the node material's properties match the data returned by getXData calls, then setting the needsRefresh flag as needed based on the result of that query? Then, within the main render loop, the nodes and bindings are only ( according to my guess) only updated in 3 scenarios

  1. In Renderer's createObject function
  2. Within _renderbundle and _renderObject direct only when the node monitor set's the Nodes objects needsRefresh flag to true.
  3. When a node is first initialized, which automatically will set the needsRefresh flag for it to be updated within the aforementioned _renderBundle and _renderObjectDirect functions.

@sunag
Copy link
Collaborator Author

sunag commented Sep 11, 2024

@cmhhelgeson Yes, your analysis is correct :)

@cmhhelgeson
Copy link
Contributor

cmhhelgeson commented Sep 12, 2024

If setupMonitor let's us manipulate the monitor's properties, would it make sense to have one of setupMonitor's arguments be a list of properties that are either included or excluded in the needsRefresh call, essentially making those properties static even if the program itself is not? Or would that not really provide any meaningful performance benefits given the small list of properties?

Or maybe it would make sense to add to a monitor's refreshUniforms property as a program is being created so a monitor only deals with uniforms relevant to its sample?

Perhaps it doesn't matter either way, since the monitor already seems to ignore properties that aren't there.

@sunag
Copy link
Collaborator Author

sunag commented Sep 12, 2024

The large list will be ignored in the frame cycle, leaving only the properties present in the material, so we wouldn't need to add many functions here.

I think interesting add refreshUniform as a property of the NodeMaterialMonitor, that way users could edit it.

The idea of ​​setupMonitor() is to encourage users to extend the NodeMaterialMonitor class and do their own specific optimization.

@sunag
Copy link
Collaborator Author

sunag commented Sep 12, 2024

This is the first time we have improved performance for many common objects without refraction, as we already had better performance in refraction, now without using special native WebGPU features.

@sunag sunag added this to the r169 milestone Sep 12, 2024
@sunag sunag changed the title WebGPURenderer: Introduce NodeMaterialMonitor WebGPURenderer: Introduce NodeMaterialMonitor and updates Sep 12, 2024
@mrdoob
Copy link
Owner

mrdoob commented Sep 12, 2024

Monitor sounds strange to me... NodeMaterialManager or NodeMaterialObserver may be more fitting?

@mrdoob
Copy link
Owner

mrdoob commented Sep 12, 2024

/cc @0b5vr

@sunag sunag changed the title WebGPURenderer: Introduce NodeMaterialMonitor and updates WebGPURenderer: Introduce NodeMaterialObserver and updates Sep 12, 2024
@mrdoob
Copy link
Owner

mrdoob commented Sep 12, 2024

Or even NodeMaterialOptimizer, whichever sounds better to you 👌

@sunag
Copy link
Collaborator Author

sunag commented Sep 12, 2024

What do you think of NodeMaterialWatcher? I'm not sure if it's better than NodeMaterialObserver.

In my head material optimizer would enter the compilation process, shaders, etc. The main objective of the class would be to check data changes and release the update of nodes and bindings.

@sunag
Copy link
Collaborator Author

sunag commented Sep 12, 2024

Some others options could be NodeMaterialUpdater, NodeMaterialListener...

@cmhhelgeson
Copy link
Contributor

I think NodeMaterialObserver is good. Updater suggests a class that's performing more robust modifications on the materials.

@sunag sunag marked this pull request as ready for review September 12, 2024 23:12
@sunag sunag merged commit 7290d8f into mrdoob:dev Sep 13, 2024
12 checks passed
@sunag sunag deleted the dev-nodemonitor branch September 13, 2024 03:58
@RenaudRohlinger
Copy link
Collaborator

Awesome!!

By the way, @sunag this PR seems to break the WebGL version of webgpu_performance_renderbundle.

LD2Studio pushed a commit to LD2Studio/LD2Studio-Editor that referenced this pull request Sep 13, 2024
…29386)

* Introduce NodeMaterialMonitor

* Update VelocityNode.js

* updates

* Update webgpu_performance_renderbundle.html

* Update Lights.js

* updates

* rename NodeMaterialMonitor -> NodeMaterialObserver

* Update NodeMaterials.js
LD2Studio pushed a commit to LD2Studio/LD2Studio-Editor that referenced this pull request Sep 13, 2024
…29386)

* Introduce NodeMaterialMonitor

* Update VelocityNode.js

* updates

* Update webgpu_performance_renderbundle.html

* Update Lights.js

* updates

* rename NodeMaterialMonitor -> NodeMaterialObserver

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

Successfully merging this pull request may close these issues.

4 participants