-
Notifications
You must be signed in to change notification settings - Fork 106
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
declarative nodeMaterial snippet #105
Comments
@jbixon13 what about something like this (you'd maybe want to add snippetId to the dependency array):
In your main component:
Snippet isn't support out of the box - it's a static method (and async) - we could add it as a new material - you'll notice it loads kind of wonky, since it's waiting to download the snippet before applying. |
Thank you! I've updated my codesandbox to try replicating your approach, but I can't seem to get it to work. I'm not sure if it's the dependency array like you said or something else but I'll keep playing with it. |
I edited the one file import React, { useRef, useEffect } from "react";
import { Engine, Scene, useBabylonScene } from "react-babylonjs";
import { Vector3, NodeMaterial } from "@babylonjs/core";
const SnippetMaterial = (props) => {
const scene = useBabylonScene();
const material = useRef(null);
useEffect(() => {
NodeMaterial.ParseFromSnippetAsync(props.snippetId, scene).then(
(nodeMaterial) => {
material.current = nodeMaterial;
},
[]
);
});
//<nodeMaterial name="sphereMat" snippetId={"#81NNDY#20"} />
return material.current === null ? null : (
<nodeMaterial fromInstance={material.current} />
);
};
const BabylonCanvas = () => {
return (
<Engine antialias>
<Scene>
<freeCamera
name="camera1"
position={new Vector3(0, 2, -10)}
target={Vector3.Zero()}
/>
<hemisphericLight
name="light1"
intensity={0.7}
direction={Vector3.Up()}
/>
<sphere
name="sphere1"
diameter={2}
segments={16}
position={new Vector3(0, 1, 0)}
>
<SnippetMaterial name="sphereMat" snippetId="#81NNDY#20" />
</sphere>
<ground name="ground1" width={6} height={6} subdivisions={2} />
</Scene>
</Engine>
);
};
export default BabylonCanvas; |
updated again and copied the above as-is, still doesn't work for some reason 😕 |
got it! I needed to update the first dependency array, not add a second one like I was doing before. Thanks for your quick and useful help :) |
ok interestingly it works if I update the dependency array and it auto-refreshes to add the material but goes back to not working if I hard-refresh the app. It may just be a codesandbox issue, I'll try it locally |
Yeah, that's a typo from me with the dependency array in the wrong place. Also, if you don't want the sphere showing up with the default material then you could put the sphere into the component as well :) |
@jbixon13 sorry about that code I sent you - the reason is that
|
that works, both locally and in codesandbox! Thanks again for the help |
Hi,
If you want to use it with brianzinn's code, you could give the SnippetMaterial i.e. an array of objects as a prop: and iterate through all of these values within the snippet Material and assigning the hook. I even use to unfreeze and freeze the material before and after the use of the hook, so the material should be performant, if it is not changed too often.
(Actually I thought I could contribute a story, but currently I am not certain if I should use the 2.3.x version or jump on 3.0.0 - also in connection to the babylonjs-loaders. I hope @brianzinn you can give us an update soon :) ) |
Thanks @dennemark - I would be really keen to get some new stories and recipes on materials. I would recommend the new |
@dennemark did you want to contribute a node material hook? seems really useful, especially with freezing and setting block values. Would like to see it in use or as a recipe! |
I'm just now getting back into this project and had another question regarding node materials. In the current material being passed to the sphere in my example the green color is hard-coded in the surface color node. Is there any way to pass this from a sphere object so that the same material can be used on multiple objects with different colors? This would be similar to how color is currently passed into I see an option in the NME to create a Basically I am trying to understand the best way to create a scene that has toon properties without having to use a new material on each object |
@jbixon13 I did check the docs and they mentioned that colors are not taken as uniform (and can change) by default unless you freeze them. I just took part of the hook from dennemark's comment above and applied to existing story (maybe add material to dep array...). useEffect(() => {
// there is a race condition here if color changes before material is loaded would lose that value
if (material) {
let block = material.getInputBlockByPredicate(b => b.name === 'Surface Color');
block.value = Color3[surfaceColor]();
}
}, [surfaceColor]); If you wanted to work on a fully declarative syntax that would allow the |
@jbixon13 Hope that example helps and also @dennemark updated the story to freeze the material as well as a hook to make it easier to update the Node Material blocks (https://github.com/brianzinn/react-babylonjs/blob/master/stories/babylonjs/Basic/snippetMaterial.stories.js). If you wanted something more declarative or have any more questions please re-open. Cheers. |
I'm new to babylon after learning three.js and react-three-fiber, so thank you for creating a declarative version of babylon to help ease the transition! I was hoping to try out a
nodeMaterial
by loading it withParseFromSnippetAsync
but I'm not sure whether that's possible declaratively, or whether I need some async functional component setup that I haven't considered.Codesandbox I'm testing on: https://codesandbox.io/s/react-babylon-testing-bzp2q?file=/src/BabylonCanvas.jsx
I'm trying to add the
nodeMaterial
to the sphere on line 25 but I'm not sure how to approach it. I noticed asnippetId
prop but it doesn't seem to work as expected. Any advice would be helpful!I noticed a similar question on the forum that you answered regarding the
CreateFromSnippetAsync
function in auseEffect
but I wasn't sure if a similar approach is necessary here or how to set it up without access to their code.https://forum.babylonjs.com/t/particlehelper-createfromsnippetasync-is-not-a-function-in-react-app/14321
The text was updated successfully, but these errors were encountered: