/
GLThreeDepthStencilBuffer.tsx
121 lines (101 loc) · 3.18 KB
/
GLThreeDepthStencilBuffer.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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,
},
});