-
-
Notifications
You must be signed in to change notification settings - Fork 36.4k
Expand file tree
/
Copy pathwebgpu_camera_array.html
More file actions
154 lines (103 loc) · 3.92 KB
/
webgpu_camera_array.html
File metadata and controls
154 lines (103 loc) · 3.92 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgpu - arraycamera</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="example.css">
</head>
<body>
<div id="info">
<a href="https://threejs.org/" target="_blank" rel="noopener" class="logo-link"></a>
<div class="title-wrapper">
<a href="https://threejs.org/" target="_blank" rel="noopener">three.js</a><span>Array Camera</span>
</div>
<small>Array cameras allow to render the scene with multiple sub cameras but with a single render call.</small>
</div>
<script type="importmap">
{
"imports": {
"three": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three/tsl": "../build/three.tsl.js",
"three/addons/": "./jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three/webgpu';
let camera, scene, renderer;
let mesh;
const AMOUNT = 6;
init();
function init() {
const subCameras = [];
for ( let i = 0; i < AMOUNT * AMOUNT; i ++ ) {
const subCamera = new THREE.PerspectiveCamera( 40, 1, 0.1, 10 );
subCamera.viewport = new THREE.Vector4();
subCameras.push( subCamera );
}
camera = new THREE.ArrayCamera( subCameras );
camera.position.z = 3;
updateCameras();
scene = new THREE.Scene();
scene.add( new THREE.AmbientLight( 0x999999 ) );
const light = new THREE.DirectionalLight( 0xffffff, 3 );
light.position.set( 0.5, 0.5, 1 );
light.castShadow = true;
light.shadow.camera.zoom = 4; // tighter shadow map
scene.add( light );
const geometryBackground = new THREE.PlaneGeometry( 100, 100 );
const materialBackground = new THREE.MeshPhongMaterial( { color: 0x000066 } );
const background = new THREE.Mesh( geometryBackground, materialBackground );
background.receiveShadow = true;
background.position.set( 0, 0, - 1 );
scene.add( background );
const geometryCylinder = new THREE.CylinderGeometry( 0.5, 0.5, 1, 32 );
const materialCylinder = new THREE.MeshPhongMaterial( { color: 0xff0000 } );
mesh = new THREE.Mesh( geometryCylinder, materialCylinder );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
renderer = new THREE.WebGPURenderer( /*{ forceWebGL: true }*/ );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animate );
renderer.shadowMap.enabled = true;
document.body.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize );
}
function updateCameras() {
const ASPECT_RATIO = window.innerWidth / window.innerHeight;
const WIDTH = window.innerWidth / AMOUNT;
const HEIGHT = window.innerHeight / AMOUNT;
camera.aspect = ASPECT_RATIO;
camera.updateProjectionMatrix();
for ( let y = 0; y < AMOUNT; y ++ ) {
for ( let x = 0; x < AMOUNT; x ++ ) {
const subcamera = camera.cameras[ AMOUNT * y + x ];
subcamera.copy( camera ); // copy fov, aspect ratio, near, far from the root camera
subcamera.viewport.set( Math.floor( x * WIDTH ), Math.floor( y * HEIGHT ), Math.ceil( WIDTH ), Math.ceil( HEIGHT ) );
subcamera.updateProjectionMatrix();
subcamera.position.x = ( x / AMOUNT ) - 0.5;
subcamera.position.y = 0.5 - ( y / AMOUNT );
subcamera.position.z = 1.5 + ( ( x + y ) * .5 );
subcamera.position.multiplyScalar( 2 );
subcamera.lookAt( 0, 0, 0 );
subcamera.updateMatrixWorld();
}
}
}
function onWindowResize() {
updateCameras();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
mesh.rotation.x += 0.005;
mesh.rotation.z += 0.01;
renderer.render( scene, camera );
}
</script>
</body>
</html>