All Projects → brianzinn → React Babylonjs

brianzinn / React Babylonjs

Licence: mit
React for Babylon 3D engine

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to React Babylonjs

C3de
C3DE is a 3D Game Engine powered by MonoGame
Stars: ✭ 78 (-73.91%)
Mutual labels:  3d-engine, physics, vr
Helixjs
A Javascript 3D game engine.
Stars: ✭ 84 (-71.91%)
Mutual labels:  3d, 3d-engine, physics
Limonengine
3D FPS game engine with full dynamic lighting and shadows
Stars: ✭ 331 (+10.7%)
Mutual labels:  3d, 3d-engine, physics
Virocore
ViroCore cross-platform AR/VR renderer
Stars: ✭ 270 (-9.7%)
Mutual labels:  3d-models, 3d-engine, vr
Lume
Create CSS3D/WebGL applications declaratively with HTML. Give regular DOM elements shadow and lighting.
Stars: ✭ 445 (+48.83%)
Mutual labels:  3d, 3d-models, 3d-engine
Assetkit
🎨 Modern 2D/3D - Importer • Exporter • Util - Library, also called (AssetIO)
Stars: ✭ 97 (-67.56%)
Mutual labels:  3d, 3d-models, 3d-engine
Tf flame
Tensorflow framework for the FLAME 3D head model. The code demonstrates how to sample 3D heads from the model, fit the model to 2D or 3D keypoints, and how to generate textured head meshes from Images.
Stars: ✭ 193 (-35.45%)
Mutual labels:  3d, 3d-models
Node Occ
build BREP Solids with OpenCascade and NodeJS - 3D Modeling
Stars: ✭ 202 (-32.44%)
Mutual labels:  3d, 3d-models
Model Viewer
Easily display interactive 3D models on the web and in AR!
Stars: ✭ 3,751 (+1154.52%)
Mutual labels:  3d, 3d-models
harfang3d
HARFANG 3D source code public repository
Stars: ✭ 173 (-42.14%)
Mutual labels:  physics, vr
Flame pytorch
This is a implementation of the 3D FLAME model in PyTorch
Stars: ✭ 153 (-48.83%)
Mutual labels:  3d, 3d-models
QuietVR
A Quiet Place in VR: Generate any 3D object with your voice. It's magic!
Stars: ✭ 17 (-94.31%)
Mutual labels:  vr, 3d-models
Glportal
🎮 Open Source teleportation based first person puzzle-platformer
Stars: ✭ 297 (-0.67%)
Mutual labels:  3d, physics
Aframe
🅰️ web framework for building virtual reality experiences.
Stars: ✭ 13,428 (+4390.97%)
Mutual labels:  3d, vr
Meshlab
The open source mesh processing system
Stars: ✭ 2,619 (+775.92%)
Mutual labels:  3d, 3d-models
Pulse
A pendant to warn you when you touch your face
Stars: ✭ 229 (-23.41%)
Mutual labels:  3d, 3d-models
Layaair discard
This is old LayaAir veriosn writetten by ActionScript 3.0 ,now LayaAir is using TypeScript as the Engine Script,Please use https://github.com/layabox/LayaAir instead.
Stars: ✭ 1,858 (+521.4%)
Mutual labels:  3d, 3d-engine
Legion-Engine
Rythe is a data-oriented C++17 game engine built to make optimal use of modern hardware.
Stars: ✭ 502 (+67.89%)
Mutual labels:  physics, 3d-engine
WebVRExamples
yonet.github.io/webvrexamples/examples/cubes.html
Stars: ✭ 19 (-93.65%)
Mutual labels:  vr, 3d-models
BBearEditor-2.0
My own 3D engine & editor in order to learn graphics algorithms and game engine architecture.
Stars: ✭ 32 (-89.3%)
Mutual labels:  physics, 3d-engine

react-babylonjs

'react-babylonjs' integrates the Babylon.js real time 3D engine with React

react-babylonjs lets you build your scene and components using a familiar declarative syntax with the benefits of reusable components and hooks. The Babylon.js API is mostly covered thanks to code generation, but also custom props allow you to declaratively add shadows, physics, attach 2D/3D UI to meshes, 3D models, etc.

