<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">

  {

    "imports": {

      "three": "https://unpkg.com/three@0.155/build/three.module.js", 

      "three/addons/": "https://unpkg.com/three@0.155/examples/jsm/",

      "three/nodes": "https://unpkg.com/three@0.155/examples/jsm/nodes/Nodes.js"

    }

  }

</script>
body{

  overflow: hidden;

  margin: 0;

}
import * as THREE from "three";
import {texture, uv, MeshBasicNodeMaterial, attribute, uniform, vec3, vec4, wgslFn, float } from 'three/nodes';
import {OrbitControls} from "three/addons/controls/OrbitControls.js";
import Stats from "three/addons/libs/stats.module.js";
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';


let scene = new THREE.Scene();
scene.background = new THREE.Color(0x00001f);
let renderer = new WebGPURenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
let camera = new THREE.PerspectiveCamera(50.0, window.innerWidth/window.innerHeight, 0.5, 10000);

camera.position.set(3, 3, 3);

let controls = new OrbitControls(camera, renderer.domElement);
let material;

window.addEventListener("resize", onWindowResize, false);

init();
render();


function init() {
  
  


  
  const uvTexture = new THREE.TextureLoader().load('https://picsum.photos/670/670');
  const textureNode = texture( uvTexture );
 
  
  const wgslPositionParams = {
		time: uniform(0),
		position: attribute('position'),
	}
  
  const wgslPositionShader = wgslFn(`
    fn mainFunction(
		  time: f32,
			position: vec3<f32>,
		) -> vec4<f32> {

		  return vec4<f32>(position * (1.2 + 0.25 * sin(time)), 1.0);						
    }
  `);
  
  
  const wgslColorParams = {
		tex: textureNode, 
		tex_sampler: textureNode, 
		uv: uv(),
    opacity: uniform(0.9)
	}
  
  const wgslColorShader = wgslFn(` 
    fn mainFunction(
      tex: texture_2d<f32>, 
      tex_sampler: sampler, 
      uv:vec2<f32>,
      opacity: f32,
    ) -> vec4<f32> {
    
      var sample1 = textureSample( tex, tex_sampler, uv );
      var sigDist: f32 = median(sample1.r, sample1.g, sample1.b) - 0.5;
      var alpha: f32 = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);
     
      var outColor: vec4<f32> = sample1;
     
      return vec4<f32>(outColor);
    }
   
    fn median(r: f32, g: f32, b: f32) -> f32 {
      return max(min(r, g), min(max(r, g), b));
    } 
  `);
  

	material = new MeshBasicNodeMaterial();
  material.positionNode = wgslPositionShader(wgslPositionParams);
	material.colorNode = wgslColorShader(wgslColorParams);
	


	const geometry = new THREE.BoxGeometry();
	let cube = new THREE.Mesh(geometry, material);
	scene.add(cube);
  
}


function render() {
  requestAnimationFrame(render);
  
  material.positionNode.parameters.time.value += 0.005;
  
  renderer.render(scene, camera);
}


function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.