Skip to content
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

[gl-cpp] Fix depth/stencil buffers not working correctly with three.js #7543

Merged
merged 4 commits into from Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/native-component-list/package.json
Expand Up @@ -101,7 +101,7 @@
"react-navigation-stack": "1.6.0-alpha.1",
"react-navigation-tabs": "^2.4.1",
"regl": "^1.3.0",
"three": "^0.109.0",
"three": "^0.115.0",
"url": "^0.11.0",
"uuid": "^3.1.0",
"victory-native": "^30.4.0"
Expand All @@ -120,4 +120,4 @@
"expo-module-scripts": "~1.2.0",
"expo-yarn-workspaces": "^1.2.1"
}
}
}
13 changes: 9 additions & 4 deletions apps/native-component-list/src/screens/GL/GLScreens.tsx
Expand Up @@ -15,6 +15,7 @@ import GLMaskScreen from './GLMaskScreen';
import GLSnapshotsScreen from './GLSnapshotsScreen';
import GLHeadlessRenderingScreen from './GLHeadlessRenderingScreen';
import ProcessingWrap from './ProcessingWrap';
import GLThreeDepthStencilBuffer from './GLThreeDepthStencilBuffer';

function optionalRequire(requirer: () => { default: React.ComponentType }) {
try {
Expand Down Expand Up @@ -175,6 +176,10 @@ const GLScreens: Screens = {
}),
},

THREEDepthStencilBuffer: {
screen: GLThreeDepthStencilBuffer,
},

