ThorAILabs commited on
Commit
4648eaa
·
verified ·
1 Parent(s): f9ae603

add webgpu raytracing (kinda)

Browse files
Files changed (1) hide show
  1. index.html +114 -6
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>3D Scene Editor with Raytracing</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
@@ -12,6 +12,7 @@
12
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/OBJLoader.min.js"></script>
13
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/exporters/OBJExporter.min.js"></script>
14
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/exporters/STLExporter.min.js"></script>
 
15
  <style>
16
  #renderCanvas {
17
  width: 100%;
@@ -28,6 +29,16 @@
28
  .sidebar.collapsed {
29
  transform: translateX(-100%);
30
  }
 
 
 
 
 
 
 
 
 
 
31
  </style>
32
  </head>
33
  <body class="bg-gray-900 text-white h-screen flex overflow-hidden">
@@ -55,6 +66,24 @@
55
  <i class="fas fa-trash mr-1"></i> Clear
56
  </button>
57
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  </div>
59
 
60
  <!-- Lighting Controls -->
@@ -125,13 +154,14 @@
125
 
126
  <div class="p-4 border-t border-gray-700 text-xs text-gray-500">
127
  <p>3D Scene Editor v1.0</p>
128
- <p>With Raytracing support</p>
129
  </div>
130
  </div>
131
 
132
  <!-- Main Content -->
133
  <div class="flex-grow relative">
134
  <div id="renderCanvas"></div>
 
135
 
136
  <!-- Stats Panel -->
137
  <div id="stats" class="absolute top-2 right-2 bg-gray-800 bg-opacity-70 p-2 rounded text-xs">
@@ -156,6 +186,7 @@
156
  // Initialize Three.js scene
157
  let scene, camera, renderer, controls;
158
  let raytracingEnabled = false;
 
159
  let objects = [];
160
  let lights = [];
161
  let clock = new THREE.Clock();
@@ -166,7 +197,7 @@
166
  };
167
 
168
  // Initialize the application
169
- function init() {
170
  // Create scene
171
  scene = new THREE.Scene();
172
  scene.background = new THREE.Color(0x111111);
@@ -183,6 +214,29 @@
183
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
184
  document.getElementById('renderCanvas').appendChild(renderer.domElement);
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  // Add orbit controls
187
  controls = new THREE.OrbitControls(camera, renderer.domElement);
188
  controls.enableDamping = true;
@@ -224,7 +278,33 @@
224
  updateStats();
225
 
226
  // Render scene
227
- renderer.render(scene, camera);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  }
229
 
230
  // Update statistics display
@@ -249,6 +329,10 @@
249
  camera.aspect = window.innerWidth / window.innerHeight;
250
  camera.updateProjectionMatrix();
251
  renderer.setSize(window.innerWidth, window.innerHeight);
 
 
 
 
252
  });
253
 
254
  // Sidebar toggle
@@ -262,8 +346,32 @@
262
  // Raytracing toggle
263
  document.getElementById('toggleRaytracing').addEventListener('click', () => {
264
  raytracingEnabled = !raytracingEnabled;
265
- // In a real implementation, you would switch to a raytracing renderer here
266
- alert(raytracingEnabled ? 'Raytracing enabled (simulated)' : 'Raytracing disabled');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  });
268
 
269
  // Clear scene
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>3D Scene Editor with WebGPU Raytracing</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
 
12
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/OBJLoader.min.js"></script>
13
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/exporters/OBJExporter.min.js"></script>
14
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/exporters/STLExporter.min.js"></script>
15
+ <script src="https://cdn.jsdelivr.net/npm/webgpu-raytracing@latest/dist/webgpu-raytracing.umd.js"></script>
16
  <style>
17
  #renderCanvas {
18
  width: 100%;
 
29
  .sidebar.collapsed {
30
  transform: translateX(-100%);
31
  }
32
+ .render-mode {
33
+ position: absolute;
34
+ top: 10px;
35
+ left: 10px;
36
+ background: rgba(0,0,0,0.5);
37
+ padding: 5px 10px;
38
+ border-radius: 5px;
39
+ color: white;
40
+ font-size: 12px;
41
+ }
42
  </style>
43
  </head>
44
  <body class="bg-gray-900 text-white h-screen flex overflow-hidden">
 
66
  <i class="fas fa-trash mr-1"></i> Clear
67
  </button>
68
  </div>
69
+
70
+ <div id="raytraceSettings" class="bg-gray-700 p-2 rounded mt-2 hidden">
71
+ <h3 class="text-sm font-medium mb-1">Raytrace Settings</h3>
72
+ <div class="space-y-2 text-xs">
73
+ <div>
74
+ <label>Bounces: <span id="bounceValue">3</span></label>
75
+ <input type="range" id="bounceSlider" min="1" max="10" value="3" class="w-full">
76
+ </div>
77
+ <div>
78
+ <label>Samples: <span id="sampleValue">4</span></label>
79
+ <input type="range" id="sampleSlider" min="1" max="16" value="4" class="w-full">
80
+ </div>
81
+ <div class="flex items-center">
82
+ <input type="checkbox" id="denoiseCheck" class="mr-2" checked>
83
+ <label for="denoiseCheck">Denoise</label>
84
+ </div>
85
+ </div>
86
+ </div>
87
  </div>
88
 
89
  <!-- Lighting Controls -->
 
154
 
155
  <div class="p-4 border-t border-gray-700 text-xs text-gray-500">
156
  <p>3D Scene Editor v1.0</p>
