|
34 | 34 | <script type="module"> |
35 | 35 |
|
36 | 36 | import * as THREE from 'three/webgpu'; |
37 | | - import * as TSL from 'three/tsl'; |
38 | 37 |
|
39 | | - import { Fn, wgslFn, positionLocal, scriptable, positionWorld, normalLocal, normalWorld, normalView, color, texture, uv, float, vec2, vec3, vec4, oscSine, triplanarTexture, screenUV, js, string, Loop, cameraProjectionMatrix, ScriptableNodeResources } from 'three/tsl'; |
| 38 | + import { Fn, wgslFn, positionLocal, positionWorld, normalLocal, normalWorld, normalView, color, texture, uv, float, vec2, vec3, vec4, oscSine, triplanarTexture, screenUV, Loop, cameraProjectionMatrix } from 'three/tsl'; |
40 | 39 |
|
41 | 40 | import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; |
42 | 41 | import WebGPU from 'three/addons/capabilities/WebGPU.js'; |
|
254 | 253 |
|
255 | 254 | } ); |
256 | 255 |
|
257 | | - // Scriptable |
258 | | - |
259 | | - ScriptableNodeResources.set( 'TSL', TSL ); |
260 | | - |
261 | | - const asyncNode = scriptable( js( ` |
262 | | -
|
263 | | - layout = { |
264 | | - outputType: 'node' |
265 | | - }; |
266 | | -
|
267 | | - const { float } = TSL; |
268 | | -
|
269 | | - function init() { |
270 | | -
|
271 | | - setTimeout( () => { |
272 | | -
|
273 | | - local.set( 'result', float( 1.0 ) ); |
274 | | -
|
275 | | - refresh(); // refresh the node |
276 | | -
|
277 | | - }, 1000 ); |
278 | | -
|
279 | | - return float( 0.0 ); |
280 | | -
|
281 | | - } |
282 | | -
|
283 | | - function main() { |
284 | | -
|
285 | | - const result = local.get( 'result', init ); |
286 | | -
|
287 | | - //console.log( 'result', result ); |
288 | | -
|
289 | | - return result; |
290 | | -
|
291 | | - } |
292 | | -
|
293 | | - ` ) ); |
294 | | - |
295 | | - const scriptableNode = scriptable( js( ` |
296 | | -
|
297 | | - layout = { |
298 | | - outputType: 'node', |
299 | | - elements: [ |
300 | | - { name: 'source', inputType: 'node' }, |
301 | | - { name: 'contrast', inputType: 'node' }, |
302 | | - { name: 'vector3', inputType: 'Vector3' }, |
303 | | - { name: 'message', inputType: 'string' }, |
304 | | - { name: 'binary', inputType: 'ArrayBuffer' }, |
305 | | - { name: 'object3d', inputType: 'Object3D' }, |
306 | | - { name: 'execFrom', inputType: 'string' } |
307 | | - ] |
308 | | - }; |
309 | | -
|
310 | | - const { saturation, float, oscSine, mul } = TSL; |
311 | | -
|
312 | | - function helloWorld() { |
313 | | -
|
314 | | - console.log( "Hello World!" ); |
315 | | -
|
316 | | - } |
317 | | -
|
318 | | - function main() { |
319 | | -
|
320 | | - const source = parameters.get( 'source' ) || float(); |
321 | | - const contrast = parameters.get( 'contrast' ) || float(); |
322 | | -
|
323 | | - const material = local.get( 'material' ); |
324 | | -
|
325 | | - //console.log( 'vector3', parameters.get( 'vector3' ) ); |
326 | | -
|
327 | | - if ( parameters.get( 'execFrom' ) === 'serialized' ) { |
328 | | -
|
329 | | - //console.log( 'message', parameters.get( 'message' ).value ); |
330 | | - //console.log( 'binary', parameters.get( 'binary' ) ); |
331 | | - //console.log( 'object3d', parameters.get( 'object3d' ) ); // unserializable yet |
332 | | -
|
333 | | - //console.log( global.get( 'renderer' ) ); |
334 | | -
|
335 | | - } |
336 | | -
|
337 | | - if ( material ) material.needsUpdate = true; |
338 | | -
|
339 | | - return mul( saturation( source, oscSine() ), contrast ); |
340 | | -
|
341 | | - } |
342 | | -
|
343 | | - output = { helloWorld }; |
344 | | -
|
345 | | - ` ) ); |
346 | | - |
347 | | - scriptableNode.setParameter( 'source', texture( uvTexture ).xyz ); |
348 | | - scriptableNode.setParameter( 'contrast', asyncNode ); |
349 | | - scriptableNode.setParameter( 'vector3', vec3( new THREE.Vector3( 1, 1, 1 ) ) ); |
350 | | - scriptableNode.setParameter( 'message', string( 'Hello World!' ) ); |
351 | | - scriptableNode.setParameter( 'binary', new ArrayBuffer( 4 ) ); |
352 | | - scriptableNode.setParameter( 'object3d', new THREE.Group() ); |
353 | | - |
354 | | - scriptableNode.call( 'helloWorld' ); |
355 | | - |
356 | | - material = new THREE.MeshBasicNodeMaterial(); |
357 | | - material.colorNode = scriptableNode; |
358 | | - materials.push( material ); |
359 | | - |
360 | | - scriptableNode.setLocal( 'material', material ); |
361 | | - |
362 | 256 | // |
363 | 257 | // Geometry |
364 | 258 | // |
|
371 | 265 |
|
372 | 266 | } |
373 | 267 |
|
374 | | - const serializeMesh = scene.children[ scene.children.length - 1 ]; |
375 | | - |
376 | 268 | // |
377 | 269 |
|
378 | 270 | renderer = new THREE.WebGPURenderer( { antialias: true } ); |
|
386 | 278 |
|
387 | 279 | window.addEventListener( 'resize', onWindowResize ); |
388 | 280 |
|
389 | | - // |
390 | | - |
391 | | - setTimeout( () => testSerialization( serializeMesh ), 1000 ); |
392 | | - |
393 | 281 | } |
394 | 282 |
|
395 | 283 | function addMesh( geometry, material ) { |
|
409 | 297 |
|
410 | 298 | } |
411 | 299 |
|
412 | | - function moduleToLib( module ) { |
413 | | - |
414 | | - const lib = {}; |
415 | | - |
416 | | - for ( const nodeElement of Object.values( module ) ) { |
417 | | - |
418 | | - if ( typeof nodeElement === 'function' && nodeElement.type !== undefined ) { |
419 | | - |
420 | | - lib[ nodeElement.type ] = nodeElement; |
421 | | - |
422 | | - } |
423 | | - |
424 | | - } |
425 | | - |
426 | | - return lib; |
427 | | - |
428 | | - } |
429 | | - |
430 | | - function testSerialization( mesh ) { |
431 | | - |
432 | | - const json = mesh.toJSON(); |
433 | | - const loader = new THREE.NodeObjectLoader().setNodes( moduleToLib( THREE ) ).setNodeMaterials( moduleToLib( THREE ) ); |
434 | | - const serializedMesh = loader.parse( json, () => { |
435 | | - |
436 | | - serializedMesh.position.x = ( objects.length % 4 ) * 200 - 400; |
437 | | - serializedMesh.position.z = Math.floor( objects.length / 4 ) * 200 - 200; |
438 | | - |
439 | | - const scriptableNode = serializedMesh.material.colorNode; |
440 | | - |
441 | | - // it's because local.get( 'material' ) is used in the example ( local/global is unserializable ) |
442 | | - scriptableNode.setLocal( 'material', serializedMesh.material ); |
443 | | - scriptableNode.setParameter( 'execFrom', 'serialized' ); |
444 | | - |
445 | | - objects.push( serializedMesh ); |
446 | | - |
447 | | - scene.add( serializedMesh ); |
448 | | - |
449 | | - } ); |
450 | | - |
451 | | - } |
452 | | - |
453 | 300 | function onWindowResize() { |
454 | 301 |
|
455 | 302 | camera.aspect = window.innerWidth / window.innerHeight; |
|
0 commit comments