Hi there!
After some detours, I’m back to adding multiple 3D views to the React Native app I’m working on.
A few months ago I’ve posted a question about having multiple views in React Native which is not supported at the moment.
As a workaround I was provided the “Split Screen” example which renders multiple cameras with different viewports. I’ve tried to replicate that in React Native but I’m running into an issue.
The view renders all the cameras but ignores their respective viewport, instead it seems to be using the view port of the last camera and apply to all cameras, no matter which camera it’s being given to render.
I’m using React Native 0.69 and I’m running on Android (both simulator and physical device).
Is this a bug that can be fixed or may be a limitation of the current implementation? Thanks in advance for your help!
Notes:
- I tried using scissors but got this error
Error: Exception in HostFunction: undefined is not an object (evaluating 'gl.enable')
- I also tried adding a second engine view node but it renders properly only if being given the same camera as the first one.
Below is the app code (the same createScene()
function works in playground):
import React, {useState, useEffect} from 'react';
import {Text, View} from 'react-native';
import {EngineView, useEngine} from '@babylonjs/react-native';
import * as BABYLON from '@babylonjs/core';
const createScene = function (engine: BABYLON.Engine) {
// This creates a basic Babylon Scene object (non-mesh)
const scene = new BABYLON.Scene(engine);
// Create cameras
const numX = 2;
const numY = 3;
for (let i = 0; i < numX; ++i) {
for (let j = 0; j < numY; ++j) {
const x = 2 * i - numX + 1;
const y = 2 * j - numY + 1;
// This creates and positions a free camera (non-mesh)
const camera = new BABYLON.FreeCamera(
`camera-${i}-${j}`,
new BABYLON.Vector3(x, y + 10, -10),
scene,
);
camera.viewport = new BABYLON.Viewport(
i / numX,
j / numY,
1 / numX,
1 / numY,
);
camera.setTarget(new BABYLON.Vector3(x, y, 0));
scene.activeCameras!.push(camera);
}
}
// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
const light = new BABYLON.HemisphericLight(
'light',
new BABYLON.Vector3(0, 1, 0),
scene,
);
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;
// Our built-in 'sphere' shape.
const sphere = BABYLON.MeshBuilder.CreateSphere(
'sphere',
{diameter: 2, segments: 32},
scene,
);
// Move the sphere upward 1/2 its height
sphere.position.y = 1;
// Our built-in 'ground' shape.
BABYLON.MeshBuilder.CreateGround('ground', {width: 6, height: 6}, scene);
return scene;
};
const App = () => {
const engine = useEngine();
const [scene, setScene] = useState<BABYLON.Scene>();
useEffect(() => {
if (engine) {
setScene(createScene(engine));
}
}, [engine]);
return (
<View style={{flex: 1}}>
<Text>Hello Babylon</Text>
<EngineView camera={scene?.activeCamera!} displayFrameRate={true} />
</View>
);
};
export default App;