brianzinn / react-babylonjs

React for Babylon 3D engine
https://brianzinn.github.io/react-babylonjs/
818 stars 105 forks source link

Particle and fire story? #185

Closed benallfree closed 2 years ago

benallfree commented 2 years ago

Hey guys, great project! Mind blown.

I just stumbled across this demo https://codepen.io/hiteshsahu/pen/VwjdXbP and wondered if you thought it would make a good storybook entry.

If so, I'd be happy to submit a PR. It would be a learning experience for me and I'm sure would inspire some great discussion.

Let me know what you think!

brianzinn commented 2 years ago

hi @benallfree - That's a great idea and would be a more than welcome addition to the storybook. I just saw the codepen authors impressive website experimental section.

It looks like that codepen can be done mostly declaratively... everything except for the ParticleHelper. I really ought to make some async creation methods a more first class citizen of the framework. There is one async playground here: https://github.com/brianzinn/react-babylonjs/blob/master/storybook/stories/babylonjs/Basic/snippetMaterial.stories.js

I would be happy to look into putting some async functionality into the renderer itself. I would like to see maybe something like this kind of syntax (note that <particleHelperCreateAsync ... /> won't currently work it is a proposal):

// This won't actually work because setting the ref won't trigger a re-render :)
const FireEmitter = () => {
  const fireEmitterRef = useRef();
  const onFireParticleHelperResolve = (set) => {
    set.start();
    for (var i = 0; i < set.systems.length; i++) {
      var particleSystem = set.systems[i];
      particleSystem.emitter = fireEmitterRef.current;
      particleSystem.emitRate = 10;
    }
  }
  return (
    <>
      <sphere ref={fireEmitterRef} name='fireEmitter' diameter={0.5}>
        <standardMaterial name='mat1' diffuseColor = {new BABYLON.Color3(1, 1, 0)} alpha={0} />
      </sphere>
      {fireEmitterRef.current &&
        <particleHelperCreateAsync type='fire' onResolve={onFireParticleHelperResolve} />
      }
    </>
  )
}

Maybe you can make the story without the declarative ParticleHelper and we can discuss the syntax?

benallfree commented 2 years ago

Great, I'd be happy to take a shot at it.

I'm sure I can figure this out with time, but your lib is doing something I've never seen before: I see JSX tags that have no import, such as <box> here: https://codesandbox.io/s/epic-darwin-tohk0?file=/src/App.tsx:1318-1327

How is that happening?

brianzinn commented 2 years ago

‘<box …/>’ is handled by the renderer. It’s calling Meshbuilder.CreateBox on your behalf. Those are hostElements once inside the ‘Scene’ component — much like a div for the DOM renderer

benallfree commented 2 years ago

I haven't played with React renderers at all, I'll have to look into it further. So is there an intuitive way to know that <box> even exists? For example, I'm struggling to understand how someone would infer:

    const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 25, height: 25});

becomes

<ground width={25} height={25}/>
brianzinn commented 2 years ago

I think the api docs could use a lot of improvement and you are right that it is not obvious. Besides the less intuitive meshbuilder and AdvancedDynamicTexture creation methods the rest are only generated from Babylon typings using constructors.

https://github.com/brianzinn/react-babylonjs/blob/master/docs/api.md

benallfree commented 2 years ago

Ok thanks. I spent some time looking at Three.js and the surrounding community. There is definitely some popular stuff out there. I just have a feeling Babylon+React is a pretty good platform for games. I'd like to learn more about Babylon and then if I decide to move forward I would be interested in working with you to beef up the docs and demos.

benallfree commented 2 years ago

It would be cool if each storybook story could have a GUI overlay to adjust variables dynamically. Three.js is good at that. Also a codesandbox version of each story would be cool. Just some thoughts as I'm sorting through everything :)

brianzinn commented 2 years ago

I totally agree with you on that. The storybook 'controls' support that, but I think not as good as other control options. Some of the newer three examples use a controls library from pmndrs - the one (I think) that inspired that project can be modified and I had it working with Babylon.js (there is a pending PR): https://github.com/birkir/react-three-gui

I agree also with the codesandbox - it's a really easy way to see and play with the examples, but also they can get out of date quickly. I have actually already thought about either improving the storybook or abandoning it and moving towards something more like playground.babylonjs.com (you can click the examples) that supports JSX. It was asked in the forum already and they didn't want to have support for JSX added, but no reason it can't be done. I think that would really be a worthwhile effort and am happy to spend time on that for sure.

benallfree commented 2 years ago

It looks like Codesandbox has a github import feature via GitHubBox.com https://codesandbox.io/docs/importing. It appears to support monorepos such as those containing example packages like this https://github.com/reduxjs/redux/tree/master/examples/todomvc. I haven't checked, but I assume based on the URL that it always pulls the current code from the master tree.

If we had the storybook plus a launch in codesandbox button, that might be the best of both worlds:

As a side note... I recently got an Oculus Quest 2 and was really impressed with the possibilities. I've noticed that WebXR is kind of an afterthought in most docs and playgrounds. Making the demos WebXR accessible could connect with a broader audience. I think the Quest 2 really proves that the wave is coming.

brianzinn commented 2 years ago

totally agree about the XR. i added the WebXRController and DOMOverlay features to Babylon.js - I haven't brought it into this library as a declarative integration, but really want to at some point. It gets interesting with all the async calls, but I think a clean solution exists with Suspense. I really like how this library builds GUI declaratively and you can drop it on a plane for XR interaction.

Launching to codesandbox would be extremely cool and useful. For many issues I end up creating a codesandbox as it's the only real way to share reproductions. I wonder if Storybook and Codesandbox can work together without duplicating everything.

benallfree commented 2 years ago

I wonder if Storybook and Codesandbox can work together without duplicating everything.

I'm attempting exactly that right now, I'll send along a PR example when I get it working in my fork.

brianzinn commented 2 years ago

Thanks for the PR @benallfree with new documentation site!