Fully supports hooks. Full support for TypeScript with auto-completion on elements and compile time checks. Context API and hooks provide easy access to Scene/Engine/Canvas.

NPM version NPM downloads

How to Install

$ npm i react-babylonjs @babylonjs/core @babylonjs/gui

OR

$ yarn add react-babylonjs @babylonjs/core @babylonjs/gui

No third party dependencies outside of React + babylon.js If you are upgrading from 2.x please follow the breaking changes guide:

3.0 breaking changes

Models

If you are using 3D models ensure you have added the @babylonjs/loaders NPM. It is not a direct dependency, but registers loaders as plugins via imports with side effects:

  • Register all model types import @babylonjs/loaders;
  • OBJ import '@babylonjs/loaders/OBJ';
  • glTF import '@babylonjs/loaders/glTF';

(more instructions on model loading in ES6 here )

Usage Styles

react-babylonjs tries to remain unopinionated about how you integrate BabylonJS with React. This module provides a 100% declarative option and/or you can customise by adding code. There are lots of escape hatches where you can switch to imperative coding and direct access to objects.

Connecting the pieces

If you are new to React or babylon.js (or both) there is some learning ahead. The babylon.js documentation site is really useful for understanding the basics of lighting, cameras, etc. This project aims to make easy to integrate those into React using JSX.

Here we re-use a SpinningBox component that can be clicked or hovered. These reusable components can be used to compose a declarative scene. We are using hooks for the clicking, hovering and spinning.

Connecting the pieces

import React, { useRef, useState } from 'react'
import { Engine, Scene, useBeforeRender, useClick, useHover } from 'react-babylonjs'
import { Vector3, Color3 } from '@babylonjs/core'

const DefaultScale = new Vector3(1, 1, 1);
const BiggerScale = new Vector3(1.25, 1.25, 1.25);

const SpinningBox = (props) => {
  // access Babylon scene objects with same React hook as regular DOM elements
  const boxRef = useRef(null);

  const [clicked, setClicked] = useState(false);
  useClick(
    () => setClicked(clicked => !clicked),
    boxRef
  );

  const [hovered, setHovered] = useState(false);
  useHover(
    () => setHovered(true),
    () => setHovered(false),
    boxRef
  );

  // This will rotate the box on every Babylon frame.
  const rpm = 5;
  useBeforeRender((scene) => {
    if (boxRef.current) {
      // Delta time smoothes the animation.
      var deltaTimeInMillis = scene.getEngine().getDeltaTime();
      boxRef.current.rotation.y += ((rpm / 60) * Math.PI * 2 * (deltaTimeInMillis / 1000));
    }
  });

  return (<box name={props.name} ref={boxRef} size={2} position={props.position} scaling={clicked ? BiggerScale : DefaultScale}>
    <standardMaterial name={`${props.name}-mat`} diffuseColor={hovered ? props.hoveredColor : props.color} specularColor={Color3.Black()} />
  </box>);
}

export const SceneWithSpinningBoxes = () => (
  <div>
    <Engine antialias adaptToDeviceRatio canvasId='babylonJS' >
      <Scene>
        <arcRotateCamera name="camera1" target={Vector3.Zero()} alpha={Math.PI / 2} beta={Math.PI / 4} radius={8} />
        <hemisphericLight name='light1' intensity={0.7} direction={Vector3.Up()} />
        <SpinningBox name='left' position={new Vector3(-2, 0, 0)}
          color={Color3.FromHexString('#EEB5EB')} hoveredColor={Color3.FromHexString('#C26DBC')}
        />
        <SpinningBox name='right' position={new Vector3(2, 0, 0)}
          color={Color3.FromHexString('#C8F4F9')} hoveredColor={Color3.FromHexString('#3CACAE')}
        />
      </Scene>
    </Engine>
  </div>
)

Hooks, Shadows and Physics (and optionally TypeScript, too)

You can declaratively use many features together - here only the button click handler actually has any code - and we have declarative Physics, GUI, Lighting and Shadows. demo: Bouncy demo

import React, { useCallback } from 'react';
/// full code at https://github.com/brianzinn/create-react-app-typescript-babylonjs

