react-babylonjs
(link) aims to be an unopinionated way to integrate React and BabylonJS. You can choose a declarative or imperative programming style or a combination of both. This is a sample project to help people get started. The react-babylonjs
homepage has more storybook examples, while this project shows how to integrate with other libraries like redux with just a few examples.
If you are cloning this repo, you just need:
$ yarn install # Install project dependencies
$ yarn start # Compile and launch (same as `npm start`)
If you are starting a fresh Create React App, then you should only need these dependencies.
yarn add @babylonjs/core @babylonjs/gui react-babylonjs
If you are using the BabylonJS GUI components then you will need '@babylonjs/gui' and if you are loading 3D models '@babylonjs/loaders'. They are peer dependencies, so you will get warnings.
A BabylonJS scene to your webpage in either a declarative manner or code manner (or combination).
Can be done purely with React Components and zero code. If you go this way, you can get a full HMR experience. Note that when the lights are dimmed that the state is persisted after the HMR update.
<Scene id="sample-canvas">
<freeCamera name="camera1" position={new Vector3(0, 5, -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)} />
<box name="box" size={1.7} position={new Vector3(0, 1, 0)}>
<rotateMeshBehavior radians={0.01} axis={Axis.Y} />
</box>
<ground name="ground1" width={6} height={6} subdivisions={2} />
</scene>
You can easily control BabylonJS models as well. This sample loads 3D models and controls them with buttons. live demo: with model live demo: with props
class WithModel extends React.Component
{
...
render() {
return (
<Scene id="sample-canvas">
<arcRotateCamera name="camera1" alpha={Math.PI / 2} beta={Math.PI / 2}
radius={0.075} target={Vector3.Zero()} minZ={0.001}
/>
<hemisphericLight name="light1" intensity={0.7} direction={Vector3.Up()} />
<Model
position={ new Vector3(0.02, 0, 0)}
rootUrl = {`${baseUrl}BoomBox/glTF/`}
sceneFilename="BoomBox.gltf"
/>
</Scene>
)
}
}
class WithVR extends React.Component
{
render() {
return (
<Scene id="sample-canvas" onMeshPicked={this.onMeshPicked}>
<arcRotateCamera name="arc"
target={ new Vector3(0, 1, 0) }
alpha={-Math.PI / 2}
beta={(0.5 + (Math.PI / 4))}
radius={2}
minZ={0.001} />
<directionalLight name="dl" direction={new Vector3(0, -0.5, 0.5)} position = {new Vector3(0, 2, 0.5)}>
<shadowGenerator mapSize={1024} useBlurExponentialShadowMap={true} blurKernel={32}
shadowCasters={["counterClockwise", "clockwise", "BoomBox"]}
/>
</directionalLight>
<icoSphere name="counterClockwise" position={new Vector3(-0.5, 1, 0)} radius={0.2} flat={true} subdivisions={1}>
<standardMaterial
diffuseColor={Color3.Yellow()}
specularColor={Color3.Black()}
/>
<rotateMeshBehavior radians={0.01} axis={Axis.Y} />
</icoSphere>
<Model
rotation= {new Vector3(0, this.state.modelRotationY, 0)}
position={ new Vector3(0, 1, 0)}
rootUrl = {`${baseUrl}BoomBox/glTF/`}
sceneFilename="BoomBox.gltf"
scaling={ new Vector3(20, 20, 20) }
/>
<icoSphere name="clockwise" position={new Vector3(0.5, 1, 0)} radius={0.2} flat={true} subdivisions={1}>
<standardMaterial
diffuseColor={Color3.FromInts(255, 165, 0)}
specularColor={Color3.Black()}
/>
<rotateMeshBehavior radians={-0.01} axis={Axis.Y} />
</icoSphere>
<vrExperienceHelper createDeviceOrientationCamera={false} teleportEnvironmentGround={true} />
<environment enableGroundShadow= {true} groundYBias={1} mainColor={Color3.FromHexString("#74b9ff")} />
</Scene>
)
}
}
You don't need to rely on the declarative Components except for Scene and are free to completely create your own scenes and even control the runRenderLoop() logic. You are provided a created Scene (and Engine via scene.getEngine()) and loaded HTML5 canvas reference.
export default class NonDeclarative extends Component
{
meshPicked(mesh) {
console.log('mesh picked:', mesh)
}
onSceneMount(e) {
const { canvas, scene } = e
// Scene to build your environment, Canvas you need to attach your camera.
var camera = new ArcRotateCamera("Camera", 0, 1.05, 6, Vector3.Zero(), scene)
camera.attachControl(canvas)
MeshBuilder.CreateBox('box', { size: 3 }, scene)
new HemisphericLight('light', Vector3.Up(), scene);
scene.getEngine().runRenderLoop(() => {
if (scene) {
scene.render();
}
});
}
render() {
return (
<Scene
onMeshPicked={this.meshPicked}
onSceneMount={this.onSceneMount}
/>)
}
}
This project was bootstrapped with Create React App. You can find out about bootstrapping and ejecting on that site. This project has not been ejected.