157
+ <p>With WebGPU Raytracing</p>
158
  </div>
159
  </div>
160
 
161
  <!-- Main Content -->
162
  <div class="flex-grow relative">
163
  <div id="renderCanvas"></div>
164
+ <div id="renderMode" class="render-mode">Rasterization</div>
165
 
166
  <!-- Stats Panel -->
167
  <div id="stats" class="absolute top-2 right-2 bg-gray-800 bg-opacity-70 p-2 rounded text-xs">
 
186
  // Initialize Three.js scene
187
  let scene, camera, renderer, controls;
188
  let raytracingEnabled = false;
189
+ let raytracingRenderer;
190
  let objects = [];
191
  let lights = [];
192
  let clock = new THREE.Clock();
 
197
  };
198
 
199
  // Initialize the application
200
+ async function init() {
201
  // Create scene
202
  scene = new THREE.Scene();
203
  scene.background = new THREE.Color(0x111111);
 
214
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
215
  document.getElementById('renderCanvas').appendChild(renderer.domElement);
216
 
217
+ // Initialize WebGPU raytracing renderer
218
+ try {
219
+ raytracingRenderer = new WebGPURaytracingRenderer({
220
+ canvas: document.createElement('canvas'),
221
+ width: window.innerWidth,
222
+ height: window.innerHeight
223
+ });
224
+
225
+ await raytracingRenderer.init();
226
+
227
+ // Configure raytracing settings
228
+ raytracingRenderer.setBounces(3);
229
+ raytracingRenderer.setSamples(4);
230
+ raytracingRenderer.setDenoise(true);
231
+
232
+ console.log("WebGPU Raytracing initialized successfully");
233
+ } catch (e) {
234
+ console.error("Failed to initialize WebGPU raytracing:", e);
235
+ document.getElementById('toggleRaytracing').disabled = true;
236
+ document.getElementById('toggleRaytracing').classList.add('opacity-50', 'cursor-not-allowed');
237
+ document.getElementById('toggleRaytracing').title = "WebGPU not supported in your browser";
238
+ }
239
+
240
  // Add orbit controls
241
  controls = new THREE.OrbitControls(camera, renderer.domElement);
242
  controls.enableDamping = true;
 
278
  updateStats();
279
 
280
  // Render scene
281
+ if (raytracingEnabled && raytracingRenderer) {
282
+ // Update raytracing renderer with current scene
283
+ raytracingRenderer.setCamera(camera);
284
+ raytracingRenderer.setScene(scene);
285
+
286
+ // Render with raytracing
287
+ raytracingRenderer.render();
288
+
289
+ // Display the raytraced result
290
+ renderer.domElement.style.display = 'none';
291
+ raytracingRenderer.canvas.style.display = 'block';
292
+ raytracingRenderer.canvas.style.width = '100%';
293
+ raytracingRenderer.canvas.style.height = '100%';
294
+
295
+ if (!document.getElementById('renderCanvas').contains(raytracingRenderer.canvas)) {
296
+ document.getElementById('renderCanvas').appendChild(raytracingRenderer.canvas);
297
+ }
298
+ } else {
299
+ // Regular rasterization rendering
300
+ renderer.render(scene, camera);
301
+
302
+ // Hide raytracing canvas if visible
303
+ if (raytracingRenderer && raytracingRenderer.canvas) {
304
+ raytracingRenderer.canvas.style.display = 'none';
305
+ }
306
+ renderer.domElement.style.display = 'block';
307
+ }
308
  }
309
 
310
  // Update statistics display
 
329
  camera.aspect = window.innerWidth / window.innerHeight;
330
  camera.updateProjectionMatrix();
331
  renderer.setSize(window.innerWidth, window.innerHeight);
332
+
333
+ if (raytracingRenderer) {
334
+ raytracingRenderer.setSize(window.innerWidth, window.innerHeight);
335
+ }
336
  });
337
 
338
  // Sidebar toggle
 
346
  // Raytracing toggle
347
  document.getElementById('toggleRaytracing').addEventListener('click', () => {
348
  raytracingEnabled = !raytracingEnabled;
349
+ document.getElementById('raytraceSettings').classList.toggle('hidden', !raytracingEnabled);
350
+ document.getElementById('renderMode').textContent = raytracingEnabled ? 'Raytracing' : 'Rasterization';
351
+
352
+ if (raytracingEnabled && !raytracingRenderer) {
353
+ alert('WebGPU raytracing is not available in your browser');
354
+ raytracingEnabled = false;
355
+ document.getElementById('raytraceSettings').classList.add('hidden');
356
+ document.getElementById('renderMode').textContent = 'Rasterization';
357
+ }
358
+ });
359
+
360
+ // Raytracing settings
361
+ document.getElementById('bounceSlider').addEventListener('input', (e) => {
362
+ const value = parseInt(e.target.value);
363
+ document.getElementById('bounceValue').textContent = value;
364
+ if (raytracingRenderer) raytracingRenderer.setBounces(value);
365
+ });
366
+
367
+ document.getElementById('sampleSlider').addEventListener('input', (e) => {
368
+ const value = parseInt(e.target.value);
369
+ document.getElementById('sampleValue').textContent = value;
370
+ if (raytracingRenderer) raytracingRenderer.setSamples(value);
371
+ });
372
+
373
+ document.getElementById('denoiseCheck').addEventListener('change', (e) => {
374
+ if (raytracingRenderer) raytracingRenderer.setDenoise(e.target.checked);
375
  });
376
 
377
  // Clear scene