npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-babylonjs

v1.1.2

Published

React Native for Babylon.js

Downloads

61

Readme

react-native-babylonjs

npm version npm downloads npm licence Platform

There are 3 ways to use babylonjs with react-native

  1. Official @babylonjs/react-native
  2. react-babylonjs + @babylonjs/react-native as described in https://github.com/brianzinn/react-babylonjs#react-native
  3. react-native-babylonjs + @flyskywhy/react-native-gcanvas

Performance: @babylonjs/react-native with JSI should be better.

MultiView: react-native-babylonjs can open many View, while @babylonjs/react-native said only one EngineView can be active.

Convenient: With react-native-babylonjs, the react-babylonjs multiple touches demo Drag 'n' Drop just ported a few codes to react -> react-native, here is the result.

Install react-native-babylonjs

npm install react-native-babylonjs @flyskywhy/react-native-gcanvas @babylonjs/core @babylonjs/gui

If your textures are stored in APP not on Web, you should also npm install react-native-fs [email protected] and write codes ref to this commit react -> react-native: babylonjs Non-Declarative works well on Android with new version @flyskywhy/react-native-gcanvas support 3d game engine babylonjs.

Use react-native-babylonjs

Ref to react-babylonjs described below and babylonjs examples in https://github.com/flyskywhy/GCanvasRNExamples.

react-native-babylonjs is touchable by default, If don't want it be touchable, need set props touchActionNone={true} e.g. <Engine touchActionNone={true} />.

react-native-babylonjs support .glb not .gltf.

import dataUri from 'data-uri.macro';
import {SceneLoader} from '@babylonjs/core';
import '@babylonjs/loaders/glTF';
const christmasTreeFile = dataUri('../images/LightTree/christmas-tree.glb');

  onSceneMount = async (e) => {
    const {canvas, scene} = e;
    ...
    SceneLoader.ImportMeshAsync(
      '',

      // 'https://raw.githubusercontent.com/orbitgw/Chirstmas-Tree/master/src/model/',
      // 'christmas-tree.glb',
// use above or below
      '',
      christmasTreeFile,

      scene,
    ).then((result) => {
      const christmasTree = result.meshes[1];
      christmasTree.position.set(0, 250, 0);
      christmasTree.scalingDeterminant = 25;

      const standardMaterial = new StandardMaterial('redMat', scene);
      standardMaterial.diffuseColor = new Color4(0.4, 0.4, 0.4, 1);
      standardMaterial.specularColor = new Color4(0.4, 0.4, 0.4, 1);
      standardMaterial.emissiveColor = new Color4(0.0, 0.16, 0.0, 1);

      christmasTree.material = standardMaterial;
    });
  };

and need below hack to avoid Cannot create URL for blob

sed -i -e "s/this.skipMaterials = false/this.skipMaterials = true/" node_modules/@babylonjs/loaders/glTF/glTFFileLoader.js

Feature of react-native-babylonjs

Not support Post Processes yet.

Memo when debug Post Processes

On Android, if uncomment pipeline.depthOfFieldEnabled = true; in /src/nonDeclarative.js ,will got black screen (and got glGetError()=GL_INVALID_FRAMEBUFFER_OPERATION after glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0)), then if put if(postProcess.name === 'circleOfConfusion') before this._postProcesses.push(postProcess); in @babylonjs v5.1.0/core/Cameras/camera.js, will got pink screen. This maybe bug of@babylonjs v5.1.0 ref to https://developer.vuforia.com/forum/unity/black-screen-android-8010, or maybe Mali GPU ref to https://stackoverflow.com/questions/46483852/gl-invalid-framebuffer-operation-framebuffer-is-not-complete-or-incompatible-wi, or maybe WebGL/OpenGLES version ref to https://forum.unity.com/threads/webgl-on-android-only-works-in-fullscreen.914435/, or maybe gl.getExtension("OES_texture_float") is false so that ThinEngine.prototype._canRenderToFramebuffer is false, or maybe FrameBuffer size should be power of 2 (I tried to set GCanvasView to 256x256 and change this._gl.drawingBufferWidth to this._gl.canvas.width in @babylonjs v5.1.0/core/Engines/thinEngine.js so that width, height in ThinEngine.prototype._setupFramebufferDepthAttachments will be 256, 256 but no effect, and needPOTTextures in @babylonjs v5.1.0/core/Engines/thinEngine.js should be true, and if not change this._gl.drawingBufferWidth to this._gl.canvas.width will GL_INVALID_FRAMEBUFFER_OPERATION after glDrawElements), or cause by WebGL can GL_DEPTH_STENCIL but OpenGL ES will getError so use GL_DEPTH24_STENCIL8 instead by renderbufferStorage() in https://github.com/flyskywhy/react-native-gcanvas/blob/master/packages/gcanvas/src/context/webgl/RenderingContext.js , or since https://blenderartists.org/t/purple-material-texture-is-driving-me-nuts/1371196/9 and https://stackoverflow.com/questions/72931171/in-unity-custom-shader-materials-appear-pink said pink generally means the material (or corresponding shader) has problem, maybe need test glFramebufferTexture2D in @flyskywhy/react-native-gcanvas, I have no clue, so just not use post processes.

Memo when debug babylonjs

if (!reflectionTexture.isReadyOrNotBlocking()) in @babylonjs v5.1.0/core/Materials/PBR/pbrBaseMaterial.js means whether url in CubeTexture.CreateFromPrefilteredData() is downloaded.

_useFinalCode() in @babylonjs v5.1.0/core/Materials/effect.js shows the shaders name that babylonjs used.

_this._hdr in @babylonjs v5.1.0/core/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.js, on Web is true, on Android is false, thus cause there is no 'imageProcessing' when enable some Post Process on Android ref to DefaultRenderingPipeline.prototype._buildPipeline.

PostProcessManager.prototype._prepareFrame and PostProcessManager.prototype._finalizeFrame in @babylonjs v5.1.0/core/PostProcesses/postProcessManager.js are called by Scene.prototype._renderForCamera in @babylonjs v5.1.0/core/scene.js to process camera as targetTexture?



Forked from react-babylonjs, below is its README.



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 declaratively thanks to code generation and even custom props allow you to declaratively add shadows, physics, 3D models, attach 2D/3D UI to meshes, 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>
)

code sandbox for above

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, { useRef } from 'react';
// full code at https://github.com/brianzinn/create-react-app-typescript-babylonjs

const App: React.FC = () => {
  let sphereRef = useRef<Nullable<Mesh>>();

  const onButtonClicked = () => {
    if (sphereRef.current) {
      sphereRef.current.physicsImpostor!.applyImpulse(
        Vector3.Up().scale(10),
        sphereRef.current.getAbsolutePosition()
      );
    }
  };

  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

Storybook

~50 sample web pages with viewable source code on github pages.

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 add support for CascadedShadowGenerator, createPortal and Html (project HTML in scene - ported from drei). Also, stories for Snippet Material and "tunnel" zustand integration.
  • kencyke created a cool multi-canvas + cloud point repo that insipired creation of <pointsCloudSystem .../> as host element.
  • flostellbrink fixed the react-babylon-spring integration and added GH action for Storybook (github pages)

Thanks also to all the people who have contributed with issues/questions/discussions. All the great ideas and requests are why this project evolved beyond an experiment.

Made with ♥