123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- <html lang="en">
- <head>
- <title>three.js webgpu - shadertoy</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <link type="text/css" rel="stylesheet" href="main.css">
- </head>
- <body>
- <div id="info">
- <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgpu - shadertoy
- <br />Shader created by <a href="https://www.shadertoy.com/view/Mt2SzR" target="_blank" rel="noopener">jackdavenport</a> and <a href="https://www.shadertoy.com/view/3tcBzH" target="_blank" rel="noopener">trinketMage</a>.
- </div>
- <script type="importmap">
- {
- "imports": {
- "three": "../build/three.webgpu.js",
- "three/tsl": "../build/three.webgpu.js",
- "three/addons/": "./jsm/"
- }
- }
- </script>
- <script type="x-shader/x-fragment" id="example1">
- // https://www.shadertoy.com/view/Mt2SzR
- float random(float x) {
-
- return fract(sin(x) * 10000.);
-
- }
-
- float noise(vec2 p) {
-
- return random(p.x + p.y * 10000.);
-
- }
-
- vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
- vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
- vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
- vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }
-
- float smoothNoise(vec2 p) {
-
- vec2 interp = smoothstep(0., 1., fract(p));
- float s = mix(noise(sw(p)), noise(se(p)), interp.x);
- float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
- return mix(s, n, interp.y);
-
- }
-
- float fractalNoise(vec2 p) {
-
- float x = 0.;
- x += smoothNoise(p );
- x += smoothNoise(p * 2. ) / 2.;
- x += smoothNoise(p * 4. ) / 4.;
- x += smoothNoise(p * 8. ) / 8.;
- x += smoothNoise(p * 16.) / 16.;
- x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
- return x;
-
- }
-
- float movingNoise(vec2 p) {
-
- float x = fractalNoise(p + iTime);
- float y = fractalNoise(p - iTime);
- return fractalNoise(p + vec2(x, y));
-
- }
-
- // call this for water noise function
- float nestedNoise(vec2 p) {
-
- float x = movingNoise(p);
- float y = movingNoise(p + 100.);
- return movingNoise(p + vec2(x, y));
-
- }
- void mainImage( out vec4 fragColor, in vec2 fragCoord )
- {
- vec2 uv = fragCoord.xy / iResolution.xy;
- float n = nestedNoise(uv * 6.);
- fragColor = vec4(mix(vec3(.4, .6, 1.), vec3(.1, .2, 1.), n), 1.);
- }
- </script>
- <script type="x-shader/x-fragment" id="example2">
- // https://www.shadertoy.com/view/3tcBzH
- float rand(vec2 co){
- return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
- }
-
- float hermite(float t)
- {
- return t * t * (3.0 - 2.0 * t);
- }
-
- float noise(vec2 co, float frequency)
- {
- vec2 v = vec2(co.x * frequency, co.y * frequency);
-
- float ix1 = floor(v.x);
- float iy1 = floor(v.y);
- float ix2 = floor(v.x + 1.0);
- float iy2 = floor(v.y + 1.0);
-
- float fx = hermite(fract(v.x));
- float fy = hermite(fract(v.y));
-
- float fade1 = mix(rand(vec2(ix1, iy1)), rand(vec2(ix2, iy1)), fx);
- float fade2 = mix(rand(vec2(ix1, iy2)), rand(vec2(ix2, iy2)), fx);
-
- return mix(fade1, fade2, fy);
- }
-
- float pnoise(vec2 co, float freq, int steps, float persistence)
- {
- float value = 0.0;
- float ampl = 1.0;
- float sum = 0.0;
- for(int i=0 ; i<steps ; i++)
- {
- sum += ampl;
- value += noise(co, freq) * ampl;
- freq *= 2.0;
- ampl *= persistence;
- }
- return value / sum;
- }
-
- void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
- vec2 uv = fragCoord.xy / iResolution.xy;
- float gradient = 1.0 - uv.y;
- float gradientStep = 0.2;
-
- vec2 pos = fragCoord.xy / iResolution.x;
- pos.y -= iTime * 0.3125;
-
- vec4 brighterColor = vec4(1.0, 0.65, 0.1, 0.25);
- vec4 darkerColor = vec4(1.0, 0.0, 0.15, 0.0625);
- vec4 middleColor = mix(brighterColor, darkerColor, 0.5);
-
- float noiseTexel = pnoise(pos, 10.0, 5, 0.5);
-
- float firstStep = smoothstep(0.0, noiseTexel, gradient);
- float darkerColorStep = smoothstep(0.0, noiseTexel, gradient - gradientStep);
- float darkerColorPath = firstStep - darkerColorStep;
- vec4 color = mix(brighterColor, darkerColor, darkerColorPath);
-
- float middleColorStep = smoothstep(0.0, noiseTexel, gradient - 0.2 * 2.0);
-
- color = mix(color, middleColor, darkerColorStep - middleColorStep);
- color = mix(vec4(0.0), color, firstStep);
- fragColor = color;
- }
- </script>
- <script type="module">
- import * as THREE from 'three';
- import * as TSL from 'three/tsl';
- import Transpiler from 'three/addons/transpiler/Transpiler.js';
- import ShaderToyDecoder from 'three/addons/transpiler/ShaderToyDecoder.js';
- import TSLEncoder from 'three/addons/transpiler/TSLEncoder.js';
- class ShaderToyNode extends THREE.Node {
- constructor() {
- super( 'vec4' );
- this.mainImage = null;
- }
- transpile( glsl, iife = false ) {
- const decoder = new ShaderToyDecoder();
- const encoder = new TSLEncoder();
- encoder.iife = iife;
- encoder.uniqueNames = true;
- const jsCode = new Transpiler( decoder, encoder ).parse( glsl );
- return jsCode;
- }
- parse( glsl ) {
- const jsCode = this.transpile( glsl, true );
- const { mainImage } = eval( jsCode )( TSL );
- this.mainImage = mainImage;
- }
- async parseAsync( glsl ) {
- const jsCode = this.transpile( glsl );
- const { mainImage } = await import( `data:text/javascript,${ encodeURIComponent( jsCode ) }` );
- this.mainImage = mainImage;
- }
- setup( builder ) {
- if ( this.mainImage === null ) {
- throw new Error( 'ShaderToyNode: .parse() must be called first.' );
- }
- return this.mainImage();
- }
- }
- let renderer, camera, scene;
- const dpr = window.devicePixelRatio;
- init();
- function init() {
- const example1Code = document.getElementById( 'example1' ).textContent;
- const example2Code = document.getElementById( 'example2' ).textContent;
- const shaderToy1Node = new ShaderToyNode();
- shaderToy1Node.parse( example1Code );
- const shaderToy2Node = new ShaderToyNode();
- shaderToy2Node.parse( example2Code );
- //
- camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
- scene = new THREE.Scene();
- const geometry = new THREE.PlaneGeometry( 2, 2 );
- const material = new THREE.MeshBasicNodeMaterial();
- material.colorNode = TSL.oscSine( TSL.timerLocal( .3 ) ).mix( shaderToy1Node, shaderToy2Node );
- const quad = new THREE.Mesh( geometry, material );
- scene.add( quad );
- //
- renderer = new THREE.WebGPURenderer( { antialias: true } );
- renderer.setPixelRatio( dpr );
- renderer.setSize( window.innerWidth, window.innerHeight );
- renderer.setAnimationLoop( animate );
- renderer.outputColorSpace = THREE.LinearSRGBColorSpace;
- document.body.appendChild( renderer.domElement );
- window.addEventListener( 'resize', onWindowResize );
- }
- function onWindowResize() {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- renderer.setSize( window.innerWidth, window.innerHeight );
- }
- function animate() {
- renderer.render( scene, camera );
- }
- </script>
- </body>
- </html>
|