const onButtonClicked = () => {
  if (sphere !== null) {
    sphere.physicsImpostor!.applyImpulse(
      Vector3.Up().scale(10), sphere.getAbsolutePosition()
    )
  }
}

const App: React.FC = () => {
  const sphereRef = useCallback(node => {
    sphere = node;
  }, []);

  return (
    <Engine antialias={true} adaptToDeviceRatio={true} canvasId="sample-canvas">
      <Scene enablePhysics={[gravityVector, new CannonJSPlugin()]}>
        <arcRotateCamera name="arc" target={ new Vector3(0, 1, 0) }
          alpha={-Math.PI / 2} beta={(0.5 + (Math.PI / 4))}
          radius={4} minZ={0.001} wheelPrecision={50} 
          lowerRadiusLimit={8} upperRadiusLimit={20} upperBetaLimit={Math.PI / 2}
        />
        <hemisphericLight name='hemi' direction={new Vector3(0, -1, 0)} intensity={0.8} />
        <directionalLight name="shadow-light" setDirectionToTarget={[Vector3.Zero()]} direction={Vector3.Zero()} position = {new Vector3(-40, 30, -40)}
          intensity={0.4} shadowMinZ={1} shadowMaxZ={2500}>
          <shadowGenerator mapSize={1024} useBlurExponentialShadowMap={true} blurKernel={32}
            shadowCasters={["sphere1", "dialog"]} forceBackFacesOnly={true} depthScale={100}
          />
        </directionalLight>
        <sphere ref={sphereRef} name="sphere1" diameter={2} segments={16} position={new Vector3(0, 2.5, 0)}>
          <physicsImpostor type={PhysicsImpostor.SphereImpostor} _options={{
              mass: 1,
              restitution: 0.9
          }} />
          <plane name="dialog" size={2} position={new Vector3(0, 1.5, 0)}>
            <advancedDynamicTexture name="dialogTexture" height={1024} width={1024} createForParentMesh={true} hasAlpha={true}>
              <rectangle name="rect-1" height={0.5} width={1} thickness={12} cornerRadius={12}>
                  <rectangle>
                    <babylon-button name="close-icon" background="green" onPointerDownObservable={onButtonClicked} >
                      <textBlock text={'\uf00d click me'} fontFamily="FontAwesome" fontStyle="bold" fontSize={200} color="white" />
                    </babylon-button>
                  </rectangle>
              </rectangle>
            </advancedDynamicTexture>
          </plane>
        </sphere>
        
        <ground name="ground1" width={10} height={10} subdivisions={2} receiveShadows={true}>
          <physicsImpostor type={PhysicsImpostor.BoxImpostor} _options={{
              mass: 0,
              restitution: 0.9
          }} />
        </ground>
        <vrExperienceHelper webVROptions={{ createDeviceOrientationCamera: false }} enableInteractions={true} />
      </Scene>
    </Engine>
  );
}

Developer Experience and Fast Refresh

With declarative (TSX/JSX) coding and fast refresh, you experience the same development workflow in 3D - ie: save changes in your editor and see them immediately in the browser. Note in this capture when the light is dimmed that the state changes persist even after code updates and scene refresh.

babylon.js Fast Refresh

API

This project uses code generation, which allows fast reconciliation and excellent typings support.

react-babylonjs API

Release History and changes

Changes and commit history

Example Projects

Contributors

  • Huge shout out to Konsumer that helped bring this project to the next level. The ideas and code sandboxes from issue #6 inspired the code generation and HOC + Context API integration.
  • seacloud9 for adding storybook, GSAP demo, dynamic terrain (extension) & PIXI demo.
  • hookex has made the largest contribution :) Proper texture handling demo, Node parenting, demo Full Screen GUI demo, Effect Layers glow demo, behaviors demo, useHover & useClick hooks demo and react-spring integration demo. Author of react-babylon-spring - https://github.com/hookex/react-babylon-spring.
  • dennemark added Cascaded Shadow Generator and story for NodeMaterial usage with hooks.
  • kencyke created a cool multi-canvas + cloud point repo that insipired creation of <pointsCloudSystem .../> as host element.
  • Thanks also to all the people who have contributed with issues and questions.

Made with ♥ by Brian Zinn

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].