vasturiano / 3d-force-graph

3D force-directed graph component using ThreeJS/WebGL
https://vasturiano.github.io/3d-force-graph/example/large-graph/
MIT License
4.66k stars 821 forks source link

Selective Bloom effect for selected nodes and links #628

Open DanielChuDC opened 1 year ago

DanielChuDC commented 1 year ago

Is your feature request related to a problem? Please describe.

@vasturiano

I hope this message finds you well. Firstly, I would like to express my gratitude for your repository. The work you have done is truly impressive.

Upon reviewing the related issue, I noticed that no solution has been provided thus far.

I took the initiative to search for a potential approach and found a suggestion on the Three.js discourse forum here. I have tested this approach myself with this library, and the results have been positive. However, I would greatly appreciate your expert opinion on this matter.

If feasible, it would be fantastic to have an example showcasing the selective bloom effect as a testament to the remarkable capabilities of your library.

Please let me know if you think this idea is viable. I would be more than happy to submit a pull request for the demo, should you find it appropriate.

Describe the solution you'd like Current approach that I have tried with

  1. Set the configOptions that ForceGraph3d({ configOptions })(<domElement>) with the parameters below.
    
    const configOptions = {
    rendererConfig: {
        outputEncoding: THREE.sRGBEncoding,
        toneMapping: THREE.ACESFilmicToneMapping,
        toneMappingExposure: 1.5, // color mgmt
    }
    };

2.  import UnrealBloomPass just like below, and set the UnrealBloomPass with 1,1,1, then add the pass into composer

```ts
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';`

const bloomPass = new UnrealBloomPass(new THREE.Vector2(width, height), 1, 1, 1);
Graph.postProcessingComposer().addPass(bloomPass);
  1. Utilise Graph.linkThreeObject to render the selective bloom effect on node or links based on the condition. By adjusting emissiveIntensity, the bloom effect will change accordingly.
    // if bloomEffect is true, render the MeshMaterial
    if (bloomEffect) {
        Graph.linkThreeObject(({ source, target }) => {
            if (
                source?.entity_index === '/m/06rf7' ||
                source?.entity_index === '/m/05k7sb' ||
                target?.entity_index === '/m/05k7sb'
            ) {
                return new THREE.Mesh(
                    new THREE.BoxGeometry(1, 1, 1), // Example geometry, replace with the appropriate one
                    new THREE.LineBasicMaterial({
                        toneMapped: false,
                        color: new THREE.Color(1, 0, 2)
                    })
                );
            }
            return new THREE.Mesh(
                new THREE.BoxGeometry(5, 5, 5), // Example geometry, replace with the appropriate one
                new THREE.LineBasicMaterial({
                    toneMapped: false,
                    color: new THREE.Color(0, 0, 0)
                })
            );
        });
        Graph.nodeThreeObject(({ entity_index }) => {
            if (entity_index === '/m/06rf7' || entity_index === '/m/05k7sb') {
                return new THREE.Mesh(
                    new THREE.BoxGeometry(5, 5, 5), // Example geometry, replace with the appropriate one
                    new THREE.MeshStandardMaterial({
                        toneMapped: false,
                        emissive: 'blue',
                        emissiveIntensity: 5
                    })
                    // new THREE.MeshBasicMaterial({
                    //  toneMapped: false,
                    //  color: new THREE.Color(10, 0, 0)
                    //   })
                );
            }
            return new THREE.Mesh(
                new THREE.BoxGeometry(5, 5, 5), // Example geometry, replace with the appropriate one
                new THREE.MeshBasicMaterial({
                    toneMapped: false,
                    color: new THREE.Color(0, 0, 0)
                })
            );
        });
    }

Demo

https://github.com/vasturiano/3d-force-graph/assets/52316624/db769857-7bf6-4638-97b6-75fd948c15bd

Some topics required for suggestions

  1. The performance seem worse than without this selective bloom effect when rendering large number of nodes and links(more than 1k) but after a fews seconds, it become slightly better. How can I improve the performance?
  2. The object will switch back to original node style, how to make it consistent or easier to configure to stick to the custom Graph.nodeThreeObject with the bloom effect? You may check out the demo at 39 seconds for more information.
DanielChuDC commented 1 year ago

The library version I am using

"three": "^0.153.0",
"3d-force-graph": "^1.71.4",
"d3-force-3d": "^3.0.5",
DanielChuDC commented 1 year ago

Hi @vasturiano, any help would be appreciated!