1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < title > three.js webgpu - dynamic cube reflection</ title >
5+ < meta charset ="utf-8 ">
6+ < meta name ="viewport " content ="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0 ">
7+ < link type ="text/css " rel ="stylesheet " href ="main.css ">
8+ < style >
9+ body {
10+ touch-action : none;
11+ }
12+ </ style >
13+ </ head >
14+ < body >
15+
16+ < div id ="info "> < a href ="https://threejs.org " target ="_blank " rel ="noopener "> three.js webgpu</ a > - dynamic cube reflection</ div >
17+
18+ <!-- Import maps polyfill -->
19+ <!-- Remove this when import maps will be widely supported -->
20+ < script async src ="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js "> </ script >
21+
22+ < script type ="importmap ">
23+ {
24+ "imports" : {
25+ "three" : "../build/three.module.js" ,
26+ "three/nodes" : "./jsm/nodes/Nodes.js" ,
27+ "three/addons/" : "./jsm/"
28+ }
29+ }
30+ </ script >
31+
32+ < script type ="module ">
33+
34+ import * as THREE from 'three' ;
35+ import * as Nodes from 'three/nodes' ;
36+
37+ import WebGPU from 'three/addons/capabilities/WebGPU.js' ;
38+ import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js' ;
39+
40+ import { OrbitControls } from 'three/addons/controls/OrbitControls.js' ;
41+ import { RGBMLoader } from 'three/addons/loaders/RGBMLoader.js' ;
42+
43+ import { GUI } from 'three/addons/libs/lil-gui.module.min.js' ;
44+ import Stats from 'three/addons/libs/stats.module.js' ;
45+
46+ let camera , scene , renderer , stats ;
47+ let cube , sphere , torus , material ;
48+
49+ let cubeCamera , cubeRenderTarget ;
50+
51+ let controls ;
52+
53+ init ( ) ;
54+
55+ function init ( ) {
56+
57+ if ( WebGPU . isAvailable ( ) === false ) {
58+
59+ document . body . appendChild ( WebGPU . getErrorMessage ( ) ) ;
60+
61+ throw new Error ( 'No WebGPU support' ) ;
62+
63+ }
64+
65+ renderer = new WebGPURenderer ( /*{ antialias: true }*/ ) ;
66+ renderer . setPixelRatio ( window . devicePixelRatio ) ;
67+ renderer . setSize ( window . innerWidth , window . innerHeight ) ;
68+ renderer . setAnimationLoop ( animation ) ;
69+ renderer . toneMapping = THREE . ACESFilmicToneMapping ;
70+ document . body . appendChild ( renderer . domElement ) ;
71+
72+ window . addEventListener ( 'resize' , onWindowResized ) ;
73+
74+ stats = new Stats ( ) ;
75+ document . body . appendChild ( stats . dom ) ;
76+
77+ camera = new THREE . PerspectiveCamera ( 60 , window . innerWidth / window . innerHeight , 1 , 1000 ) ;
78+ camera . position . z = 75 ;
79+
80+ scene = new THREE . Scene ( ) ;
81+
82+ const uvTexture = new THREE . TextureLoader ( ) . load ( './textures/uv_grid_opengl.jpg' ) ;
83+
84+ const rgbmUrls = [ 'px.png' , 'nx.png' , 'py.png' , 'ny.png' , 'pz.png' , 'nz.png' ] ;
85+ const texture = new RGBMLoader ( )
86+ . setMaxRange ( 16 )
87+ . setPath ( './textures/cube/pisaRGBM16/' )
88+ . loadCubemap ( rgbmUrls ) ;
89+
90+ texture . name = 'pisaRGBM16' ;
91+ texture . minFilter = THREE . LinearMipmapLinearFilter ;
92+ texture . magFilter = THREE . LinearFilter ;
93+
94+ scene . background = texture ;
95+ scene . environment = texture ;
96+
97+ //
98+
99+ cubeRenderTarget = new THREE . WebGLCubeRenderTarget ( 256 ) ;
100+ cubeRenderTarget . texture . type = THREE . HalfFloatType ;
101+ cubeRenderTarget . texture . minFilter = THREE . LinearMipmapLinearFilter ;
102+ cubeRenderTarget . texture . magFilter = THREE . LinearFilter ;
103+ cubeRenderTarget . texture . generateMipmaps = true ;
104+
105+ cubeCamera = new THREE . CubeCamera ( 1 , 1000 , cubeRenderTarget ) ;
106+
107+ //
108+
109+ material = new Nodes . MeshStandardNodeMaterial ( {
110+ envMap : cubeRenderTarget . texture ,
111+ roughness : 0.05 ,
112+ metalness : 1
113+ } ) ;
114+
115+ const gui = new GUI ( ) ;
116+ gui . add ( material , 'roughness' , 0 , 1 ) ;
117+ gui . add ( material , 'metalness' , 0 , 1 ) ;
118+ gui . add ( renderer , 'toneMappingExposure' , 0 , 2 ) . name ( 'exposure' ) ;
119+
120+ sphere = new THREE . Mesh ( new THREE . IcosahedronGeometry ( 15 , 8 ) , material ) ;
121+ scene . add ( sphere ) ;
122+
123+ const material2 = new THREE . MeshStandardMaterial ( {
124+ map : uvTexture ,
125+ roughness : 0.1 ,
126+ metalness : 0
127+ } ) ;
128+
129+ cube = new THREE . Mesh ( new THREE . BoxGeometry ( 15 , 15 , 15 ) , material2 ) ;
130+ scene . add ( cube ) ;
131+
132+ torus = new THREE . Mesh ( new THREE . TorusKnotGeometry ( 8 , 3 , 128 , 16 ) , material2 ) ;
133+ scene . add ( torus ) ;
134+
135+ //
136+
137+ controls = new OrbitControls ( camera , renderer . domElement ) ;
138+ controls . autoRotate = true ;
139+
140+ }
141+
142+ function onWindowResized ( ) {
143+
144+ renderer . setSize ( window . innerWidth , window . innerHeight ) ;
145+
146+ camera . aspect = window . innerWidth / window . innerHeight ;
147+ camera . updateProjectionMatrix ( ) ;
148+
149+ }
150+
151+ function animation ( msTime ) {
152+
153+ const time = msTime / 1000 ;
154+
155+ cube . position . x = Math . cos ( time ) * 30 ;
156+ cube . position . y = Math . sin ( time ) * 30 ;
157+ cube . position . z = Math . sin ( time ) * 30 ;
158+
159+ cube . rotation . x += 0.02 ;
160+ cube . rotation . y += 0.03 ;
161+
162+ torus . position . x = Math . cos ( time + 10 ) * 30 ;
163+ torus . position . y = Math . sin ( time + 10 ) * 30 ;
164+ torus . position . z = Math . sin ( time + 10 ) * 30 ;
165+
166+ torus . rotation . x += 0.02 ;
167+ torus . rotation . y += 0.03 ;
168+
169+ material . visible = false ;
170+
171+ cubeCamera . update ( renderer , scene ) ;
172+
173+ material . visible = true ;
174+
175+ controls . update ( ) ;
176+
177+ renderer . render ( scene , camera ) ;
178+
179+ stats . update ( ) ;
180+
181+ }
182+
183+ </ script >
184+
185+ </ body >
186+ </ html >
0 commit comments