THREEGlitchFilm: {
screen: GLWrap('three.js glitch and film effects', async gl => {
const scene = new THREE.Scene();
Expand All @@ -189,10 +194,10 @@ const GLScreens: Screens = {
renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
renderer.setClearColor(0xffffff);

const composer = new EffectComposer( renderer );
composer.addPass( new RenderPass( scene, camera ) );
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
const glitchPass = new GlitchPass();
composer.addPass( glitchPass );
composer.addPass(glitchPass);

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({
Expand Down Expand Up @@ -410,7 +415,7 @@ const GLScreens: Screens = {
...(GLCameraScreen && {
GLCamera: {
screen: GLCameraScreen,
}
},
}),

// WebGL 2.0 sample - http://webglsamples.org/WebGL2Samples/#transform_feedback_separated_2
Expand Down
@@ -0,0 +1,121 @@
import React from 'react';
import * as THREE from 'three';
import { StyleSheet, View } from 'react-native';
import { GLView, ExpoWebGLRenderingContext } from 'expo-gl';

export default class GLThreeDepthStencilBuffer extends React.PureComponent {
static title = 'three.js depth and stencil buffer';

animationFrameId: number = -1;

componentWillUnmount() {
if (this.animationFrameId >= 0) {
cancelAnimationFrame(this.animationFrameId);
}
}

onContextCreate = async (gl: ExpoWebGLRenderingContext) => {
const renderer = new THREE.WebGLRenderer({
context: gl,
});
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.BasicShadowMap;

renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
renderer.setClearColor(0xffffff, 1.0);
renderer.shadowMap.enabled = true;

// Standard Camera
const camera = new THREE.PerspectiveCamera(
70,
gl.drawingBufferWidth / gl.drawingBufferHeight,
0.1,
1000
);
camera.position.set(10, 10, 0);
camera.lookAt(0, 0, 0);

const scene = new THREE.Scene();

scene.add(new THREE.AmbientLight(0xffffff, 0.5));

// Three's lights use depth and stencil buffers.
const light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(0, 6, 0);
light.castShadow = true;
light.shadow.camera.left = -1;
light.shadow.camera.right = 1;
light.shadow.camera.top = -1;
light.shadow.camera.bottom = 1;
scene.add(light);

const shadowHelper = new THREE.DirectionalLightHelper(light, 2, 0x0000ff);
scene.add(shadowHelper);

// Create a plane that receives shadows (but does not cast them).
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10, 32, 32);
const planeMaterial = new THREE.MeshStandardMaterial({
color: 0x00ff00,
side: THREE.DoubleSide,
});

const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = Math.PI / 2;
plane.position.y = -2;
scene.add(plane);

const cube = new THREE.Mesh(
new THREE.BoxGeometry(1.2, 1.2, 1.2),
new THREE.MeshPhongMaterial({
color: 0xffff00,
})
);
cube.castShadow = true;
cube.receiveShadow = true;
cube.renderOrder = 3;
scene.add(cube);

const another = new THREE.Mesh(
new THREE.BoxGeometry(1.4, 1.4, 1.4),
new THREE.MeshPhongMaterial({
color: 0xff0000,
})
);
another.position.set(0, 2, 0);
another.castShadow = true;
another.receiveShadow = true;
another.renderOrder = 1;
scene.add(another);

const helper = new THREE.CameraHelper(light.shadow.camera);
scene.add(helper);

const animate = () => {
this.animationFrameId = requestAnimationFrame(animate);

cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
gl.endFrameEXP();
};

animate();
renderer.render(scene, camera);
gl.endFrameEXP();
};

render() {
return (
<View style={styles.flex}>
<GLView style={styles.flex} onContextCreate={this.onContextCreate} />
</View>
);
}
}

const styles = StyleSheet.create({
flex: {
flex: 1,
},
});
Binary file modified packages/expo-gl-cpp/android/dist/arm64-v8a/libexpo-gl.so
Binary file not shown.
Binary file modified packages/expo-gl-cpp/android/dist/armeabi-v7a/libexpo-gl.so
Binary file not shown.
Binary file modified packages/expo-gl-cpp/android/dist/x86/libexpo-gl.so
Binary file not shown.
Binary file modified packages/expo-gl-cpp/android/dist/x86_64/libexpo-gl.so
Binary file not shown.
5 changes: 5 additions & 0 deletions packages/expo-gl-cpp/cpp/EXGLNativeMethods.cpp
Expand Up @@ -534,6 +534,11 @@ _WRAP_METHOD_IS_OBJECT(Renderbuffer)

_WRAP_METHOD(renderbufferStorage, 4) {
EXJS_UNPACK_ARGV(GLenum target, GLint internalformat, GLsizei width, GLsizei height);

// WebGL allows `GL_DEPTH_STENCIL` flag to be passed here,
// however OpenGL ES seems to require sized format, so we fall back to `GL_DEPTH24_STENCIL8`.
internalformat = internalformat == GL_DEPTH_STENCIL ? GL_DEPTH24_STENCIL8 : internalformat;

addToNextBatch([=] {
glRenderbufferStorage(target, internalformat, width, height);
});
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-gl/CHANGELOG.md
Expand Up @@ -7,3 +7,5 @@
### 🎉 New features

### 🐛 Bug fixes

- Fix depth/stencil buffers not working correctly with `three.js`. ([#7543](https://github.com/expo/expo/pull/7543) by [@tsapeta](https://github.com/tsapeta))
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -18066,10 +18066,10 @@ thenify-all@^1.0.0:
dependencies:
any-promise "^1.0.0"

three@^0.109.0:
version "0.109.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.109.0.tgz#611c9ef860d10bd107695cead6c6abcd2422e5fd"
integrity sha512-XT99T3Hvgh2CEvwPdHYEunNE+clLK6KiT1U8En7YOgIqTUw4MrLeIc8zxQAJ6wbP8hhJaY5+Cff3jwBPpBa0gA==
three@^0.115.0:
version "0.115.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.115.0.tgz#540d800c381b9da2334c024f0fbe4d23f84eb05e"
integrity sha512-mAV2Ky3RdcbdSbR9capI+tKLvRldWYxd4151PZTT/o7+U2jh9Is3a4KmnYwzyUAhB2ZA3pXSgCd2DOY4Tj5kow==

throat@^4.0.0, throat@^4.1.0:
version "4.1.0"
Expand Down