webgpu_shadertoy.html 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <html lang="en">
  2. <head>
  3. <title>three.js webgpu - shadertoy</title>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  6. <link type="text/css" rel="stylesheet" href="example.css">
  7. </head>
  8. <body>
  9. <div id="info">
  10. <a href="https://threejs.org/" target="_blank" rel="noopener" class="logo-link"></a>
  11. <div class="title-wrapper">
  12. <a href="https://threejs.org/" target="_blank" rel="noopener">three.js</a><span>Shadertoy</span>
  13. </div>
  14. <small>
  15. 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>.
  16. </small>
  17. </div>
  18. <script type="importmap">
  19. {
  20. "imports": {
  21. "three": "../build/three.webgpu.js",
  22. "three/webgpu": "../build/three.webgpu.js",
  23. "three/tsl": "../build/three.tsl.js",
  24. "three/addons/": "./jsm/"
  25. }
  26. }
  27. </script>
  28. <script type="x-shader/x-fragment" id="example1">
  29. // https://www.shadertoy.com/view/Mt2SzR
  30. float random(float x) {
  31. return fract(sin(x) * 10000.);
  32. }
  33. float noise(vec2 p) {
  34. return random(p.x + p.y * 10000.);
  35. }
  36. vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
  37. vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
  38. vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
  39. vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }
  40. float smoothNoise(vec2 p) {
  41. vec2 interp = smoothstep(0., 1., fract(p));
  42. float s = mix(noise(sw(p)), noise(se(p)), interp.x);
  43. float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
  44. return mix(s, n, interp.y);
  45. }
  46. float fractalNoise(vec2 p) {
  47. float x = 0.;
  48. x += smoothNoise(p );
  49. x += smoothNoise(p * 2. ) / 2.;
  50. x += smoothNoise(p * 4. ) / 4.;
  51. x += smoothNoise(p * 8. ) / 8.;
  52. x += smoothNoise(p * 16.) / 16.;
  53. x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
  54. return x;
  55. }
  56. float movingNoise(vec2 p) {
  57. float x = fractalNoise(p + iTime);
  58. float y = fractalNoise(p - iTime);
  59. return fractalNoise(p + vec2(x, y));
  60. }
  61. // call this for water noise function
  62. float nestedNoise(vec2 p) {
  63. float x = movingNoise(p);
  64. float y = movingNoise(p + 100.);
  65. return movingNoise(p + vec2(x, y));
  66. }
  67. void mainImage( out vec4 fragColor, in vec2 fragCoord )
  68. {
  69. vec2 uv = fragCoord.xy / iResolution.xy;
  70. float n = nestedNoise(uv * 6.);
  71. fragColor = vec4(mix(vec3(.4, .6, 1.), vec3(.1, .2, 1.), n), 1.);
  72. }
  73. </script>
  74. <script type="x-shader/x-fragment" id="example2">
  75. // https://www.shadertoy.com/view/3tcBzH
  76. float rand(vec2 co){
  77. return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
  78. }
  79. float hermite(float t)
  80. {
  81. return t * t * (3.0 - 2.0 * t);
  82. }
  83. float noise(vec2 co, float frequency)
  84. {
  85. vec2 v = vec2(co.x * frequency, co.y * frequency);
  86. float ix1 = floor(v.x);
  87. float iy1 = floor(v.y);
  88. float ix2 = floor(v.x + 1.0);
  89. float iy2 = floor(v.y + 1.0);
  90. float fx = hermite(fract(v.x));
  91. float fy = hermite(fract(v.y));
  92. float fade1 = mix(rand(vec2(ix1, iy1)), rand(vec2(ix2, iy1)), fx);
  93. float fade2 = mix(rand(vec2(ix1, iy2)), rand(vec2(ix2, iy2)), fx);
  94. return mix(fade1, fade2, fy);
  95. }
  96. float pnoise(vec2 co, float freq, int steps, float persistence)
  97. {
  98. float value = 0.0;
  99. float ampl = 1.0;
  100. float sum = 0.0;
  101. for(int i=0 ; i<steps ; i++)
  102. {
  103. sum += ampl;
  104. value += noise(co, freq) * ampl;
  105. freq *= 2.0;
  106. ampl *= persistence;
  107. }
  108. return value / sum;
  109. }
  110. void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
  111. vec2 uv = fragCoord.xy / iResolution.xy;
  112. float gradient = 1.0 - uv.y;
  113. float gradientStep = 0.2;
  114. vec2 pos = fragCoord.xy / iResolution.x;
  115. pos.y -= iTime * 0.3125;
  116. vec4 brighterColor = vec4(1.0, 0.65, 0.1, 0.25);
  117. vec4 darkerColor = vec4(1.0, 0.0, 0.15, 0.0625);
  118. vec4 middleColor = mix(brighterColor, darkerColor, 0.5);
  119. float noiseTexel = pnoise(pos, 10.0, 5, 0.5);
  120. float firstStep = smoothstep(0.0, noiseTexel, gradient);
  121. float darkerColorStep = smoothstep(0.0, noiseTexel, gradient - gradientStep);
  122. float darkerColorPath = firstStep - darkerColorStep;
  123. vec4 color = mix(brighterColor, darkerColor, darkerColorPath);
  124. float middleColorStep = smoothstep(0.0, noiseTexel, gradient - 0.2 * 2.0);
  125. color = mix(color, middleColor, darkerColorStep - middleColorStep);
  126. color = mix(vec4(0.0), color, firstStep);
  127. fragColor = color;
  128. }
  129. </script>
  130. <script type="module">
  131. import * as THREE from 'three/webgpu';
  132. import * as TSL from 'three/tsl';
  133. import Transpiler from 'three/addons/transpiler/Transpiler.js';
  134. import ShaderToyDecoder from 'three/addons/transpiler/ShaderToyDecoder.js';
  135. import TSLEncoder from 'three/addons/transpiler/TSLEncoder.js';
  136. class ShaderToyNode extends THREE.Node {
  137. constructor() {
  138. super( 'vec4' );
  139. this.mainImage = null;
  140. }
  141. transpile( glsl, iife = false ) {
  142. const decoder = new ShaderToyDecoder();
  143. const encoder = new TSLEncoder();
  144. encoder.iife = iife;
  145. const jsCode = new Transpiler( decoder, encoder ).parse( glsl );
  146. return jsCode;
  147. }
  148. parse( glsl ) {
  149. const jsCode = this.transpile( glsl, true );
  150. const { mainImage } = eval( jsCode )( TSL );
  151. this.mainImage = mainImage;
  152. }
  153. async parseAsync( glsl ) {
  154. const jsCode = this.transpile( glsl );
  155. const { mainImage } = await import( `data:text/javascript,${ encodeURIComponent( jsCode ) }` );
  156. this.mainImage = mainImage;
  157. }
  158. setup( builder ) {
  159. if ( this.mainImage === null ) {
  160. throw new Error( 'ShaderToyNode: .parse() must be called first.' );
  161. }
  162. return this.mainImage();
  163. }
  164. }
  165. let renderer, camera, scene;
  166. const dpr = window.devicePixelRatio;
  167. init();
  168. function init() {
  169. const example1Code = document.getElementById( 'example1' ).textContent;
  170. const example2Code = document.getElementById( 'example2' ).textContent;
  171. const shaderToy1Node = new ShaderToyNode();
  172. shaderToy1Node.parse( example1Code );
  173. const shaderToy2Node = new ShaderToyNode();
  174. shaderToy2Node.parse( example2Code );
  175. //
  176. camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
  177. scene = new THREE.Scene();
  178. const geometry = new THREE.PlaneGeometry( 2, 2 );
  179. const material = new THREE.MeshBasicNodeMaterial();
  180. material.colorNode = TSL.oscSine( TSL.time.mul( .3 ) ).mix( shaderToy1Node, shaderToy2Node );
  181. const quad = new THREE.Mesh( geometry, material );
  182. scene.add( quad );
  183. //
  184. renderer = new THREE.WebGPURenderer( { antialias: true } );
  185. renderer.setPixelRatio( dpr );
  186. renderer.setSize( window.innerWidth, window.innerHeight );
  187. renderer.setAnimationLoop( animate );
  188. renderer.outputColorSpace = THREE.LinearSRGBColorSpace;
  189. document.body.appendChild( renderer.domElement );
  190. window.addEventListener( 'resize', onWindowResize );
  191. }
  192. function onWindowResize() {
  193. camera.aspect = window.innerWidth / window.innerHeight;
  194. camera.updateProjectionMatrix();
  195. renderer.setSize( window.innerWidth, window.innerHeight );
  196. }
  197. function animate() {
  198. renderer.render( scene, camera );
  199. }
  200. </script>
  201. </body>
  202. </html>
粤ICP备19079148号