webgpu_shadertoy.html 7.7 KB

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