Skip to content

Commit e1fa729

Browse files
authored
WebGPURenderer: Support Scene.backgroundRotation. (#1367)
* WebGPURenderer: Support Scene.backgroundRotation. * Update three.js * Add src * Update patch and delete src * Add examples * Update patch and delete examples
1 parent 3da584d commit e1fa729

38 files changed

+5993
-39
lines changed

examples-testing/changes.patch

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14103,10 +14103,10 @@ index 54d26d65..824c087a 100644
1410314103

1410414104
mesh = new THREE.Mesh(geometry, material);
1410514105
diff --git a/examples-testing/examples/webgpu_materials_envmaps.ts b/examples-testing/examples/webgpu_materials_envmaps.ts
14106-
index f49b4ca1..73c27f5c 100644
14106+
index 012a5065..6ca474e3 100644
1410714107
--- a/examples-testing/examples/webgpu_materials_envmaps.ts
1410814108
+++ b/examples-testing/examples/webgpu_materials_envmaps.ts
14109-
@@ -1,11 +1,13 @@
14109+
@@ -1,11 +1,20 @@
1411014110
-import * as THREE from 'three';
1411114111
+import * as THREE from 'three/webgpu';
1411214112

@@ -14120,7 +14120,14 @@ index f49b4ca1..73c27f5c 100644
1412014120
+let textureEquirec: THREE.Texture, textureCube: THREE.CubeTexture;
1412114121
+let sphereMesh: THREE.Mesh,
1412214122
+ sphereMaterial: THREE.MeshBasicMaterial,
14123-
+ params: { Cube: () => void; Equirectangular: () => void; Refraction: boolean };
14123+
+ params: {
14124+
+ Cube: () => void;
14125+
+ Equirectangular: () => void;
14126+
+ Refraction: boolean;
14127+
+ backgroundRotationX: boolean;
14128+
+ backgroundRotationY: boolean;
14129+
+ backgroundRotationZ: boolean;
14130+
+ };
1412414131

1412514132
init();
1412614133

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import * as THREE from 'three';
2+
3+
import Stats from 'three/addons/libs/stats.module.js';
4+
5+
let stats: Stats, clock: THREE.Clock;
6+
let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, mixer: THREE.AnimationMixer;
7+
8+
init();
9+
10+
function init() {
11+
scene = new THREE.Scene();
12+
13+
//
14+
15+
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000);
16+
camera.position.set(25, 25, 50);
17+
camera.lookAt(scene.position);
18+
19+
//
20+
21+
const axesHelper = new THREE.AxesHelper(10);
22+
scene.add(axesHelper);
23+
24+
//
25+
26+
const geometry = new THREE.BoxGeometry(5, 5, 5);
27+
const material = new THREE.MeshBasicMaterial({
28+
color: 0xffffff,
29+
transparent: true,
30+
});
31+
const mesh = new THREE.Mesh(geometry, material);
32+
scene.add(mesh);
33+
34+
// create a keyframe track (i.e. a timed sequence of keyframes) for each animated property
35+
// Note: the keyframe track type should correspond to the type of the property being animated
36+
37+
// POSITION
38+
const positionKF = new THREE.VectorKeyframeTrack('.position', [0, 1, 2], [0, 0, 0, 30, 0, 0, 0, 0, 0]);
39+
40+
// SCALE
41+
const scaleKF = new THREE.VectorKeyframeTrack('.scale', [0, 1, 2], [1, 1, 1, 2, 2, 2, 1, 1, 1]);
42+
43+
// ROTATION
44+
// Rotation should be performed using quaternions, using a THREE.QuaternionKeyframeTrack
45+
// Interpolating Euler angles (.rotation property) can be problematic and is currently not supported
46+
47+
// set up rotation about x axis
48+
const xAxis = new THREE.Vector3(1, 0, 0);
49+
50+
const qInitial = new THREE.Quaternion().setFromAxisAngle(xAxis, 0);
51+
const qFinal = new THREE.Quaternion().setFromAxisAngle(xAxis, Math.PI);
52+
const quaternionKF = new THREE.QuaternionKeyframeTrack(
53+
'.quaternion',
54+
[0, 1, 2],
55+
[
56+
qInitial.x,
57+
qInitial.y,
58+
qInitial.z,
59+
qInitial.w,
60+
qFinal.x,
61+
qFinal.y,
62+
qFinal.z,
63+
qFinal.w,
64+
qInitial.x,
65+
qInitial.y,
66+
qInitial.z,
67+
qInitial.w,
68+
],
69+
);
70+
71+
// COLOR
72+
const colorKF = new THREE.ColorKeyframeTrack(
73+
'.material.color',
74+
[0, 1, 2],
75+
[1, 0, 0, 0, 1, 0, 0, 0, 1],
76+
THREE.InterpolateDiscrete,
77+
);
78+
79+
// OPACITY
80+
const opacityKF = new THREE.NumberKeyframeTrack('.material.opacity', [0, 1, 2], [1, 0, 1]);
81+
82+
// create an animation sequence with the tracks
83+
// If a negative time value is passed, the duration will be calculated from the times of the passed tracks array
84+
const clip = new THREE.AnimationClip('Action', 3, [scaleKF, positionKF, quaternionKF, colorKF, opacityKF]);
85+
86+
// setup the THREE.AnimationMixer
87+
mixer = new THREE.AnimationMixer(mesh);
88+
89+
// create a ClipAction and set it to play
90+
const clipAction = mixer.clipAction(clip);
91+
clipAction.play();
92+
93+
//
94+
95+
renderer = new THREE.WebGLRenderer({ antialias: true });
96+
renderer.setPixelRatio(window.devicePixelRatio);
97+
renderer.setSize(window.innerWidth, window.innerHeight);
98+
renderer.setAnimationLoop(animate);
99+
document.body.appendChild(renderer.domElement);
100+
101+
//
102+
103+
stats = new Stats();
104+
document.body.appendChild(stats.dom);
105+
106+
//
107+
108+
clock = new THREE.Clock();
109+
110+
//
111+
112+
window.addEventListener('resize', onWindowResize);
113+
}
114+
115+
function onWindowResize() {
116+
camera.aspect = window.innerWidth / window.innerHeight;
117+
camera.updateProjectionMatrix();
118+
119+
renderer.setSize(window.innerWidth, window.innerHeight);
120+
}
121+
122+
function animate() {
123+
const delta = clock.getDelta();
124+
125+
if (mixer) {
126+
mixer.update(delta);
127+
}
128+
129+
renderer.render(scene, camera);
130+
131+
stats.update();
132+
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import * as THREE from 'three';
2+
3+
import Stats from 'three/addons/libs/stats.module.js';
4+
5+
let container: HTMLElement, stats: Stats;
6+
7+
let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
8+
9+
let mesh: THREE.Mesh;
10+
11+
init();
12+
animate();
13+
14+
function init() {
15+
container = document.getElementById('container')!;
16+
17+
//
18+
19+
camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500);
20+
camera.position.z = 2750;
21+
22+
scene = new THREE.Scene();
23+
scene.background = new THREE.Color(0x050505);
24+
scene.fog = new THREE.Fog(0x050505, 2000, 3500);
25+
26+
//
27+
28+
scene.add(new THREE.AmbientLight(0xcccccc));
29+
30+
const light1 = new THREE.DirectionalLight(0xffffff, 1.5);
31+
light1.position.set(1, 1, 1);
32+
scene.add(light1);
33+
34+
const light2 = new THREE.DirectionalLight(0xffffff, 4.5);
35+
light2.position.set(0, -1, 0);
36+
scene.add(light2);
37+
38+
//
39+
40+
const triangles = 160000;
41+
42+
const geometry = new THREE.BufferGeometry();
43+
44+
const positions = [];
45+
const normals = [];
46+
const colors = [];
47+
48+
const color = new THREE.Color();
49+
50+
const n = 800,
51+
n2 = n / 2; // triangles spread in the cube
52+
const d = 12,
53+
d2 = d / 2; // individual triangle size
54+
55+
const pA = new THREE.Vector3();
56+
const pB = new THREE.Vector3();
57+
const pC = new THREE.Vector3();
58+
59+
const cb = new THREE.Vector3();
60+
const ab = new THREE.Vector3();
61+
62+
for (let i = 0; i < triangles; i++) {
63+
// positions
64+
65+
const x = Math.random() * n - n2;
66+
const y = Math.random() * n - n2;
67+
const z = Math.random() * n - n2;
68+
69+
const ax = x + Math.random() * d - d2;
70+
const ay = y + Math.random() * d - d2;
71+
const az = z + Math.random() * d - d2;
72+
73+
const bx = x + Math.random() * d - d2;
74+
const by = y + Math.random() * d - d2;
75+
const bz = z + Math.random() * d - d2;
76+
77+
const cx = x + Math.random() * d - d2;
78+
const cy = y + Math.random() * d - d2;
79+
const cz = z + Math.random() * d - d2;
80+
81+
positions.push(ax, ay, az);
82+
positions.push(bx, by, bz);
83+
positions.push(cx, cy, cz);
84+
85+
// flat face normals
86+
87+
pA.set(ax, ay, az);
88+
pB.set(bx, by, bz);
89+
pC.set(cx, cy, cz);
90+
91+
cb.subVectors(pC, pB);
92+
ab.subVectors(pA, pB);
93+
cb.cross(ab);
94+
95+
cb.normalize();
96+
97+
const nx = cb.x;
98+
const ny = cb.y;
99+
const nz = cb.z;
100+
101+
normals.push(nx, ny, nz);
102+
normals.push(nx, ny, nz);
103+
normals.push(nx, ny, nz);
104+
105+
// colors
106+
107+
const vx = x / n + 0.5;
108+
const vy = y / n + 0.5;
109+
const vz = z / n + 0.5;
110+
111+
color.setRGB(vx, vy, vz);
112+
113+
const alpha = Math.random();
114+
115+
colors.push(color.r, color.g, color.b, alpha);
116+
colors.push(color.r, color.g, color.b, alpha);
117+
colors.push(color.r, color.g, color.b, alpha);
118+
}
119+
120+
function disposeArray(this: THREE.BufferAttribute) {
121+
this.array = null as unknown as THREE.TypedArray;
122+
}
123+
124+
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3).onUpload(disposeArray));
125+
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3).onUpload(disposeArray));
126+
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4).onUpload(disposeArray));
127+
128+
geometry.computeBoundingSphere();
129+
130+
const material = new THREE.MeshPhongMaterial({
131+
color: 0xd5d5d5,
132+
specular: 0xffffff,
133+
shininess: 250,
134+
side: THREE.DoubleSide,
135+
vertexColors: true,
136+
transparent: true,
137+
});
138+
139+
mesh = new THREE.Mesh(geometry, material);
140+
scene.add(mesh);
141+
142+
//
143+
144+
renderer = new THREE.WebGLRenderer({ antialias: true });
145+
renderer.setPixelRatio(window.devicePixelRatio);
146+
renderer.setSize(window.innerWidth, window.innerHeight);
147+
renderer.setAnimationLoop(animate);
148+
container.appendChild(renderer.domElement);
149+
150+
//
151+
152+
stats = new Stats();
153+
container.appendChild(stats.dom);
154+
155+
//
156+
157+
window.addEventListener('resize', onWindowResize);
158+
}
159+
160+
function onWindowResize() {
161+
camera.aspect = window.innerWidth / window.innerHeight;
162+
camera.updateProjectionMatrix();
163+
164+
renderer.setSize(window.innerWidth, window.innerHeight);
165+
}
166+
167+
//
168+
169+
function animate() {
170+
const time = Date.now() * 0.001;
171+
172+
mesh.rotation.x = time * 0.25;
173+
mesh.rotation.y = time * 0.5;
174+
175+
renderer.render(scene, camera);
176+
177+
stats.update();
178+
}

0 commit comments

Comments
 (0)