├── .gitignore ├── LICENSE ├── POINTS.code-workspace ├── README.md ├── audio ├── cognitive_dissonance ├── cognitive_dissonance.mp3 └── generative_audio_test.ogg ├── docs ├── 0001-0600.mp4 ├── Thumbs.db ├── base_demo.png ├── bloom1.png ├── dithering1.png ├── dithering2.png ├── dithering3.png ├── imagetexture2.png ├── imagetexture3.png └── noise1.png ├── examples ├── audio1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── audio2 │ ├── frag.js │ ├── index.js │ └── vert.js ├── base │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── basic.html ├── bloom1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── circleblur │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── data1 │ ├── compute.js │ └── index.js ├── demo_6 │ ├── frag.js │ ├── index.js │ └── vert.js ├── dithering1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── dithering2 │ ├── frag.js │ ├── index.js │ └── vert.js ├── dithering3_1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── dithering3_2 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── dithering4 │ ├── frag.js │ ├── index.js │ └── vert.js ├── dithering_video_1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── droste_effect_1 │ ├── index.js │ ├── renderpass0 │ │ ├── compute.js │ │ ├── frag.js │ │ └── vert.js │ ├── renderpass1 │ │ ├── compute.js │ │ ├── frag.js │ │ └── vert.js │ └── structs.js ├── events1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── imagescale1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── imagetexture1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── imagetexture2 │ ├── frag.js │ ├── index.js │ └── vert.js ├── imagetexture3 │ ├── frag.js │ ├── index.js │ └── vert.js ├── imagetexture4 │ ├── frag.js │ ├── index.js │ └── vert.js ├── index.html ├── index_files │ ├── ic_code_black_24dp.svg │ └── shader_projects.js ├── lavalamp1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── layers1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── main.js ├── mandelbrot1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── mesh1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── mouse1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── mouseclickscroll1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── noise1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── noisecircle1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── params_test │ ├── compute.js │ ├── frag.js │ ├── index.js │ ├── structs.js │ └── vert.js ├── pointstitle1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── random1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── random2 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── random3 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── renderpasses1 │ ├── index.js │ ├── renderpass1 │ │ ├── frag.js │ │ └── vert.js │ └── renderpass2 │ │ ├── frag.js │ │ └── vert.js ├── renderpasses2 │ ├── index.js │ └── renderpass1 │ │ ├── frag.js │ │ └── vert.js ├── shapes1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── shapes2 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js ├── spritesheet1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── style.css ├── swirl1 │ ├── frag.js │ ├── index.js │ ├── structs.js │ └── vert.js ├── swirl2 │ ├── frag0.js │ ├── frag1.js │ ├── index.js │ ├── structs.js │ └── vert.js ├── utils.js ├── uvs1 │ ├── frag.js │ ├── index.js │ └── vert.js ├── videotexture1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js └── webgpu_particles_1 │ ├── index.js │ ├── pass0 │ ├── compute.js │ ├── frag.js │ ├── index.js │ ├── structs.js │ └── vert.js │ ├── pass1 │ ├── compute.js │ ├── frag.js │ ├── index.js │ └── vert.js │ ├── readme │ ├── structs.js │ └── webgpu.png ├── img ├── 45da0cdd-f0a1-4a71-aed1-217a529b225c.png ├── 61c6eeaf-87cf5e18.mp4 ├── 6982698-hd_1440_1080_25fps_800x800.mp4 ├── absulit_800x800.jpg ├── angel_600x600.jpg ├── astronaut_512x512.jpg ├── carmen_lyra_2_800x800.jpg ├── carmen_lyra_2_blur_800x800.jpg ├── carmen_lyra_423x643.jpg ├── carmen_lyra_800x800.jpg ├── fishing_bobbles_nelson-yiap_24x24.png ├── gioconda_300x300.jpg ├── grace_hopper_512x600.jpg ├── grace_hopper_crop.jpg ├── gratia_800x800.jpg ├── house_512x512.jpg ├── inconsolata_regular_8x22.png ├── lr_penguin2_tamashihoshi_32x32.png ├── noiseTexture.png ├── noiseTexture2.png ├── old_king_100x100.jpg ├── old_king_200x200.jpg ├── old_king_600x600.jpg ├── old_king_color_800x800.png ├── pexels-hannah-nelson-1037989.jpg ├── pexels-ketut-subiyanto-4350315.jpg ├── pexels-kindel-media-7149147.jpg ├── pexels-shubh-haque-4746616-960x540-30fps.mp4 ├── sprite.png ├── sprite_nums.kra ├── sprite_nums.png ├── sprite_nums_1024x1024.kra ├── sprite_nums_1024x1024.png ├── sprite_nums_640x640.kra ├── sprite_nums_640x640.png ├── sprite_nums_handdrawn.kra ├── unnamed_horror_100x100.png └── unnamed_horror_800x800.png ├── jsconfig.json ├── legacy ├── Common │ ├── LoadShaders.js │ ├── MV.js │ ├── README.txt │ ├── _InitShaders.js │ ├── flatten.js │ ├── initShaders.js │ ├── initShaders2.js │ └── webgl-utils.js ├── absulit.js ├── absulit.module.js ├── css │ └── style.css ├── index.html ├── js │ ├── arrays.txt │ ├── cache.js │ ├── ccapture │ │ └── CCapture.all.min.js │ ├── color.js │ ├── coordinate.js │ ├── effects.js │ ├── es6 │ │ ├── main.js │ │ ├── stats.js │ │ ├── three.js │ │ ├── three.min.js │ │ ├── three.module.js │ │ └── utils.js │ ├── flowfields.js │ ├── imageloader.js │ ├── layer.js │ ├── mathutil.js │ ├── point.js │ ├── screen.js │ ├── spriteloader.js │ ├── utils.js │ ├── valuenoise.js │ └── videoloader.js ├── main.html ├── main.js ├── main_examples.js ├── shaderdemo.html ├── shaderdemo.js ├── stats.js └── style.css ├── src ├── CanvasRecorder.js ├── RenderPass.js ├── RenderPasses.js ├── ShaderType.js ├── UniformKeys.js ├── VertexBufferInfo.js ├── absulit.points.module.js ├── clock.js ├── color.js ├── coordinate.js ├── core │ ├── RenderPasses │ │ ├── bloom │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── blur │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── chromaticAberration │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── color │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── filmgrain │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── grayscale │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── lensDistortion │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ ├── pixelate │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ │ └── waves │ │ │ ├── frag.js │ │ │ ├── index.js │ │ │ └── vert.js │ ├── animation.js │ ├── audio.js │ ├── cellular2d.js │ ├── classicnoise2d.js │ ├── color.js │ ├── debug.js │ ├── defaultConstants.js │ ├── defaultFunctions.js │ ├── defaultStructs.js │ ├── defaultVertexStructs.js │ ├── effects.js │ ├── image.js │ ├── math.js │ ├── noise2d.js │ ├── random.js │ ├── sdf.js │ ├── valuenoise.js │ └── voronoi.js ├── data-size.js └── vendor │ ├── ccapture │ └── CCapture.all.min.js │ ├── datgui │ ├── dat.gui.css │ ├── dat.gui.module.js │ └── dat.gui.module.js.map │ └── stats.js └── webgpu_demo_reference ├── assets └── old_king_600x600.jpg ├── demo1.html ├── demo1.js ├── demo2.html ├── demo2.js ├── demo2_1.html ├── demo2_1.js ├── demo3.html ├── demo3.js ├── demo3_1.html ├── demo3_1.js ├── demo4.html ├── demo4.js ├── demo5.html ├── demo5.js ├── demo6.html ├── demo6.js ├── js ├── absulit.webgpu.module.js ├── ccapture │ └── CCapture.all.min.js ├── color.js └── coordinate.js ├── shader_loader.js ├── shaders ├── demo6.compute.wgsl ├── demo6_colors.frag.wgsl ├── demo6_colors.vert.wgsl ├── demo6_texture.frag.wgsl ├── demo6_texture.vert.wgsl ├── demo6_update.points.wgsl ├── points.compute.wgsl ├── points.old.compute.wgsl ├── red.frag.wgsl ├── red3_1.frag.wgsl ├── red4.frag.wgsl ├── red5.frag.wgsl ├── red5_colors.frag.wgsl ├── texture_example.frag.wgsl ├── texture_example.vert.wgsl ├── triangle.vert.wgsl ├── triangle3_1.vert.wgsl ├── triangle4.vert.wgsl ├── triangle5.vert.wgsl └── triangle5_colors.vert.wgsl ├── snail1.html ├── snail1.js ├── stats.js ├── style.css ├── texture_example.html └── texture_example.js /.gitignore: -------------------------------------------------------------------------------- 1 | /out 2 | /assets_ignore 3 | img/Thumbs.db 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Sebastian Sanabria Diaz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /POINTS.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": {} 8 | } 9 | -------------------------------------------------------------------------------- /audio/cognitive_dissonance: -------------------------------------------------------------------------------- 1 | "Cognitive Dissonance" Kevin MacLeod (incompetech.com) 2 | Licensed under Creative Commons: By Attribution 4.0 License 3 | http://creativecommons.org/licenses/by/4.0/ -------------------------------------------------------------------------------- /audio/cognitive_dissonance.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/audio/cognitive_dissonance.mp3 -------------------------------------------------------------------------------- /audio/generative_audio_test.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/audio/generative_audio_test.ogg -------------------------------------------------------------------------------- /docs/0001-0600.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/0001-0600.mp4 -------------------------------------------------------------------------------- /docs/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/Thumbs.db -------------------------------------------------------------------------------- /docs/base_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/base_demo.png -------------------------------------------------------------------------------- /docs/bloom1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/bloom1.png -------------------------------------------------------------------------------- /docs/dithering1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/dithering1.png -------------------------------------------------------------------------------- /docs/dithering2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/dithering2.png -------------------------------------------------------------------------------- /docs/dithering3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/dithering3.png -------------------------------------------------------------------------------- /docs/imagetexture2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/imagetexture2.png -------------------------------------------------------------------------------- /docs/imagetexture3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/imagetexture3.png -------------------------------------------------------------------------------- /docs/noise1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/docs/noise1.png -------------------------------------------------------------------------------- /examples/audio1/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | @compute @workgroup_size(8,8,1) 4 | fn main( 5 | @builtin(global_invocation_id) GlobalId: vec3, 6 | @builtin(workgroup_id) WorkGroupID: vec3, 7 | @builtin(local_invocation_id) LocalInvocationID: vec3 8 | ) { 9 | let time = params.time; 10 | } 11 | `; 12 | 13 | export default compute; 14 | -------------------------------------------------------------------------------- /examples/audio1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { snoise } from 'noise2d'; 3 | import { sdfCircle } from 'sdf'; 4 | import { WHITE, RED, layer } from 'color'; 5 | import { audioAverage, audioAverageSegments } from 'audio'; 6 | 7 | const frag = /*wgsl*/` 8 | 9 | ${fnusin} 10 | ${snoise} 11 | ${sdfCircle} 12 | ${layer} 13 | ${audioAverage} 14 | ${audioAverageSegments} 15 | ${WHITE} 16 | ${RED} 17 | 18 | @fragment 19 | fn main( 20 | @location(0) color: vec4, 21 | @location(1) uv: vec2, 22 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 23 | @location(3) uvr: vec2, // uv with aspect ratio corrected 24 | @location(4) mouse: vec2, 25 | @builtin(position) position: vec4 26 | ) -> @location(0) vec4 { 27 | 28 | let audioX = audio.data[ u32(uvr.x * params.audioLength)] / 256; 29 | 30 | if(params.mouseClick == 1.){ 31 | click_event.updated = 1; 32 | } 33 | 34 | 35 | var c = vec4f(); 36 | c.r = audioX; 37 | c.a = 1.; 38 | 39 | return c; 40 | } 41 | `; 42 | 43 | export default frag; 44 | -------------------------------------------------------------------------------- /examples/audio1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import Points from 'points'; 5 | 6 | let audio = null; 7 | 8 | const base = { 9 | vert, 10 | compute, 11 | frag, 12 | /** 13 | * 14 | * @param {Points} points 15 | */ 16 | init: async points => { 17 | let volume = 1; 18 | let loop = true; 19 | // audio = points.setAudio('audio', './../../audio/generative_audio_test.ogg', volume, loop); 20 | audio = points.setAudio('audio', './../../audio/cognitive_dissonance.mp3', volume, loop, false); 21 | points.addEventListener('click_event', data => { 22 | audio.play(); 23 | }, 4); 24 | // points.setAudio('audio', 'https://mdn.github.io/voice-change-o-matic/audio/concert-crowd.ogg', volume, loop); 25 | points.setStorage('result', 'f32'); 26 | }, 27 | /** 28 | * 29 | * @param {Points} points 30 | */ 31 | update: points => { 32 | }, 33 | 34 | remove: _ => { 35 | audio.pause(); 36 | audio.remove(); 37 | } 38 | } 39 | 40 | export default base; -------------------------------------------------------------------------------- /examples/audio1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/audio2/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | import Points from 'points'; 4 | import RenderPasses from 'renderpasses'; 5 | 6 | let audio = null; 7 | 8 | const base = { 9 | vert, 10 | compute: null, 11 | frag, 12 | /** 13 | * 14 | * @param {Points} points 15 | */ 16 | init: async points => { 17 | let volume = 1; 18 | let loop = true; 19 | // let audio = points.setAudio('audio', './../../audio/generative_audio_test.ogg', volume, loop); 20 | audio = points.setAudio('audio', './../../audio/cognitive_dissonance.mp3', volume, loop, false); 21 | // audio = points.setAudio('audio', 'https://mdn.github.io/voice-change-o-matic/audio/concert-crowd.ogg', volume, loop); 22 | 23 | points.addEventListener('click_event', data => { 24 | audio.play(); 25 | }, 4); 26 | 27 | 28 | points.setStorage('result', 'array', 4); 29 | 30 | // RenderPasses.filmgrain(points); 31 | // RenderPasses.bloom(points, .1); 32 | // RenderPasses.lensDistortion(points, .5, .01); 33 | // RenderPasses.blur(points, 100, 100, .1,0); 34 | 35 | points.setSampler('imageSampler', null); 36 | points.setTexture2d('feedbackTexture', true); 37 | }, 38 | /** 39 | * 40 | * @param {Points} points 41 | */ 42 | update: points => { 43 | }, 44 | 45 | remove: _ => { 46 | audio.pause(); 47 | audio.remove(); 48 | } 49 | } 50 | 51 | export default base; -------------------------------------------------------------------------------- /examples/audio2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/base/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | @compute @workgroup_size(8,8,1) 4 | fn main( 5 | @builtin(global_invocation_id) GlobalId: vec3, 6 | @builtin(workgroup_id) WorkGroupID: vec3, 7 | @builtin(local_invocation_id) LocalInvocationID: vec3 8 | ) { 9 | let time = params.time; 10 | } 11 | `; 12 | 13 | export default compute; 14 | -------------------------------------------------------------------------------- /examples/base/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | 3 | const frag = /*wgsl*/` 4 | 5 | ${fnusin} 6 | 7 | @fragment 8 | fn main( 9 | @location(0) color: vec4, 10 | @location(1) uv: vec2, 11 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 12 | @location(3) uvr: vec2, // uv with aspect ratio corrected 13 | @location(4) mouse: vec2, 14 | @builtin(position) position: vec4 15 | ) -> @location(0) vec4 { 16 | 17 | let cellSize = 20. + 10. * fnusin(1.); 18 | let a = sin(uvr.x * cellSize) * sin(uvr.y * cellSize); 19 | let b = sin(uvr.x * uvr.y * 10. * 9.1 * .25 ); 20 | let c = fnusin(uvr.x * uvr.y * 10.); 21 | let d = distance(a,b); 22 | let f = d * uvr.x * uvr.y; 23 | let finalColor:vec4 = vec4(a*d,f*c*a,f, 1.); 24 | 25 | return finalColor; 26 | } 27 | `; 28 | 29 | export default frag; 30 | -------------------------------------------------------------------------------- /examples/base/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import Points from 'points'; 5 | 6 | const options = { 7 | val: 0, 8 | bool: false, 9 | color1: '#FF0000', // CSS string 10 | color2: [0, 128, 255], // RGB array 11 | color3: [0, 128, 255, 0.3], // RGB with alpha 12 | color4: { h: 350, s: 0.9, v: 0.3 }, // Hue, saturation, value 13 | color5: { r: 115, g: 50.9, b: 20.3, a: .1 }, // r, g, b object 14 | } 15 | 16 | const base = { 17 | vert, 18 | compute, 19 | frag, 20 | /** 21 | * 22 | * @param {Points} points 23 | */ 24 | init: async (points, folder) => { 25 | 26 | // Add elements to dat gui 27 | // create an uniform and get value from options 28 | points.setUniform('val', options.val); 29 | 30 | // https://github.com/dataarts/dat.gui/blob/master/API.md#GUI+add 31 | folder.add(options, 'val', -1, 1, .0001).name('Val'); 32 | folder.add(options, 'bool').name('Bool'); 33 | 34 | // https://github.com/dataarts/dat.gui/blob/master/API.md#GUI+addColor 35 | folder.addColor(options, 'color1'); 36 | folder.addColor(options, 'color2'); 37 | folder.addColor(options, 'color3'); 38 | folder.addColor(options, 'color4'); 39 | folder.addColor(options, 'color5'); 40 | 41 | folder.open(); 42 | }, 43 | update: points => { 44 | points.setUniform('val', options.val); 45 | } 46 | } 47 | 48 | export default base; -------------------------------------------------------------------------------- /examples/base/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/bloom1/frag.js: -------------------------------------------------------------------------------- 1 | import { snoise } from 'noise2d'; 2 | import { texturePosition } from 'image'; 3 | import { bloom, brightness } from 'color'; 4 | import { sdfCircle, sdfLine, sdfSegment } from 'sdf'; 5 | import { fnusin, fusin } from 'animation'; 6 | import { polar, PI } from 'math'; 7 | 8 | const frag = /*wgsl*/` 9 | 10 | ${fnusin} 11 | ${fusin} 12 | ${sdfCircle} 13 | ${sdfSegment} 14 | ${sdfLine} 15 | ${brightness} 16 | ${polar} 17 | ${snoise} 18 | ${PI} 19 | ${texturePosition} 20 | ${bloom} 21 | 22 | 23 | @fragment 24 | fn main( 25 | @location(0) color: vec4, 26 | @location(1) uv: vec2, 27 | @location(2) ratio: vec2, 28 | @location(3) uvr: vec2, 29 | @location(4) mouse: vec2, 30 | @builtin(position) position: vec4 31 | ) -> @location(0) vec4 { 32 | 33 | let startPosition = vec2(0.,0.); 34 | let rgbaImage = texturePosition(image, imageSampler, startPosition, uvr / params.scale, true); //* .998046; 35 | 36 | let input = rgbaImage.r; 37 | let bloomVal = bloom(input, 2, params.bloom); 38 | let rgbaBloom = vec4(bloomVal); 39 | 40 | 41 | let finalColor:vec4 = rgbaImage + rgbaBloom; 42 | 43 | 44 | return finalColor; 45 | } 46 | `; 47 | 48 | export default frag; 49 | -------------------------------------------------------------------------------- /examples/bloom1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { scale: 1, bloom: .133 } 5 | 6 | const bloom1 = { 7 | vert, 8 | frag, 9 | init: async (points, folder) => { 10 | let descriptor = { 11 | addressModeU: 'repeat', 12 | addressModeV: 'repeat', 13 | } 14 | 15 | points.setSampler('imageSampler', descriptor); 16 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 17 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 18 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 19 | 20 | points.setUniform('scale', options.scale); 21 | points.setUniform('bloom', options.bloom); 22 | folder.add(options, 'scale', 0, 1, .0001).name('scale'); 23 | folder.add(options, 'bloom', -1, 1, .0001).name('bloom'); 24 | folder.open(); 25 | }, 26 | update: points => { 27 | points.setUniform('scale', options.scale); 28 | points.setUniform('bloom', options.bloom); 29 | } 30 | } 31 | 32 | export default bloom1; -------------------------------------------------------------------------------- /examples/bloom1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/circleblur/compute.js: -------------------------------------------------------------------------------- 1 | 2 | import { clearMix } from 'effects'; 3 | const compute = /*wgsl*/` 4 | 5 | ${clearMix} 6 | 7 | const workgroupSize = 1; 8 | 9 | //'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup' 10 | 11 | @compute @workgroup_size(workgroupSize,workgroupSize,1) 12 | fn main( 13 | @builtin(global_invocation_id) GlobalId: vec3, 14 | @builtin(workgroup_id) WorkGroupID: vec3, 15 | @builtin(local_invocation_id) LocalInvocationID: vec3 16 | ) { 17 | 18 | // let filterDim = 128u; 19 | // let blockDim = 128u; 20 | // let flipValue = 0u; 21 | 22 | // let filterOffset : u32 = (filterDim - 1u) / 2u; 23 | 24 | // let baseIndex = vec2( 25 | // WorkGroupID.xy * vec2(blockDim, 4u) + 26 | // LocalInvocationID.xy * vec2(4u, 1u) 27 | // ) - vec2(i32(filterOffset), 0); 28 | 29 | // ---------------------------------------------- 30 | 31 | 32 | var rgba = textureSampleLevel( 33 | feedbackTexture,feedbackSampler, 34 | vec2(f32(GlobalId.x), f32(GlobalId.y)), 35 | 0.0 36 | ); 37 | rgba = clearMix(rgba, 1.01) + vec4(1.,0.,0., .5); 38 | textureStore(outputTex, GlobalId.xy, rgba); 39 | } 40 | `; 41 | 42 | export default compute; -------------------------------------------------------------------------------- /examples/circleblur/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin, fusin } from 'animation'; 2 | import { texturePosition } from 'image'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | struct Particle{ 7 | x: f32, 8 | y: f32 9 | } 10 | 11 | ${fnusin} 12 | ${fusin} 13 | ${texturePosition} 14 | 15 | @fragment 16 | fn main( 17 | @location(0) color: vec4, 18 | @location(1) uv: vec2, 19 | @location(2) ratio: vec2, 20 | @location(3) uvr: vec2, 21 | @location(4) mouse: vec2, 22 | @builtin(position) position: vec4 23 | ) -> @location(0) vec4 { 24 | 25 | let startPosition = vec2(0.); 26 | let texColor = texturePosition(feedbackTexture, feedbackSampler, startPosition, uvr, false); 27 | let texColor2 = texturePosition(feedbackTexture, feedbackSampler, startPosition, uvr + vec2(-.001,1), false); 28 | let texColor3 = texturePosition(feedbackTexture, feedbackSampler, startPosition, uvr + vec2(.001,1), false); 29 | 30 | let texColorCompute = texturePosition(computeTexture, feedbackSampler, startPosition, uv, false); 31 | 32 | let d = distance(uvr, vec2(.5 + .1 * fusin(2.), .5 + .1 * fusin(4.123)) * ratio); 33 | var c = 1.; 34 | if(d > .1){ 35 | c = 0.; 36 | } 37 | 38 | let decayR = texColor.r * .9 * texColor2.r; 39 | let decayG = texColor.g * .9; 40 | let decayB = texColor.b * .9 * texColor3.b; 41 | let decayA = texColor.a * .9; 42 | 43 | var finalColor:vec4 = vec4(uv.x * c, uv.y * c, c, 1); 44 | finalColor += vec4(decayR, decayG, decayB, 1); 45 | finalColor += texColorCompute; 46 | 47 | return finalColor; 48 | } 49 | `; 50 | 51 | export default frag; -------------------------------------------------------------------------------- /examples/circleblur/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | import Points from 'points'; 6 | const circleblur = { 7 | renderPasses: [ 8 | new RenderPass(null, null, compute, 800, 800, 1), 9 | new RenderPass(vert, frag, null, 8, 1, 1) 10 | ], 11 | /** 12 | * 13 | * @param {Points} points 14 | */ 15 | init: async points => { 16 | points.setSampler('feedbackSampler', null); 17 | points.setTexture2d('feedbackTexture', true); 18 | points.setBindingTexture('outputTex', 'computeTexture'); 19 | }, 20 | update: points => { 21 | 22 | } 23 | } 24 | 25 | export default circleblur; -------------------------------------------------------------------------------- /examples/circleblur/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | return defaultVertexBody(position, color, uv); 11 | } 12 | `; 13 | 14 | export default vert; -------------------------------------------------------------------------------- /examples/data1/compute.js: -------------------------------------------------------------------------------- 1 | // original article on compute shaders 2 | // https://developer.chrome.com/articles/gpu-compute/ 3 | 4 | const compute = /*wgsl*/` 5 | 6 | struct Matrix { 7 | size : vec2, 8 | numbers: array, 9 | } 10 | 11 | @compute @workgroup_size(8,8,1) 12 | fn main( 13 | @builtin(global_invocation_id) GlobalId: vec3, 14 | @builtin(workgroup_id) WorkGroupID: vec3, 15 | @builtin(local_invocation_id) LocalInvocationID: vec3 16 | ) { 17 | // Guard against out-of-bounds work group sizes 18 | if (GlobalId.x >= u32(firstMatrix.size.x) || GlobalId.y >= u32(secondMatrix.size.y)) { 19 | return; 20 | } 21 | 22 | resultMatrix.size = vec2(firstMatrix.size.x, secondMatrix.size.y); 23 | 24 | let resultCell = vec2(GlobalId.x, GlobalId.y); 25 | var result = 0.0; 26 | for (var i = 0u; i < u32(firstMatrix.size.y); i = i + 1u) { 27 | let a = i + resultCell.x * u32(firstMatrix.size.y); 28 | let b = resultCell.y + i * u32(secondMatrix.size.y); 29 | result = result + firstMatrix.numbers[a] * secondMatrix.numbers[b]; 30 | } 31 | 32 | let index = resultCell.y + resultCell.x * u32(secondMatrix.size.y); 33 | resultMatrix.numbers[index] = result; 34 | 35 | } 36 | `; 37 | 38 | export default compute; 39 | -------------------------------------------------------------------------------- /examples/data1/index.js: -------------------------------------------------------------------------------- 1 | // original article on compute shaders 2 | // https://developer.chrome.com/articles/gpu-compute/ 3 | 4 | import compute from './compute.js'; 5 | 6 | let read = false; 7 | 8 | const data1 = { 9 | compute, 10 | init: async points => { 11 | 12 | const firstMatrix = [ 13 | 2 /* rows */, 4 /* columns */, 14 | 1, 2, 3, 4, 15 | 5, 6, 7, 8 16 | ]; 17 | 18 | points.setStorageMap('firstMatrix', firstMatrix, 'Matrix'); 19 | 20 | const secondMatrix = [ 21 | 4 /* rows */, 2 /* columns */, 22 | 1, 2, 23 | 3, 4, 24 | 5, 6, 25 | 7, 8 26 | ]; 27 | 28 | points.setStorageMap('secondMatrix', secondMatrix, 'Matrix'); 29 | 30 | // original lines as reference: 31 | // let resultMatrixBufferSize = 2 + firstMatrix[0] * secondMatrix[1]; 32 | // console.log(resultMatrixBufferSize); 33 | points.setStorage('resultMatrix', 'Matrix', true); 34 | }, 35 | update: async points => { 36 | 37 | }, 38 | read: async points => { 39 | if(!read){ 40 | let result = await points.readStorage('resultMatrix'); 41 | console.log(result); 42 | read = true; 43 | } 44 | } 45 | } 46 | 47 | export default data1; -------------------------------------------------------------------------------- /examples/demo_6/frag.js: -------------------------------------------------------------------------------- 1 | const frag = /*wgsl*/` 2 | 3 | @fragment 4 | fn main( 5 | @location(0) color: vec4, 6 | @location(1) uv: vec2 7 | ) -> @location(0) vec4 { 8 | 9 | return color; 10 | } 11 | `; 12 | 13 | export default frag; 14 | -------------------------------------------------------------------------------- /examples/demo_6/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | const demo6 = { 4 | vert, 5 | frag, 6 | init: async points => { 7 | }, 8 | update: points => { 9 | 10 | } 11 | } 12 | 13 | export default demo6; -------------------------------------------------------------------------------- /examples/demo_6/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | // By default there's a Fragment struct (check base demo) 4 | // but you can create your own to send to the Fragment Shader in frag.js 5 | struct CustomFragment { 6 | @builtin(position) position: vec4, 7 | @location(0) color: vec4, 8 | @location(1) uv: vec2 9 | } 10 | 11 | @vertex 12 | fn main( 13 | @location(0) position: vec4, 14 | @location(1) color: vec4, 15 | @location(2) uv: vec2, 16 | @builtin(vertex_index) vertexIndex: u32) -> CustomFragment { 17 | 18 | var result: CustomFragment; 19 | 20 | result.position = vec4(position); 21 | result.uv = uv; 22 | result.color = vec4(color); 23 | 24 | return result; 25 | } 26 | `; 27 | 28 | export default vert; 29 | -------------------------------------------------------------------------------- /examples/dithering1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | depth: 1, 7 | } 8 | 9 | const dithering1 = { 10 | vert, 11 | frag, 12 | init: async (points, folder) => { 13 | let descriptor = { 14 | addressModeU: 'repeat', 15 | addressModeV: 'repeat', 16 | } 17 | points.setSampler('feedbackSampler', descriptor); 18 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 19 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 20 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 21 | 22 | points.setUniform('scale', options.scale); 23 | points.setUniform('depth', options.depth); 24 | 25 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 26 | folder.add(options, 'depth', -1, 1, .0001).name('Depth'); 27 | folder.open(); 28 | }, 29 | update: points => { 30 | points.setUniform('scale', options.scale); 31 | points.setUniform('depth', options.depth); 32 | } 33 | } 34 | 35 | export default dithering1; -------------------------------------------------------------------------------- /examples/dithering1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/dithering2/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | depth: 1, 7 | distance: 1, 8 | } 9 | 10 | const dithering2 = { 11 | vert, 12 | frag, 13 | init: async (points, folder) => { 14 | let descriptor = { 15 | addressModeU: 'repeat', 16 | addressModeV: 'repeat', 17 | } 18 | points.setSampler('feedbackSampler', descriptor); 19 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 20 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 21 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 22 | 23 | points.setUniform('scale', options.scale); 24 | points.setUniform('depth', options.depth); 25 | points.setUniform('distance', options.depth); 26 | 27 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 28 | folder.add(options, 'depth', -1, 1, .0001).name('Depth'); 29 | folder.add(options, 'distance', -1, 1, .0001).name('Distance'); 30 | folder.open(); 31 | }, 32 | update: points => { 33 | points.setUniform('scale', options.scale); 34 | points.setUniform('depth', options.depth); 35 | points.setUniform('distance', options.distance); 36 | } 37 | } 38 | 39 | export default dithering2; -------------------------------------------------------------------------------- /examples/dithering2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/dithering3_1/frag.js: -------------------------------------------------------------------------------- 1 | import { snoise } from 'noise2d'; 2 | import { texturePosition } from 'image'; 3 | import { fnusin } from 'animation'; 4 | 5 | const frag = /*wgsl*/` 6 | struct Variable{ 7 | init: i32 8 | } 9 | 10 | ${fnusin} 11 | ${snoise} 12 | ${texturePosition} 13 | 14 | @fragment 15 | fn main( 16 | @location(0) color: vec4, 17 | @location(1) uv: vec2, 18 | @location(2) ratio: vec2, 19 | @location(3) uvRatio: vec2, 20 | @location(4) mouse: vec2, 21 | @builtin(position) position: vec4 22 | ) -> @location(0) vec4 { 23 | 24 | //let imageUV = (uv / f + vec2(0, .549 ) ) * vec2(1,-1 * dimsRatio) * ratio.y / params.sliderA; 25 | //var point = textureSample(computeTexture, imageSampler, imageUV); //* .998046; 26 | var point = texturePosition(computeTexture, imageSampler, vec2(0.), uv / params.scale, true); //* .998046; 27 | 28 | return point; 29 | } 30 | `; 31 | 32 | export default frag; 33 | -------------------------------------------------------------------------------- /examples/dithering3_1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import ShaderType from 'shadertype'; 5 | 6 | const options = { 7 | scale: 1, 8 | } 9 | 10 | 11 | const dithering3 = { 12 | vert, 13 | compute, 14 | frag, 15 | init: async (points, folder) => { 16 | let descriptor = { 17 | addressModeU: 'repeat', 18 | addressModeV: 'repeat', 19 | } 20 | points.setSampler('imageSampler', descriptor); 21 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 22 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 23 | // await points.setTextureWebcam('image'); 24 | // await points.setTextureImage('image', './../img/angel_600x600.jpg'); 25 | // await points.setTextureImage('image', './../img/gratia_800x800.jpg'); 26 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 27 | points.setBindingTexture('outputTex', 'computeTexture'); 28 | points.setLayers(2); 29 | points.setStorage('variables', 'Variable', false, ShaderType.COMPUTE); 30 | 31 | points.setUniform('scale', options.scale); 32 | 33 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 34 | folder.open(); 35 | }, 36 | update: points => { 37 | points.setUniform('scale', options.scale); 38 | } 39 | } 40 | 41 | export default dithering3; -------------------------------------------------------------------------------- /examples/dithering3_1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Variable{ 4 | init: i32 5 | } 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @location(2) uv: vec2, 12 | @builtin(vertex_index) vertexIndex: u32 13 | ) -> Fragment { 14 | 15 | return defaultVertexBody(position, color, uv); 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/dithering3_2/frag.js: -------------------------------------------------------------------------------- 1 | import { snoise } from 'noise2d'; 2 | import { texturePosition } from 'image'; 3 | import { fnusin } from 'animation'; 4 | 5 | const frag = /*wgsl*/` 6 | struct Variable{ 7 | init: i32 8 | } 9 | 10 | ${fnusin} 11 | ${snoise} 12 | ${texturePosition} 13 | 14 | @fragment 15 | fn main( 16 | @location(0) color: vec4, 17 | @location(1) uv: vec2, 18 | @location(2) ratio: vec2, 19 | @location(3) uvRatio: vec2, 20 | @location(4) mouse: vec2, 21 | @builtin(position) position: vec4 22 | ) -> @location(0) vec4 { 23 | 24 | //let imageUV = (uv / f + vec2(0, .549 ) ) * vec2(1,-1 * dimsRatio) * ratio.y / params.sliderA; 25 | //var point = textureSample(computeTexture, imageSampler, imageUV); //* .998046; 26 | var point = texturePosition(computeTexture, imageSampler, vec2(0.), uv / params.scale, false); //* .998046; 27 | 28 | return point; 29 | } 30 | `; 31 | 32 | export default frag; 33 | -------------------------------------------------------------------------------- /examples/dithering3_2/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | import ShaderType from 'shadertype'; 6 | 7 | const options = { 8 | scale: 1, 9 | quantError: 1, 10 | } 11 | 12 | const dithering3 = { 13 | renderPasses: [ 14 | new RenderPass(vert, frag, compute, 800, 800) 15 | ], 16 | init: async (points, folder) => { 17 | let descriptor = { 18 | addressModeU: 'repeat', 19 | addressModeV: 'repeat', 20 | } 21 | points.setSampler('imageSampler', descriptor); 22 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 23 | // await points.setTextureImage('image', './../img/old_king_800x00.jpg'); 24 | // await points.setTextureWebcam('image'); 25 | // await points.setTextureImage('image', './../img/angel_600x600.jpg'); 26 | // await points.setTextureImage('image', './../img/gratia_800x800.jpg'); 27 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 28 | points.setBindingTexture('outputTex', 'computeTexture'); 29 | points.setLayers(2); 30 | points.setStorage('variables', 'Variable', false, ShaderType.COMPUTE); 31 | 32 | points.setUniform('scale', options.scale); 33 | points.setUniform('quantError', options.quantError); 34 | 35 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 36 | folder.add(options, 'quantError', -1, 1, .0001).name('quantError'); 37 | folder.open(); 38 | }, 39 | update: points => { 40 | points.setUniform('scale', options.scale); 41 | points.setUniform('quantError', options.quantError); 42 | } 43 | } 44 | 45 | export default dithering3; -------------------------------------------------------------------------------- /examples/dithering3_2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Variable{ 4 | init: i32 5 | } 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @location(2) uv: vec2, 12 | @builtin(vertex_index) vertexIndex: u32 13 | ) -> Fragment { 14 | 15 | return defaultVertexBody(position, color, uv); 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/dithering4/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | distance: 1, 7 | } 8 | 9 | const dithering4 = { 10 | vert, 11 | frag, 12 | init: async (points, folder) => { 13 | let descriptor = { 14 | addressModeU: 'clamp-to-edge', 15 | addressModeV: 'clamp-to-edge', 16 | } 17 | points.setSampler('feedbackSampler', descriptor); 18 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 19 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 20 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 21 | 22 | points.setUniform('scale', options.scale); 23 | points.setUniform('distance', options.distance); 24 | 25 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 26 | folder.add(options, 'distance', 0, 1, .0001).name('Distance'); 27 | folder.open(); 28 | }, 29 | update: points => { 30 | points.setUniform('scale', options.scale); 31 | points.setUniform('distance', options.distance); 32 | } 33 | } 34 | 35 | export default dithering4; -------------------------------------------------------------------------------- /examples/dithering4/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | 4 | @vertex 5 | fn main( 6 | @location(0) position: vec4, 7 | @location(1) color: vec4, 8 | @location(2) uv: vec2, 9 | @builtin(vertex_index) vertexIndex: u32 10 | ) -> Fragment { 11 | 12 | return defaultVertexBody(position, color, uv); 13 | } 14 | `; 15 | 16 | export default vert; 17 | -------------------------------------------------------------------------------- /examples/dithering_video_1/frag.js: -------------------------------------------------------------------------------- 1 | import { snoise } from 'noise2d'; 2 | import { texturePosition } from 'image'; 3 | import { fnusin } from 'animation'; 4 | 5 | const frag = /*wgsl*/` 6 | struct Variable{ 7 | init: i32 8 | } 9 | 10 | ${fnusin} 11 | ${snoise} 12 | ${texturePosition} 13 | 14 | @fragment 15 | fn main( 16 | @location(0) color: vec4, 17 | @location(1) uv: vec2, 18 | @location(2) ratio: vec2, 19 | @location(3) uvRatio: vec2, 20 | @location(4) mouse: vec2, 21 | @builtin(position) position: vec4 22 | ) -> @location(0) vec4 { 23 | 24 | //let imageUV = (uv / f + vec2(0, .549 ) ) * vec2(1,-1 * dimsRatio) * ratio.y / params.sliderA; 25 | //var point = textureSample(computeTexture, imageSampler, imageUV); //* .998046; 26 | var point = texturePosition(computeTexture, imageSampler, vec2(0.), uv / params.scale, false); //* .998046; 27 | 28 | return point; 29 | } 30 | `; 31 | 32 | export default frag; 33 | -------------------------------------------------------------------------------- /examples/dithering_video_1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | import ShaderType from 'shadertype'; 6 | import Points from 'points'; 7 | 8 | const options = { 9 | scale: 1, 10 | quantError: .15, 11 | } 12 | 13 | const base = { 14 | renderPasses: [ 15 | new RenderPass(vert, frag, compute, 800, 800) 16 | ], 17 | /** 18 | * 19 | * @param {Points} points 20 | * @param {*} folder 21 | */ 22 | init: async (points, folder) => { 23 | let descriptor = { 24 | addressModeU: 'repeat', 25 | addressModeV: 'repeat', 26 | } 27 | points.setSampler('imageSampler', descriptor); 28 | await points.setTextureVideo('image', './../img/6982698-hd_1440_1080_25fps_800x800.mp4'); 29 | points.setBindingTexture('outputTex', 'computeTexture'); 30 | points.setLayers(2); 31 | points.setStorage('variables', 'Variable', false, ShaderType.COMPUTE); 32 | 33 | points.setUniform('scale', options.scale); 34 | points.setUniform('quantError', options.quantError); 35 | 36 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 37 | folder.add(options, 'quantError', -1, 1, .0001).name('quantError'); 38 | folder.open(); 39 | }, 40 | update: points => { 41 | points.setUniform('scale', options.scale); 42 | points.setUniform('quantError', options.quantError); 43 | } 44 | } 45 | 46 | export default base; -------------------------------------------------------------------------------- /examples/dithering_video_1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Variable{ 4 | init: i32 5 | } 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @location(2) uv: vec2, 12 | @builtin(vertex_index) vertexIndex: u32 13 | ) -> Fragment { 14 | 15 | return defaultVertexBody(position, color, uv); 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/droste_effect_1/index.js: -------------------------------------------------------------------------------- 1 | import vert0 from './renderpass0/vert.js'; 2 | import compute0 from './renderpass0/compute.js'; 3 | import frag0 from './renderpass0/frag.js'; 4 | 5 | import vert1 from './renderpass1/vert.js'; 6 | import compute1 from './renderpass1/compute.js'; 7 | import frag1 from './renderpass1/frag.js'; 8 | 9 | import Points from 'points'; 10 | import ShaderType from 'shadertype'; 11 | import RenderPasses from 'renderpasses'; 12 | import RenderPass from 'renderpass'; 13 | 14 | 15 | /** 16 | * Genuary 3: Droste Effect 17 | * http://roy.red/posts/droste/ 18 | * https://github.com/ruby-processing/picrate-examples/blob/master/library/video/capture/data/droste.glsl 19 | */ 20 | 21 | const base = { 22 | 23 | renderPasses: [ 24 | new RenderPass(vert0, frag0, compute0), 25 | new RenderPass(vert1, frag1, compute1) 26 | ], 27 | /** 28 | * 29 | * @param {Points} points 30 | */ 31 | init: async (points, folder) => { 32 | points.setSampler('imageSampler', null, ShaderType.FRAGMENT); 33 | points.setTexture2d('feedbackTexture', true); 34 | points.setStorage('variables', 'Variables'); 35 | points.setStorage('colors', 'array'); 36 | }, 37 | update: points => { 38 | } 39 | } 40 | 41 | export default base; -------------------------------------------------------------------------------- /examples/droste_effect_1/renderpass0/compute.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const compute = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @compute @workgroup_size(8,8,1) 8 | fn main( 9 | @builtin(global_invocation_id) GlobalId: vec3, 10 | @builtin(workgroup_id) WorkGroupID: vec3, 11 | @builtin(local_invocation_id) LocalInvocationID: vec3 12 | ) { 13 | 14 | if(variables.init == 0){ 15 | var index = 0; 16 | colors[index] = vec3f(248, 208, 146) / 255; index++; 17 | colors[index] = vec3f(21, 144, 151) / 255; index++; 18 | colors[index] = vec3f(56, 164, 140) / 255; index++; 19 | colors[index] = vec3f(26, 86, 120) / 255; index++; 20 | colors[index] = vec3f(37, 36, 93) / 255; index++; 21 | colors[index] = vec3f(87, 28, 86) / 255; index++; 22 | 23 | variables.init = 1; 24 | } 25 | 26 | 27 | } 28 | `; 29 | 30 | export default compute; 31 | -------------------------------------------------------------------------------- /examples/droste_effect_1/renderpass0/vert.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const vert = /*wgsl*/` 4 | ${structs} 5 | @vertex 6 | fn main( 7 | @location(0) position: vec4, 8 | @location(1) color: vec4, 9 | @location(2) uv: vec2, 10 | @builtin(vertex_index) vertexIndex: u32 11 | ) -> Fragment { 12 | 13 | return defaultVertexBody(position, color, uv); 14 | } 15 | `; 16 | 17 | export default vert; 18 | -------------------------------------------------------------------------------- /examples/droste_effect_1/renderpass1/compute.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const compute = /*wgsl*/` 4 | ${structs} 5 | @compute @workgroup_size(8,8,1) 6 | fn main( 7 | @builtin(global_invocation_id) GlobalId: vec3, 8 | @builtin(workgroup_id) WorkGroupID: vec3, 9 | @builtin(local_invocation_id) LocalInvocationID: vec3 10 | ) { 11 | // let time = params.time; 12 | } 13 | `; 14 | 15 | export default compute; 16 | -------------------------------------------------------------------------------- /examples/droste_effect_1/renderpass1/vert.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const vert = /*wgsl*/` 4 | ${structs} 5 | @vertex 6 | fn main( 7 | @location(0) position: vec4, 8 | @location(1) color: vec4, 9 | @location(2) uv: vec2, 10 | @builtin(vertex_index) vertexIndex: u32 11 | ) -> Fragment { 12 | 13 | return defaultVertexBody(position, color, uv); 14 | } 15 | `; 16 | 17 | export default vert; 18 | -------------------------------------------------------------------------------- /examples/droste_effect_1/structs.js: -------------------------------------------------------------------------------- 1 | export const structs = /*wgsl*/` 2 | 3 | struct Variables { 4 | init: i32, 5 | } 6 | 7 | `; 8 | -------------------------------------------------------------------------------- /examples/events1/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | struct Variable{ 4 | init: f32, 5 | circleRadius:f32, 6 | circlePosition:vec2 7 | } 8 | 9 | @compute @workgroup_size(8,8,1) 10 | fn main( 11 | @builtin(global_invocation_id) GlobalId: vec3, 12 | @builtin(workgroup_id) WorkGroupID: vec3, 13 | @builtin(local_invocation_id) LocalInvocationID: vec3 14 | ) { 15 | let time = params.time; 16 | } 17 | `; 18 | 19 | export default compute; 20 | -------------------------------------------------------------------------------- /examples/events1/frag.js: -------------------------------------------------------------------------------- 1 | import { sdfCircle } from 'sdf'; 2 | import { WHITE, BLUE, GREEN, RED, YELLOW } from 'color'; 3 | import { fnusin } from 'animation'; 4 | 5 | const frag = /*wgsl*/` 6 | 7 | ${sdfCircle} 8 | ${fnusin} 9 | ${WHITE + RED + GREEN + BLUE + YELLOW} 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 16 | @location(3) uvr: vec2, // uv with aspect ratio corrected 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | let f0 = fnusin(1.); 22 | let f1 = fnusin(2.); 23 | 24 | // < ------------ TWO PULSATING CIRCLES 25 | 26 | if(f0 >= .9999){ 27 | left_blink.data[0] = 1.; 28 | left_blink.data[1] = 1.; 29 | left_blink.updated = 1u; 30 | } 31 | 32 | if(f1 >= .9999){ 33 | right_blink.data[0] = 2.; 34 | right_blink.data[1] = 2.; 35 | right_blink.updated = 1u; 36 | } 37 | 38 | let circleValue1 = sdfCircle(vec2f(.2,.5), .01 + f0 * .09, 0., uvr); 39 | let circleValue2 = sdfCircle(vec2f(.8,.5), .01 + f1 * .09, 0., uvr); 40 | 41 | var circle1Color = circleValue1 * WHITE; 42 | var circle2Color = circleValue2 * WHITE; 43 | // > ------------ TWO PULSATING CIRCLES 44 | 45 | return circle1Color + circle2Color; 46 | } 47 | `; 48 | 49 | export default frag; 50 | -------------------------------------------------------------------------------- /examples/events1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import Points from 'points'; 5 | 6 | const base = { 7 | vert, 8 | compute, 9 | frag, 10 | /** 11 | * 12 | * @param {Points} points 13 | */ 14 | init: async points => { 15 | points.addEventListener('left_blink', data => { 16 | console.log('---- Left Circle'); 17 | }, 4); 18 | 19 | points.addEventListener( 20 | 'right_blink', // name of the event (and name of a storage) 21 | data => { // data returned after the event and callback 22 | console.log('---- Right Circle'); 23 | }, 24 | 4 // size of the data to return 25 | ); 26 | }, 27 | /** 28 | * 29 | * @param {Points} points 30 | */ 31 | update: points => { 32 | 33 | }, 34 | /** 35 | * 36 | * @param {Points} points 37 | */ 38 | read: async points => { 39 | // let event = await points.readStorage('event'); 40 | // console.clear(); 41 | // console.log(event); 42 | // console.log(event[0], event[1], event[2]); 43 | } 44 | } 45 | 46 | export default base; 47 | -------------------------------------------------------------------------------- /examples/events1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Variable{ 4 | init: f32, 5 | circleRadius:f32, 6 | circlePosition:vec2 7 | } 8 | 9 | @vertex 10 | fn main( 11 | @location(0) position: vec4, 12 | @location(1) color: vec4, 13 | @location(2) uv: vec2, 14 | @builtin(vertex_index) vertexIndex: u32 15 | ) -> Fragment { 16 | 17 | return defaultVertexBody(position, color, uv); 18 | } 19 | `; 20 | 21 | export default vert; 22 | -------------------------------------------------------------------------------- /examples/imagescale1/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from 'image'; 2 | import { layer } from 'color'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${layer} 8 | 9 | 10 | @fragment 11 | fn main( 12 | @location(0) color: vec4, 13 | @location(1) uv: vec2, 14 | @location(2) ratio: vec2, 15 | @location(3) uvr: vec2, 16 | @location(4) mouse: vec2, 17 | @builtin(position) position: vec4 18 | ) -> @location(0) vec4 { 19 | 20 | let startPosition = vec2(0.,0.); 21 | let rgbaImage1 = texturePosition(image1, feedbackSampler, startPosition, uvr, true); 22 | let rgbaImage2 = texturePosition(image2, feedbackSampler, startPosition, uvr, true); 23 | let rgbaImage3 = texturePosition(image3, feedbackSampler, startPosition, uvr, true); 24 | 25 | var finalColor:vec4 = layer(rgbaImage2, rgbaImage3); 26 | finalColor = layer(rgbaImage1, finalColor); 27 | 28 | return finalColor; 29 | } 30 | `; 31 | 32 | export default frag; 33 | -------------------------------------------------------------------------------- /examples/imagescale1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | const imagescale1 = { 4 | vert, 5 | frag, 6 | init: async points => { 7 | let descriptor = { 8 | addressModeU: 'repeat', 9 | addressModeV: 'clamp-to-edge', 10 | magFilter: 'nearest', 11 | minFilter: 'nearest', 12 | mipmapFilter: 'nearest', 13 | // maxAnisotropy: 10, 14 | // compare: 'always', 15 | } 16 | points.setSampler('feedbackSampler', descriptor); 17 | await points.setTextureImage('image1', './../img/gratia_800x800.jpg'); 18 | await points.setTextureImage('image2', './../img/old_king_600x600.jpg'); 19 | await points.setTextureImage('image3', './../img/unnamed_horror_100x100.png'); 20 | }, 21 | update: points => { 22 | 23 | } 24 | } 25 | 26 | export default imagescale1; 27 | 28 | // enum GPUCompareFunction { 29 | // "never", 30 | // "less", 31 | // "equal", 32 | // "less-equal", 33 | // "greater", 34 | // "not-equal", 35 | // "greater-equal", 36 | // "always", 37 | // }; -------------------------------------------------------------------------------- /examples/imagescale1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/imagetexture1/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from 'image'; 2 | 3 | const frag = /*wgsl*/` 4 | 5 | ${texturePosition} 6 | 7 | 8 | @fragment 9 | fn main( 10 | @location(0) color: vec4, 11 | @location(1) uv: vec2, 12 | @location(2) ratio: vec2, 13 | @location(3) uvr: vec2, 14 | @location(4) mouse: vec2, 15 | @builtin(position) position: vec4 16 | ) -> @location(0) vec4 { 17 | 18 | 19 | let dims: vec2 = textureDimensions(image, 0); 20 | 21 | let startPosition = vec2(.0); 22 | let rgbaImage = texturePosition(image, feedbackSampler, startPosition, uvr / params.scale, true); //* .998046; 23 | let finalColor:vec4 = rgbaImage; 24 | 25 | return finalColor; 26 | } 27 | `; 28 | 29 | export default frag; 30 | -------------------------------------------------------------------------------- /examples/imagetexture1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | } 7 | 8 | const imagetexture1 = { 9 | vert, 10 | frag, 11 | init: async (points, folder) => { 12 | points.setSampler('feedbackSampler', null); 13 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 14 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 15 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 16 | 17 | points.setUniform('scale', options.scale); 18 | 19 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 20 | folder.open(); 21 | }, 22 | update: points => { 23 | points.setUniform('scale', options.scale); 24 | } 25 | } 26 | 27 | export default imagetexture1; -------------------------------------------------------------------------------- /examples/imagetexture1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/imagetexture2/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { brightness } from 'color'; 3 | import { polar } from 'math'; 4 | import { snoise } from 'noise2d'; 5 | import { texturePosition } from 'image'; 6 | 7 | const frag = /*wgsl*/` 8 | 9 | ${fnusin} 10 | ${brightness} 11 | ${polar} 12 | ${snoise} 13 | ${texturePosition} 14 | 15 | 16 | @fragment 17 | fn main( 18 | @location(0) color: vec4, 19 | @location(1) uv: vec2, 20 | @location(2) ratio: vec2, 21 | @location(3) uvr: vec2, 22 | @location(4) mouse: vec2, 23 | @builtin(position) position: vec4 24 | ) -> @location(0) vec4 { 25 | 26 | let n1 = snoise(uv * 10.); 27 | let color0 = vec4(params.color0/255, 1.); 28 | let color1 = vec4(params.color1/255, 1.); 29 | 30 | let dims: vec2 = textureDimensions(image, 0); 31 | var dimsRatio = f32(dims.x) / f32(dims.y); 32 | 33 | // let imageUV = uv * vec2(1,-1 * dimsRatio) * ratio.y / params.sliderA; 34 | //let oldKingUVClamp = uv * vec2(1,1 * dimsRatio) * ratio.x; 35 | let startPosition = vec2(.0); 36 | let rgbaImage = texturePosition(image, feedbackSampler, startPosition, uvr / params.scale, false); //* .998046; 37 | 38 | let b = brightness(rgbaImage); 39 | let d = distance(uv, rgbaImage.xy); 40 | 41 | //let finalColor:vec4 = vec4(b); 42 | let finalColor:vec4 = mix( color0, color1, b) * fnusin(d); 43 | //let finalColor:vec4 = rgbaImage; 44 | 45 | 46 | return finalColor; 47 | } 48 | `; 49 | 50 | export default frag; 51 | -------------------------------------------------------------------------------- /examples/imagetexture2/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | color0: [255, 0, 0], 7 | color1: [255, 255, 0], 8 | } 9 | 10 | const imagetexture2 = { 11 | vert, 12 | frag, 13 | init: async (points, folder) => { 14 | points.setSampler('feedbackSampler', null); 15 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 16 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 17 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 18 | 19 | // TODO: error if scale is placed before the colors 20 | points.setUniform('color0', options.color0, 'vec3f'); 21 | points.setUniform('color1', options.color1, 'vec3f'); 22 | points.setUniform('scale', options.scale, 'f32'); 23 | 24 | 25 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 26 | folder.addColor(options, 'color0'); 27 | folder.addColor(options, 'color1'); 28 | folder.open(); 29 | }, 30 | update: points => { 31 | points.setUniform('scale', options.scale); 32 | points.setUniform('color0', options.color0); 33 | points.setUniform('color1', options.color1); 34 | } 35 | } 36 | 37 | export default imagetexture2; -------------------------------------------------------------------------------- /examples/imagetexture2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/imagetexture3/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { brightness } from 'color'; 3 | import { texturePosition } from 'image'; 4 | 5 | const frag = /*wgsl*/` 6 | 7 | ${fnusin} 8 | ${brightness} 9 | ${texturePosition} 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, 16 | @location(3) uvr: vec2, 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | let lines = sin( uv.x*(uv.x + 3. * fnusin(1.)) ) ; 22 | let startPosition = vec2(0.); 23 | let rgbaImage = texturePosition(image, feedbackSampler, startPosition, uvr * lines / params.scale, false); //* .998046; 24 | 25 | let b = brightness(rgbaImage); 26 | 27 | let finalColor:vec4 = vec4(b); 28 | 29 | 30 | return finalColor; 31 | } 32 | `; 33 | 34 | export default frag; 35 | -------------------------------------------------------------------------------- /examples/imagetexture3/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | } 7 | 8 | const imagetexture3 = { 9 | vert, 10 | frag, 11 | init: async (points, folder) => { 12 | points.setSampler('feedbackSampler', null); 13 | // await points.setTextureImage('oldking', './../img/carmen_lyra_423x643.jpg'); 14 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 15 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 16 | 17 | points.setUniform('scale', options.scale, 'f32'); 18 | 19 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 20 | folder.open(); 21 | }, 22 | update: points => { 23 | points.setUniform('scale', options.scale); 24 | } 25 | } 26 | 27 | export default imagetexture3; -------------------------------------------------------------------------------- /examples/imagetexture3/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/imagetexture4/frag.js: -------------------------------------------------------------------------------- 1 | import { snoise } from 'noise2d'; 2 | import { texturePosition } from 'image'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${snoise} 7 | ${texturePosition} 8 | 9 | 10 | const N = 2.; 11 | 12 | @fragment 13 | fn main( 14 | @location(0) color: vec4, 15 | @location(1) uv: vec2, 16 | @location(2) ratio: vec2, 17 | @location(3) uvr: vec2, 18 | @location(4) mouse: vec2, 19 | @builtin(position) position: vec4 20 | ) -> @location(0) vec4 { 21 | 22 | let startPosition = vec2(.0); 23 | let rgbaImage = texturePosition(image, imageSampler, startPosition, uvr * params.scale, false); //* .998046; 24 | let finalColor:vec4 = rgbaImage; 25 | 26 | return finalColor; 27 | } 28 | `; 29 | 30 | export default frag; 31 | -------------------------------------------------------------------------------- /examples/imagetexture4/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale: 1, 6 | } 7 | 8 | const imagetexture4 = { 9 | vert, 10 | frag, 11 | init: async (points, folder) => { 12 | /** 13 | * @type {GPUObjectDescriptorBase} 14 | */ 15 | let descriptor = { 16 | addressModeU: 'clamp-to-edge', 17 | addressModeV: 'clamp-to-edge', 18 | magFilter: 'nearest', 19 | minFilter: 'nearest', 20 | mipmapFilter: 'nearest', 21 | //maxAnisotropy: 10, 22 | } 23 | 24 | points.setSampler('imageSampler', descriptor); 25 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 26 | await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 27 | // await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 28 | 29 | points.setUniform('scale', options.scale, 'f32'); 30 | 31 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 32 | folder.open(); 33 | }, 34 | update: points => { 35 | points.setUniform('scale', options.scale); 36 | } 37 | } 38 | 39 | export default imagetexture4; -------------------------------------------------------------------------------- /examples/imagetexture4/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/index_files/ic_code_black_24dp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/lavalamp1/index.js: -------------------------------------------------------------------------------- 1 | import Points from 'points'; 2 | import RenderPass from 'renderpass'; 3 | import ShaderType from 'shadertype'; 4 | 5 | import vert1 from './vert.js'; 6 | import frag1 from './frag.js'; 7 | 8 | 9 | /** 10 | * Genuary 12: Lava Lamp 11 | * 12 | */ 13 | 14 | const base = { 15 | renderPasses: [ 16 | new RenderPass(vert1, frag1), 17 | ], 18 | /** 19 | * 20 | * @param {Points} points 21 | */ 22 | init: async points => { 23 | const numObjects = 20; 24 | points.setStorage('variables', 'Variables', false, ShaderType.FRAGMENT); 25 | points.setStorage('objects', `array`, false, ShaderType.FRAGMENT); 26 | }, 27 | update: points => { 28 | 29 | } 30 | } 31 | 32 | export default base; -------------------------------------------------------------------------------- /examples/lavalamp1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | return defaultVertexBody(position, color, uv); 11 | } 12 | `; 13 | 14 | export default vert; 15 | -------------------------------------------------------------------------------- /examples/layers1/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | @compute @workgroup_size(8,8,1) 4 | fn main( 5 | @builtin(global_invocation_id) GlobalId: vec3, 6 | @builtin(workgroup_id) WorkGroupID: vec3, 7 | @builtin(local_invocation_id) LocalInvocationID: vec3 8 | ) { 9 | // compute code 10 | } 11 | `; 12 | 13 | export default compute; 14 | -------------------------------------------------------------------------------- /examples/layers1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | const frag = /*wgsl*/` 3 | 4 | ${fnusin} 5 | 6 | @fragment 7 | fn main( 8 | @location(0) color: vec4, 9 | @location(1) uv: vec2, 10 | @location(2) ratio: vec2, 11 | @location(3) uvr: vec2, 12 | @location(4) mouse: vec2, 13 | @builtin(position) position: vec4 14 | ) -> @location(0) vec4 { 15 | 16 | let cellSize = 20. + 10. * fnusin(1.); 17 | let a = sin(uvr.x * cellSize) * sin(uvr.y * cellSize); 18 | let b = sin(uvr.x * uvr.y * 10. * 9.1 * .25 ); 19 | let c = fnusin(uvr.x * uvr.y * 10.); 20 | let d = distance(a,b); 21 | let f = d * uvr.x * uvr.y; 22 | let finalColor:vec4 = vec4(a*d,f*c*a,f, 1.); 23 | 24 | return finalColor; 25 | } 26 | `; 27 | 28 | export default frag; 29 | -------------------------------------------------------------------------------- /examples/layers1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | const layers1 = { 5 | vert, 6 | compute, 7 | frag, 8 | init: async points => { 9 | const numPoints = 800*800; 10 | points.setUniform('numPoints', numPoints); 11 | // points.setStorage('points', numPoints, `array, ${numPoints}>`, 4); 12 | points.setLayers(2); 13 | }, 14 | update: points => { 15 | 16 | } 17 | } 18 | 19 | export default layers1; -------------------------------------------------------------------------------- /examples/layers1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/mandelbrot1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin, fucos, fusin } from 'animation'; 2 | const frag = /*wgsl*/` 3 | 4 | ${fnusin} 5 | ${fusin} 6 | ${fucos} 7 | 8 | 9 | const NUMITERATIONS = 40; 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 16 | @location(3) uvr: vec2, // uv with aspect ratio corrected 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | let center = vec2(.5,.5) * ratio; 22 | 23 | let c_re = (uvr.x - center.x) / params.scale; 24 | let c_im = (uvr.y - center.y) / params.scale; 25 | 26 | var x = 0.; 27 | var y = 0.; 28 | var iteration = 0; 29 | while(x * x + y * y <= 4 && iteration < NUMITERATIONS){ 30 | var x_new = x * x - y * y + c_re; 31 | y = 2 * x * y + c_im; 32 | x = x_new; 33 | iteration++; 34 | } 35 | 36 | let percentageIteration = f32(iteration) / NUMITERATIONS; 37 | 38 | 39 | var finalColor:vec4f = vec4(); 40 | 41 | if(iteration < NUMITERATIONS){ 42 | finalColor = vec4(percentageIteration, percentageIteration * uvr.x * fusin(1), percentageIteration * uvr.y, 1); 43 | }else{ 44 | finalColor = vec4(percentageIteration, percentageIteration * uvr.x, 1 - percentageIteration * uvr.y, 1); 45 | } 46 | 47 | return finalColor; 48 | } 49 | `; 50 | 51 | export default frag; 52 | -------------------------------------------------------------------------------- /examples/mandelbrot1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | import Points from 'points'; 4 | 5 | const options = { 6 | scale: 0.53, 7 | } 8 | 9 | const base = { 10 | vert, 11 | frag, 12 | /** 13 | * 14 | * @param {Points} points 15 | */ 16 | init: async (points, folder) => { 17 | points.setUniform('scale', options.scale); 18 | folder.add(options, 'scale', -1, 1, .0001).name('scale'); 19 | folder.open(); 20 | }, 21 | update: points => { 22 | points.setUniform('scale', options.scale); 23 | } 24 | } 25 | 26 | export default base; 27 | -------------------------------------------------------------------------------- /examples/mandelbrot1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/mesh1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | const frag = /*wgsl*/` 3 | 4 | ${fnusin} 5 | 6 | @fragment 7 | fn main( 8 | @location(0) color: vec4, 9 | @location(1) uv: vec2, 10 | @location(2) ratio: vec2, 11 | @location(3) uvr: vec2, 12 | @location(4) mouse: vec2, 13 | @builtin(position) position: vec4 14 | ) -> @location(0) vec4 { 15 | 16 | let cellSize = 20. + 10. * fnusin(1.); 17 | let a = sin(uvr.x * cellSize) * sin(uvr.y * cellSize); 18 | let b = sin(uvr.x * uvr.y * 10. * 9.1 * .25 ); 19 | let c = fnusin(uvr.x * uvr.y * 10.); 20 | let d = distance(a,b); 21 | let f = d * uvr.x * uvr.y; 22 | let finalColor:vec4 = vec4(a*d,f*c*a,f, 1.); 23 | 24 | return finalColor; 25 | } 26 | `; 27 | 28 | export default frag; 29 | -------------------------------------------------------------------------------- /examples/mesh1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | const mesh1 = { 4 | vert, 5 | frag, 6 | init: async points => { 7 | points.setMeshDensity(20,20); 8 | }, 9 | update: points => { 10 | 11 | } 12 | } 13 | 14 | export default mesh1; -------------------------------------------------------------------------------- /examples/mesh1/vert.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | const vert = /*wgsl*/` 3 | 4 | ${fnusin} 5 | 6 | @vertex 7 | fn main( 8 | @location(0) position: vec4, 9 | @location(1) color: vec4, 10 | @location(2) uv: vec2, 11 | @builtin(vertex_index) vertexIndex: u32 12 | ) -> Fragment { 13 | 14 | var modifiedPosition = position; 15 | modifiedPosition.w = modifiedPosition.w + sin(f32(vertexIndex) * (params.time) * .01) * .1; 16 | 17 | return defaultVertexBody(modifiedPosition, color, uv); 18 | } 19 | `; 20 | 21 | export default vert; 22 | -------------------------------------------------------------------------------- /examples/mouse1/frag.js: -------------------------------------------------------------------------------- 1 | import { showDebugCross, showDebugFrame } from 'debug'; 2 | import { sdfLine, sdfSegment } from 'sdf'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${sdfSegment} 7 | ${sdfLine} 8 | ${showDebugCross} 9 | ${showDebugFrame} 10 | 11 | 12 | @fragment 13 | fn main( 14 | @location(0) color: vec4, 15 | @location(1) uv: vec2, 16 | @location(2) ratio: vec2, 17 | @location(3) uvr: vec2, 18 | @location(4) mouse: vec2, 19 | @builtin(position) position: vec4 20 | ) -> @location(0) vec4 { 21 | 22 | let startPosition = mouse * ratio;//vec2(.0); 23 | 24 | let positionCross = showDebugCross(startPosition, vec4(1,0,0,1.), uvr); 25 | 26 | let frame = showDebugFrame(vec4(1,0,0,1.), uvr); 27 | 28 | let finalColor:vec4 = positionCross + frame; 29 | 30 | return finalColor; 31 | } 32 | `; 33 | 34 | export default frag; 35 | -------------------------------------------------------------------------------- /examples/mouse1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | const mouse1 = { 4 | vert, 5 | frag, 6 | init: async points => { 7 | 8 | }, 9 | update: points => { 10 | 11 | } 12 | } 13 | 14 | export default mouse1; -------------------------------------------------------------------------------- /examples/mouse1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/mouseclickscroll1/frag.js: -------------------------------------------------------------------------------- 1 | import { sdfCircle } from 'sdf'; 2 | import { GREEN, RED } from 'color'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | struct Variable{ 7 | init: f32, 8 | circleRadius:f32, 9 | circlePosition:vec2 10 | } 11 | 12 | ${sdfCircle} 13 | ${RED + GREEN} 14 | 15 | @fragment 16 | fn main( 17 | @location(0) color: vec4, 18 | @location(1) uv: vec2, 19 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 20 | @location(3) uvr: vec2, // uv with aspect ratio corrected 21 | @location(4) mouse: vec2, 22 | @builtin(position) position: vec4 23 | ) -> @location(0) vec4 { 24 | 25 | if(variables.init == 0.){ 26 | variables.circleRadius = .1; 27 | variables.circlePosition = vec2(.5, .5) * ratio; 28 | 29 | variables.init = 1.; 30 | } 31 | 32 | if(params.mouseWheel == 1.){ 33 | if(params.mouseDelta.y > 0.){ 34 | variables.circleRadius += .0001; 35 | }else{ 36 | variables.circleRadius -= .0001; 37 | } 38 | } 39 | 40 | if(params.mouseClick == 1.){ 41 | variables.circlePosition = mouse * ratio; 42 | } 43 | 44 | let circleValue = sdfCircle(variables.circlePosition, variables.circleRadius, 0., uvr); 45 | var finalColor = vec4(1.) * circleValue; 46 | 47 | if(params.mouseDown == 1.){ 48 | finalColor *= GREEN; 49 | }else{ 50 | finalColor *= RED; 51 | } 52 | 53 | return finalColor; 54 | } 55 | `; 56 | 57 | export default frag; 58 | -------------------------------------------------------------------------------- /examples/mouseclickscroll1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const mouseclickscroll1 = { 5 | vert, 6 | frag, 7 | init: async points => { 8 | points.setStorage('variables', 'Variable'); 9 | }, 10 | update: points => { 11 | 12 | } 13 | } 14 | 15 | export default mouseclickscroll1; 16 | -------------------------------------------------------------------------------- /examples/mouseclickscroll1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | // TODO: 1262 how to remove this from vertex shader 4 | // please check TODO: 1262 5 | 6 | struct Variable{ 7 | init: f32, 8 | circleRadius:f32, 9 | circlePosition:vec2 10 | } 11 | 12 | @vertex 13 | fn main( 14 | @location(0) position: vec4, 15 | @location(1) color: vec4, 16 | @location(2) uv: vec2, 17 | @builtin(vertex_index) vertexIndex: u32 18 | ) -> Fragment { 19 | 20 | return defaultVertexBody(position, color, uv); 21 | } 22 | `; 23 | 24 | export default vert; 25 | -------------------------------------------------------------------------------- /examples/noise1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { snoise } from 'noise2d'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | struct Variable{ 7 | valueNoiseCreated:f32, 8 | } 9 | 10 | ${fnusin} 11 | ${snoise} 12 | 13 | @fragment 14 | fn main( 15 | @location(0) color: vec4, 16 | @location(1) uv: vec2, 17 | @location(2) ratio: vec2, 18 | @location(3) uvr: vec2, 19 | @location(4) mouse: vec2, 20 | @builtin(position) position: vec4 21 | ) -> @location(0) vec4 { 22 | 23 | let cellSize = 20. + 10. * fnusin(1.); 24 | let a = sin(uvr.x * cellSize) * sin(uvr.y * cellSize); 25 | let b = sin(uvr.x * uvr.y * 10. * 9.1 * .25 ); 26 | let c = fnusin(uvr.x * uvr.y * 10.); 27 | let d = distance(a,b); 28 | let f = d * uvr.x * uvr.y; 29 | let n1 = snoise(uvr * 200. * params.scale0 + 10. * fnusin(.01)); 30 | let n2 = snoise(uvr * 200. * params.scale1 + 10. * fnusin(.02)); 31 | let n3 = snoise(uvr * 200. * params.scale2 + 10. * fnusin(.03)); 32 | //let finalColor:vec4 = vec4(a*d*n2,f*c*a*n3,f * n1, 1.); 33 | //let finalColor = vec4(fract(n1 * n2 + n3)); 34 | let n4 = fract(n1 * n2 + n3); 35 | //let finalColor = vec4(n4, uvr.x - n4, 0, 1); 36 | let finalColor = mix( vec4(1, 0, 0, 1.) , vec4(1, 1, 0, 1.), n4 ); 37 | 38 | return finalColor; 39 | } 40 | `; 41 | 42 | export default frag; 43 | -------------------------------------------------------------------------------- /examples/noise1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const options = { 5 | scale0: .291, 6 | scale1: .018, 7 | scale2: .059, 8 | } 9 | 10 | const noise1 = { 11 | vert, 12 | frag, 13 | init: async (points, folder) => { 14 | const numPoints = 800*800; 15 | points.setUniform('value_noise_data_length', numPoints); 16 | points.setStorage('value_noise_data', `array`); 17 | points.setStorage('variables', 'Variable'); 18 | 19 | points.setUniform('scale0', options.scale0, 'f32'); 20 | points.setUniform('scale1', options.scale1, 'f32'); 21 | points.setUniform('scale2', options.scale2, 'f32'); 22 | 23 | folder.add(options, 'scale0', 0, 1, .0001).name('Scale 0'); 24 | folder.add(options, 'scale1', 0, 1, .0001).name('Scale 1'); 25 | folder.add(options, 'scale2', 0, 1, .0001).name('Scale 2'); 26 | folder.open(); 27 | }, 28 | update: points => { 29 | points.setUniform('scale0', options.scale0); 30 | points.setUniform('scale1', options.scale1); 31 | points.setUniform('scale2', options.scale2); 32 | } 33 | } 34 | 35 | export default noise1; -------------------------------------------------------------------------------- /examples/noise1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Variable{ 4 | valueNoiseCreated:f32, 5 | } 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @location(2) uv: vec2, 12 | @builtin(vertex_index) vertexIndex: u32 13 | ) -> Fragment { 14 | 15 | return defaultVertexBody(position, color, uv); 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/noisecircle1/frag.js: -------------------------------------------------------------------------------- 1 | import { sdfCircle } from 'sdf'; 2 | import { snoise } from 'noise2d'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${sdfCircle} 7 | ${snoise} 8 | 9 | // this looks like a sunset 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, 16 | @location(3) uvr: vec2, 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | let time = params.time; 22 | 23 | var circle = sdfCircle(vec2(.5,.5) * ratio, .2, .1, uvr); 24 | 25 | var n1 = (snoise(uvr * 5.14 + 200. * fract(time * -.01))+1.)*.5; 26 | //var n2 = (snoise(uvr * 15.14 + 200. * fract(time * -.01))+1.)*.5; 27 | let skewMask = vec2(1, 1.1); 28 | let mask = (1.-sdfCircle(vec2(.5,.5) * ratio, .0999, .5, uvr * skewMask )); 29 | let result = vec4(1.) * mask * n1 * circle + circle; 30 | 31 | var finalColor:vec4 = mask * vec4(1,.5,0,1) + mix( vec4(1,0,0,result.a), vec4(1,.5,0,1), result ); 32 | 33 | return finalColor; 34 | } 35 | `; 36 | 37 | export default frag; 38 | -------------------------------------------------------------------------------- /examples/noisecircle1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | const noisecircle1 = { 4 | vert, 5 | frag, 6 | init: async points => { 7 | 8 | }, 9 | update: points => { 10 | 11 | } 12 | } 13 | 14 | export default noisecircle1; -------------------------------------------------------------------------------- /examples/noisecircle1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Variable{ 4 | particlesCreated: f32, 5 | } 6 | 7 | 8 | @vertex 9 | fn main( 10 | @location(0) position: vec4, 11 | @location(1) color: vec4, 12 | @location(2) uv: vec2, 13 | @builtin(vertex_index) vertexIndex: u32 14 | ) -> Fragment { 15 | 16 | return defaultVertexBody(position, color, uv); 17 | } 18 | `; 19 | 20 | export default vert; 21 | -------------------------------------------------------------------------------- /examples/params_test/compute.js: -------------------------------------------------------------------------------- 1 | import { structs } from './structs.js'; 2 | 3 | const compute = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @compute @workgroup_size(8,8,1) 8 | fn main( 9 | @builtin(global_invocation_id) GlobalId: vec3, 10 | @builtin(workgroup_id) WorkGroupID: vec3, 11 | @builtin(local_invocation_id) LocalInvocationID: vec3 12 | ) { 13 | let time = params.time; 14 | } 15 | `; 16 | 17 | export default compute; 18 | -------------------------------------------------------------------------------- /examples/params_test/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { structs } from './structs.js'; 3 | import { rand } from 'random'; 4 | 5 | const frag = /*wgsl*/` 6 | 7 | ${fnusin} 8 | ${structs} 9 | ${rand} 10 | 11 | // struct Colors{ 12 | // // items: array< vec4, 800*800 > 13 | // items: array< vec4, 640000 > 14 | // } 15 | 16 | @fragment 17 | fn main( 18 | @location(0) color: vec4, 19 | @location(1) uv: vec2, 20 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 21 | @location(3) uvr: vec2, // uv with aspect ratio corrected 22 | @location(4) mouse: vec2, 23 | @builtin(position) position: vec4 24 | ) -> @location(0) vec4 { 25 | 26 | var finalColor:vec4 = vec4(); 27 | 28 | if(variables.init == 0.){ 29 | rand_seed = uvr + params.time; 30 | rand(); 31 | finalColor = vec4(rand_seed, 0, 1); 32 | variables.init = 1; 33 | variables.color = finalColor; 34 | } 35 | finalColor = variables.color; 36 | 37 | let c = values[1]; 38 | 39 | 40 | return variables.color; 41 | } 42 | `; 43 | 44 | export default frag; 45 | -------------------------------------------------------------------------------- /examples/params_test/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import Points from '.points'; 5 | import { dataSize } from 'datasize'; 6 | 7 | const base = { 8 | vert, 9 | compute, 10 | frag, 11 | /** 12 | * 13 | * @param {Points} points 14 | */ 15 | init: async points => { 16 | 17 | 18 | var startTime = performance.now() 19 | const result = dataSize(` 20 | 21 | struct Params { 22 | sliderA:f32, 23 | sliderB:f32, 24 | sliderC:f32, 25 | right:vec3, 26 | up:vec3, 27 | modelViewProjectionMatrix:mat4x4, 28 | time:f32, 29 | epoch:f32, 30 | screen:vec2f, 31 | mouse:vec2f, 32 | mouseClick:f32, 33 | mouseDown:f32, 34 | mouseDelta:vec2f, 35 | mouseWheel:f32, 36 | 37 | } 38 | 39 | 40 | 41 | `); 42 | var endTime = performance.now() 43 | 44 | console.log(`Call to doSomething took ${endTime - startTime} milliseconds`) 45 | console.log(result); 46 | for (let [r, c] of result) { 47 | console.log(r, c.bytes) 48 | 49 | } 50 | 51 | 52 | points.setStorageMap('test', [0, 0, 1, .5], 'vec4f'); 53 | 54 | 55 | points.setStorage('variables', 'Variable'); 56 | points.setStorage('test2', 'TestStruct'); 57 | 58 | points.setUniform('test3', [1, 0, 0, 1], 'vec4f'); 59 | 60 | points.setStorage('anim', 'array'); 61 | 62 | points.setStorageMap('values', [1.0, 99.0], 'array'); 63 | 64 | // points.setUniform('test4', [1, 0, 0, 1], 'array< vec4, 1 >'); 65 | // TODO: throw error if using array in uniform? 66 | // points.setUniform('test5', [1,1,1,1], 'array'); 67 | 68 | 69 | }, 70 | update: points => { 71 | 72 | } 73 | } 74 | 75 | export default base; -------------------------------------------------------------------------------- /examples/params_test/structs.js: -------------------------------------------------------------------------------- 1 | export const structs = /*wgsl*/` 2 | struct Variable{ 3 | init: f32, 4 | color: vec4f, 5 | } 6 | 7 | struct TestStruct { 8 | color1: vec4f, 9 | value: f32, 10 | } 11 | `; 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/params_test/vert.js: -------------------------------------------------------------------------------- 1 | import { structs } from './structs.js'; 2 | 3 | const vert = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @location(2) uv: vec2, 12 | @builtin(vertex_index) vertexIndex: u32 13 | ) -> Fragment { 14 | 15 | return defaultVertexBody(position, color, uv); 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/pointstitle1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | import Points from 'points'; 4 | 5 | const pointstitle1 = { 6 | vert, 7 | frag, 8 | /** 9 | * 10 | * @param {Points} points 11 | */ 12 | init: async points => { 13 | 14 | await points.setTextureImage('font', './../img/inconsolata_regular_8x22.png'); 15 | 16 | points.setSampler('imageSampler', null); 17 | 18 | }, 19 | update: points => { 20 | 21 | } 22 | } 23 | 24 | export default pointstitle1; -------------------------------------------------------------------------------- /examples/pointstitle1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/random1/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | @compute @workgroup_size(8,8,1) 4 | fn main( 5 | @builtin(global_invocation_id) GlobalId: vec3, 6 | @builtin(workgroup_id) WorkGroupID: vec3, 7 | @builtin(local_invocation_id) LocalInvocationID: vec3 8 | ) { 9 | let r = params.randNumber; 10 | let r2 = params.randNumber2; 11 | 12 | textureStore(outputTex, vec2( u32(r * 800.) , u32(r2 * 800.) ), vec4(1, params.sliderA,0,1)); 13 | } 14 | `; 15 | 16 | export default compute; 17 | -------------------------------------------------------------------------------- /examples/random1/frag.js: -------------------------------------------------------------------------------- 1 | import { fusin } from 'animation'; 2 | import { texturePosition } from 'image'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${fusin} 7 | ${texturePosition} 8 | 9 | @fragment 10 | fn main( 11 | @location(0) color: vec4, 12 | @location(1) uv: vec2, 13 | @location(2) ratio: vec2, 14 | @location(3) uvr: vec2, 15 | @location(4) mouse: vec2, 16 | @builtin(position) position: vec4 17 | ) -> @location(0) vec4 { 18 | 19 | 20 | let startPosition = vec2(0.); 21 | let texColorCompute = texturePosition(computeTexture, computeTextureSampler, startPosition, uvr, false); 22 | 23 | 24 | let d = distance(uvr, vec2(.5 + .1 * fusin(2.), .5 + .1 * fusin(4.123))); 25 | var c = 1.; 26 | if(d > .1){ 27 | c = 0.; 28 | } 29 | 30 | 31 | let finalColor:vec4 = vec4(c) + texColorCompute; 32 | 33 | return finalColor; 34 | } 35 | `; 36 | 37 | export default frag; 38 | -------------------------------------------------------------------------------- /examples/random1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import ShaderType from 'shadertype'; 5 | 6 | const options = { 7 | sliderA: .291, 8 | } 9 | 10 | const random1 = { 11 | vert, 12 | compute, 13 | frag, 14 | init: async (points, folder) => { 15 | points.setUniform('randNumber', 0); 16 | points.setUniform('randNumber2', 0); 17 | points.setSampler('computeTextureSampler'); 18 | points.setBindingTexture('outputTex', 'computeTexture'); 19 | 20 | points.setUniform('sliderA', options.sliderA, 'f32'); 21 | folder.add(options, 'sliderA', 0, 1, .0001).name('sliderA'); 22 | folder.open(); 23 | }, 24 | update: points => { 25 | points.setUniform('randNumber', Math.random()); 26 | points.setUniform('randNumber2', Math.random()); 27 | 28 | points.setUniform('sliderA', options.sliderA); 29 | } 30 | } 31 | 32 | export default random1; -------------------------------------------------------------------------------- /examples/random1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | struct Star{ 4 | a: f32, 5 | b: f32, 6 | c: f32, 7 | d: f32, 8 | } 9 | 10 | @vertex 11 | fn main( 12 | @location(0) position: vec4, 13 | @location(1) color: vec4, 14 | @location(2) uv: vec2, 15 | @builtin(vertex_index) vertexIndex: u32 16 | ) -> Fragment { 17 | 18 | return defaultVertexBody(position, color, uv); 19 | } 20 | `; 21 | 22 | export default vert; -------------------------------------------------------------------------------- /examples/random2/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | const workgroupSize = 8; 4 | 5 | @compute @workgroup_size(workgroupSize,workgroupSize,1) 6 | fn main( 7 | @builtin(global_invocation_id) GlobalId: vec3, 8 | @builtin(workgroup_id) WorkGroupID: vec3, 9 | @builtin(local_invocation_id) LocalInvocationID: vec3 10 | ) { 11 | let dims = textureDimensions(feedbackTexture); 12 | 13 | //-------------------------------------------------- 14 | 15 | let pointIndex = i32(GlobalId.y + (GlobalId.x * dims.x)); 16 | let c = rands[pointIndex]; 17 | 18 | textureStore(outputTex, GlobalId.xy, vec4(c)); 19 | storageBarrier(); 20 | } 21 | `; 22 | 23 | export default compute; 24 | -------------------------------------------------------------------------------- /examples/random2/frag.js: -------------------------------------------------------------------------------- 1 | import { fusin } from 'animation'; 2 | import { texturePosition } from 'image'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | 7 | ${fusin} 8 | ${texturePosition} 9 | 10 | @fragment 11 | fn main( 12 | @location(0) color: vec4, 13 | @location(1) uv: vec2, 14 | @location(2) ratio: vec2, 15 | @location(3) uvr: vec2, 16 | @location(4) mouse: vec2, 17 | @builtin(position) position: vec4 18 | ) -> @location(0) vec4 { 19 | 20 | let startPosition = vec2(0.,0.); 21 | // let texColor = texturePosition(feedbackTexture, feedbackSampler, startPosition, uvr, false); 22 | let texColorCompute = texturePosition(computeTexture, feedbackSampler, startPosition, uvr, false); 23 | 24 | 25 | let d = distance(uvr, vec2(.5 + .1 * fusin(2.), .5 + .1 * fusin(4.123))); 26 | var c = 1.; 27 | if(d > .1){ 28 | c = 0.; 29 | } 30 | 31 | let finalColor:vec4 = vec4(c) + texColorCompute; 32 | 33 | return finalColor; 34 | } 35 | `; 36 | 37 | export default frag; 38 | -------------------------------------------------------------------------------- /examples/random2/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | 6 | let data = []; 7 | 8 | const random2 = { 9 | renderPasses: [ 10 | new RenderPass(vert, frag, compute, 800, 800) 11 | ], 12 | init: async points => { 13 | points.setUniform('randNumber', 0); 14 | points.setUniform('randNumber2', 0); 15 | // let data = []; 16 | for (let k = 0; k < 800*800; k++) { 17 | data.push(Math.random()); 18 | } 19 | points.setStorageMap('rands', data, 'array'); 20 | points.setSampler('feedbackSampler'); 21 | points.setTexture2d('feedbackTexture', true); 22 | points.setBindingTexture('outputTex', 'computeTexture'); 23 | }, 24 | update: points => { 25 | points.setUniform('randNumber', Math.random()); 26 | points.setUniform('randNumber2', Math.random()); 27 | // data = []; 28 | for (let k = 0; k < 800*800; k++) { 29 | data[k] = Math.random(); 30 | } 31 | // points.updateStorageMap('rands', data); 32 | } 33 | } 34 | 35 | export default random2; -------------------------------------------------------------------------------- /examples/random2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | return defaultVertexBody(position, color, uv); 11 | } 12 | `; 13 | 14 | export default vert; -------------------------------------------------------------------------------- /examples/random3/compute.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { RGBAFromHSV } from 'color'; 3 | import { rand, random } from 'random'; 4 | 5 | const compute = /*wgsl*/` 6 | 7 | ${random} 8 | ${rand} 9 | ${RGBAFromHSV} 10 | ${fnusin} 11 | 12 | const workgroupSize = 1; 13 | 14 | @compute @workgroup_size(workgroupSize,workgroupSize,1) 15 | fn main( 16 | @builtin(global_invocation_id) GlobalId: vec3, 17 | @builtin(workgroup_id) WorkGroupID: vec3, 18 | @builtin(local_invocation_id) LocalInvocationID: vec3 19 | ) { 20 | 21 | let numColumns:f32 = params.screen.x; 22 | let numRows:f32 = params.screen.y; 23 | 24 | rand_seed.x += f32(WorkGroupID.x); 25 | rand_seed.y += f32(WorkGroupID.y); 26 | 27 | seed += i32(WorkGroupID.x + WorkGroupID.y); 28 | 29 | let randNumber = rand(); 30 | rand_seed.y += randNumber + fract(params.sliderA); 31 | var v = 0.; 32 | if(randNumber < .5){ 33 | v = 1.; 34 | } 35 | 36 | // textureStore(outputTex, GlobalId.xy, vec4(randNumber)); 37 | // textureStore(outputTex, GlobalId.xy, RGBAFromHSV(randNumber, 1, 1)); 38 | // textureStore(outputTex, GlobalId.xy, RGBAFromHSV( fnusin(randNumber), 1, 1)); 39 | // textureStore(outputTex, GlobalId.xy, vec4( fnusin(randNumber))); 40 | 41 | textureStore(outputTex, GlobalId.xy, vec4( fract(randNumber + fnusin(1)))); 42 | // textureStore(outputTex, WorkGroupID.xy, vec4( fract(randNumber + fnusin(1)))); 43 | // textureStore(outputTex, LocalInvocationID.xy, vec4( fract(randNumber + fnusin(1)))); 44 | 45 | } 46 | `; 47 | 48 | export default compute; 49 | -------------------------------------------------------------------------------- /examples/random3/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from 'image'; 2 | 3 | const frag = /*wgsl*/` 4 | 5 | ${texturePosition} 6 | 7 | @fragment 8 | fn main( 9 | @location(0) color: vec4, 10 | @location(1) uv: vec2, 11 | @location(2) ratio: vec2, 12 | @location(3) uvr: vec2, 13 | @location(4) mouse: vec2, 14 | @builtin(position) position: vec4 15 | ) -> @location(0) vec4 { 16 | 17 | let startPosition = vec2(0.); 18 | let texColorCompute = texturePosition(computeTexture, feedbackSampler, startPosition, uvr, false); 19 | let finalColor:vec4 = texColorCompute; 20 | 21 | return finalColor; 22 | } 23 | `; 24 | 25 | export default frag; 26 | -------------------------------------------------------------------------------- /examples/random3/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | 6 | const options = { 7 | sliderA: .291, 8 | } 9 | 10 | const random3 = { 11 | 12 | renderPasses: [ 13 | new RenderPass(vert, frag, compute, 800, 800) 14 | ], 15 | init: async (points, folder) => { 16 | points.setSampler('feedbackSampler'); 17 | points.setTexture2d('feedbackTexture', true); 18 | points.setBindingTexture('outputTex', 'computeTexture'); 19 | 20 | points.setUniform('sliderA', options.sliderA, 'f32'); 21 | folder.add(options, 'sliderA', 0, 1, .0001).name('sliderA'); 22 | folder.open(); 23 | }, 24 | update: points => { 25 | points.setUniform('sliderA', options.sliderA); 26 | } 27 | } 28 | 29 | export default random3; -------------------------------------------------------------------------------- /examples/random3/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; -------------------------------------------------------------------------------- /examples/renderpasses1/index.js: -------------------------------------------------------------------------------- 1 | import vert1 from './renderpass1/vert.js'; 2 | import frag1 from './renderpass1/frag.js'; 3 | 4 | import vert2 from './renderpass2/vert.js'; 5 | import frag2 from './renderpass2/frag.js'; 6 | 7 | import RenderPass from 'renderpass'; 8 | 9 | const options = { 10 | rotation: .8, 11 | } 12 | 13 | const renderpasses1 = { 14 | /** 15 | * Render Passes expect to have an order 16 | */ 17 | renderPasses: [ 18 | new RenderPass(vert1, frag1), 19 | new RenderPass(vert2, frag2), 20 | ], 21 | init: async (points, folder) => { 22 | points.setSampler('imageSampler', null); 23 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 24 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 25 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 26 | points.setSampler('feedbackSampler', null); 27 | points.setTexture2d('feedbackTexture', true); 28 | 29 | points.setUniform('rotation', options.rotation, 'f32'); 30 | folder.add(options, 'rotation', 0, 1, .0001).name('Rotation'); 31 | folder.open(); 32 | }, 33 | update: points => { 34 | points.setUniform('rotation', options.rotation); 35 | } 36 | } 37 | 38 | export default renderpasses1; -------------------------------------------------------------------------------- /examples/renderpasses1/renderpass1/frag.js: -------------------------------------------------------------------------------- 1 | import { fusin } from 'animation'; 2 | import { texturePosition } from 'image'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${fusin} 8 | 9 | @fragment 10 | fn main( 11 | @location(0) color: vec4, 12 | @location(1) uv: vec2, 13 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 14 | @location(3) uvr: vec2, // uv with aspect ratio corrected 15 | @location(4) mouse: vec2, 16 | @builtin(position) position: vec4 17 | ) -> @location(0) vec4 { 18 | 19 | let imageColor = texturePosition(image, imageSampler, vec2(0., 0), uvr, true); 20 | // first render pass doesn't use the feedback texture, it's the second pass 21 | // _ = texturePosition(feedbackTexture, feedbackSampler, vec2(0,0), uvr, true); 22 | 23 | let d = distance(uvr, vec2(.5 + .1 * fusin(2.), .5 + .1 * fusin(4.123))); 24 | var c = 1.; 25 | if(d > .1){ 26 | c = 0.; 27 | } 28 | 29 | let finalColor = imageColor + c * vec4(1); 30 | 31 | return finalColor; 32 | } 33 | `; 34 | 35 | export default frag; 36 | -------------------------------------------------------------------------------- /examples/renderpasses1/renderpass1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/renderpasses1/renderpass2/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from 'image'; 2 | import { PI, rotateVector } from 'math'; 3 | import { blur9 } from 'effects'; 4 | 5 | const frag = /*wgsl*/` 6 | 7 | ${texturePosition} 8 | ${rotateVector} 9 | ${PI} 10 | ${blur9} 11 | 12 | 13 | 14 | @fragment 15 | fn main( 16 | @location(0) color: vec4, 17 | @location(1) uv: vec2, 18 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 19 | @location(3) uvr: vec2, // uv with aspect ratio corrected 20 | @location(4) mouse: vec2, 21 | @builtin(position) position: vec4 22 | ) -> @location(0) vec4 { 23 | 24 | // second pass doesn't use the image, that's the first pass 25 | // _ = texturePosition(image, imageSampler, vec2(0,0), uvr, true); 26 | let feedbackColor = blur9(feedbackTexture, feedbackSampler, vec2(0.,0), uvr, vec2(100.,100.), rotateVector(vec2(.4,.0), 2 * PI * params.rotation)); 27 | 28 | let finalColor = feedbackColor; 29 | 30 | return finalColor; 31 | } 32 | `; 33 | 34 | export default frag; 35 | -------------------------------------------------------------------------------- /examples/renderpasses1/renderpass2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/renderpasses2/index.js: -------------------------------------------------------------------------------- 1 | import vert1 from './renderpass1/vert.js'; 2 | import frag1 from './renderpass1/frag.js'; 3 | 4 | import RenderPass from 'renderpass'; 5 | import RenderPasses from 'renderpasses'; 6 | 7 | const renderpasses1 = { 8 | /** 9 | * Render Passes expect to have an order 10 | */ 11 | renderPasses: [ 12 | new RenderPass(vert1, frag1), 13 | // new RenderPass(yellow.vertexShader, yellow.fragmentShader), 14 | ], 15 | init: async points => { 16 | // await yellow.init(points, {blendAmount: .5}); 17 | points.setSampler('imageSampler', null); 18 | // await points.setTextureImage('image', './../img/carmen_lyra_423x643.jpg'); 19 | // await points.setTextureImage('image', './../img/old_king_600x600.jpg'); 20 | await points.setTextureImage('image', './../img/absulit_800x800.jpg'); 21 | points.setSampler('feedbackSampler'); 22 | points.setTexture2d('feedbackTexture', true); 23 | 24 | 25 | RenderPasses.grayscale(points); 26 | RenderPasses.chromaticAberration(points, .02); 27 | RenderPasses.color(points, .5, 1, 0, 1, .5); 28 | RenderPasses.pixelate(points, 10, 10); 29 | RenderPasses.lensDistortion(points, .4, .01); 30 | RenderPasses.filmgrain(points); 31 | RenderPasses.bloom(points, .5); 32 | RenderPasses.blur(points, 100, 100, .4, 0, 0.0); 33 | RenderPasses.waves(points, .05, .03); 34 | 35 | }, 36 | update: points => { 37 | 38 | } 39 | } 40 | 41 | export default renderpasses1; -------------------------------------------------------------------------------- /examples/renderpasses2/renderpass1/frag.js: -------------------------------------------------------------------------------- 1 | import { fusin } from 'animation'; 2 | import { texturePosition } from 'image'; 3 | 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${fusin} 8 | 9 | @fragment 10 | fn main( 11 | @location(0) color: vec4, 12 | @location(1) uv: vec2, 13 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 14 | @location(3) uvr: vec2, // uv with aspect ratio corrected 15 | @location(4) mouse: vec2, 16 | @builtin(position) position: vec4 17 | ) -> @location(0) vec4 { 18 | 19 | let imageColor = texturePosition(image, imageSampler, vec2(0.,0), uvr, true); 20 | 21 | let finalColor = imageColor; 22 | 23 | return finalColor; 24 | } 25 | `; 26 | 27 | export default frag; 28 | -------------------------------------------------------------------------------- /examples/renderpasses2/renderpass1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/shapes1/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | const workgroupSize = 1; 4 | 5 | @compute @workgroup_size(workgroupSize,workgroupSize,1) 6 | fn main( 7 | @builtin(global_invocation_id) GlobalId: vec3, 8 | @builtin(workgroup_id) WorkGroupID: vec3, 9 | @builtin(local_invocation_id) LocalInvocationID: vec3 10 | ) { 11 | let time = params.time; 12 | let numPoints = u32(params.numPoints); 13 | 14 | // list of points for the sine wave 15 | let fk = f32(GlobalId.x); 16 | let point = &points[GlobalId.x]; 17 | (*point).x = fk / params.numPoints; 18 | (*point).y = sin( ((*point).x * 32) + time) * .1; 19 | 20 | } 21 | `; 22 | 23 | export default compute; 24 | -------------------------------------------------------------------------------- /examples/shapes1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | 6 | const options = { 7 | squareSize: .180, 8 | squareFeather: .302, 9 | lineWidth: .236, 10 | } 11 | 12 | const shapes1 = { 13 | renderPasses: [ 14 | new RenderPass(vert, frag, compute, 128, 1, 1) 15 | ], 16 | init: async (points, folder) => { 17 | const numPoints = 128; 18 | points.setUniform('numPoints', numPoints); 19 | points.setStorage('points', `array, ${numPoints}>`); 20 | 21 | points.setUniform('squareSize', options.squareSize, 'f32'); 22 | points.setUniform('squareFeather', options.squareFeather, 'f32'); 23 | points.setUniform('lineWidth', options.lineWidth, 'f32'); 24 | 25 | folder.add(options, 'squareSize', 0, 1, .0001).name('Square Size'); 26 | folder.add(options, 'squareFeather', 0, 1, .0001).name('Square Feather'); 27 | folder.add(options, 'lineWidth', 0, 1, .0001).name('Line Width'); 28 | folder.open(); 29 | }, 30 | update: points => { 31 | points.setUniform('squareSize', options.squareSize); 32 | points.setUniform('squareFeather', options.squareFeather); 33 | points.setUniform('lineWidth', options.lineWidth); 34 | } 35 | } 36 | 37 | export default shapes1; -------------------------------------------------------------------------------- /examples/shapes1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/shapes2/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | const frag = /*wgsl*/` 3 | 4 | ${fnusin} 5 | 6 | const CHROMATIC_DISPLACEMENT = 0.003695; 7 | 8 | @fragment 9 | fn main( 10 | @location(0) color: vec4, 11 | @location(1) uv: vec2, 12 | @location(2) ratio: vec2, 13 | @location(3) uvr: vec2, 14 | @location(4) mouse: vec2, 15 | @builtin(position) position: vec4 16 | ) -> @location(0) vec4 { 17 | 18 | let texColorCompute = textureSample(computeTexture, feedbackSampler, uvr).g; 19 | 20 | let texColorComputeR = textureSample(computeTexture, feedbackSampler, uvr + vec2(CHROMATIC_DISPLACEMENT, 0.)).r; 21 | let texColorComputeB = textureSample(computeTexture, feedbackSampler, uvr - vec2(CHROMATIC_DISPLACEMENT, 0.)).b; 22 | 23 | 24 | return (texColorCompute + vec4(texColorComputeR,0,0,1) + vec4(0,0,texColorComputeB,1)); 25 | } 26 | `; 27 | 28 | export default frag; 29 | -------------------------------------------------------------------------------- /examples/shapes2/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import compute from './compute.js'; 3 | import frag from './frag.js'; 4 | import RenderPass from 'renderpass'; 5 | const shapes2 = { 6 | renderPasses: [ 7 | new RenderPass(vert, frag, compute, 800, 800, 1) 8 | ], 9 | init: async points => { 10 | const numPoints = 800*800; 11 | points.setUniform('numPoints', numPoints); 12 | points.setStorage('points', `array, ${numPoints}>`); 13 | points.setSampler('feedbackSampler', null); 14 | points.setBindingTexture('outputTex', 'computeTexture'); 15 | }, 16 | update: points => { 17 | 18 | } 19 | } 20 | 21 | export default shapes2; -------------------------------------------------------------------------------- /examples/shapes2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/spritesheet1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | const spritesheet1 = { 4 | vert, 5 | frag, 6 | init: async points => { 7 | let descriptor = { 8 | addressModeU: 'clamp-to-edge', 9 | addressModeV: 'clamp-to-edge', 10 | magFilter: 'nearest', 11 | minFilter: 'nearest', 12 | mipmapFilter: 'nearest', 13 | //maxAnisotropy: 10, 14 | } 15 | points.setSampler('imageSampler', descriptor); 16 | await points.setTextureImage('image', './../img/inconsolata_regular_8x22.png'); 17 | /** 18 | * sprite sheet animation created by Nelson Yiap 19 | * https://opengameart.org/users/nelson-yiap 20 | */ 21 | await points.setTextureImage('bobbles', './../img/fishing_bobbles_nelson-yiap_24x24.png'); 22 | /** 23 | * penguin sprite by tamashihoshi 24 | * https://opengameart.org/users/tamashihoshi 25 | */ 26 | await points.setTextureImage('penguin', './../img/lr_penguin2_tamashihoshi_32x32.png'); 27 | }, 28 | update: points => { 29 | 30 | } 31 | } 32 | 33 | export default spritesheet1; -------------------------------------------------------------------------------- /examples/spritesheet1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/swirl1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag0 from './frag.js'; 3 | import Points from 'points'; 4 | import RenderPass from 'renderpass'; 5 | 6 | const options = { 7 | rotation: -.866, 8 | scale: .090, 9 | displace: false, 10 | } 11 | 12 | const base = { 13 | renderPasses: [ 14 | new RenderPass(vert, frag0), 15 | ], 16 | /** 17 | * 18 | * @param {Points} points 19 | */ 20 | init: async (points, folder) => { 21 | 22 | // Add elements to dat gui 23 | // create an uniform and get value from options 24 | points.setUniform('rotation', options.rotation); 25 | points.setUniform('scale', options.scale); 26 | points.setUniform('displace', options.displace); 27 | 28 | // https://github.com/dataarts/dat.gui/blob/master/API.md#GUI+add 29 | folder.add(options, 'rotation', -10, 10, .0001).name('rotation'); 30 | folder.add(options, 'scale', 0, 1, .0001).name('scale'); 31 | folder.add(options, 'displace').name('displace'); 32 | 33 | points.setStorage('variables', 'Variables'); 34 | points.setStorage('colors', 'array'); 35 | 36 | folder.open(); 37 | }, 38 | update: points => { 39 | points.setUniform('rotation', options.rotation); 40 | points.setUniform('scale', options.scale); 41 | points.setUniform('displace', options.displace); 42 | } 43 | } 44 | 45 | export default base; -------------------------------------------------------------------------------- /examples/swirl1/structs.js: -------------------------------------------------------------------------------- 1 | export const structs = /*wgsl*/` 2 | 3 | struct Variables { 4 | init: i32, 5 | } 6 | 7 | `; 8 | -------------------------------------------------------------------------------- /examples/swirl1/vert.js: -------------------------------------------------------------------------------- 1 | import { structs } from './structs.js'; 2 | 3 | const vert = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @location(2) uv: vec2, 12 | @builtin(vertex_index) vertexIndex: u32 13 | ) -> Fragment { 14 | 15 | return defaultVertexBody(position, color, uv); 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/swirl2/frag0.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { texturePosition } from 'image'; 3 | import { PI } from 'math'; 4 | import { snoise } from 'noise2d'; 5 | 6 | const frag = /*wgsl*/` 7 | 8 | ${fnusin} 9 | ${snoise} 10 | ${texturePosition} 11 | ${PI} 12 | 13 | @fragment 14 | fn main( 15 | @location(0) color: vec4, 16 | @location(1) uv: vec2, 17 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 18 | @location(3) uvr: vec2, // uv with aspect ratio corrected 19 | @location(4) mouse: vec2, 20 | @builtin(position) position: vec4 21 | ) -> @location(0) vec4 { 22 | 23 | 24 | let center = vec2f(.5) * ratio; 25 | let uvr2 = (uvr - center); // to center 26 | 27 | let a = atan2(uvr2.y, uvr2.x); 28 | let r = length(uvr2); 29 | let st = vec2(a / PI, .1 / r * params.sliderA) + params.time * .1; 30 | let imageColor = texturePosition(image, imageSampler, vec2f(), st, false); 31 | 32 | return imageColor; 33 | } 34 | `; 35 | 36 | export default frag; 37 | -------------------------------------------------------------------------------- /examples/swirl2/frag1.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { PI, rotateVector } from 'math'; 3 | import { snoise } from 'noise2d'; 4 | import { sdfCircle } from 'sdf'; 5 | import { texturePosition } from 'image'; 6 | 7 | const frag = /*wgsl*/` 8 | 9 | ${fnusin} 10 | ${sdfCircle} 11 | ${rotateVector} 12 | ${PI} 13 | ${snoise} 14 | ${texturePosition} 15 | 16 | @fragment 17 | fn main( 18 | @location(0) color: vec4f, 19 | @location(1) uv: vec2f, 20 | @location(2) ratio: vec2f, // relation between params.screen.x and params.screen.y 21 | @location(3) uvr: vec2f, // uv with aspect ratio corrected 22 | @location(4) mouse: vec2f, 23 | @builtin(position) position: vec4f 24 | ) -> @location(0) vec4f { 25 | 26 | let center = vec2f(.5) * ratio; 27 | 28 | let d = 1 - distance(uvr, center); 29 | let uvrRotated = rotateVector( (uvr - center) / params.scale, params.time * .1); 30 | let uvrTwisted = rotateVector(uvrRotated, params.rotation * 2 * PI * d); 31 | 32 | var displaceValue = 0.; 33 | if(params.displace == 1){ 34 | displaceValue = params.time; 35 | } 36 | 37 | let n = snoise(displaceValue + uvrTwisted ) * .5 + .5; 38 | let n2 = snoise(-displaceValue - uvrTwisted ) * .5 + .5; 39 | 40 | let imageColor = texturePosition(feedbackTexture, imageSampler, vec2f(), uvr * vec2(n,n2) , false); 41 | 42 | return imageColor; 43 | } 44 | `; 45 | 46 | export default frag; 47 | -------------------------------------------------------------------------------- /examples/swirl2/structs.js: -------------------------------------------------------------------------------- 1 | export const structs = /*wgsl*/` 2 | 3 | struct Variables { 4 | init: i32, 5 | } 6 | 7 | `; 8 | -------------------------------------------------------------------------------- /examples/swirl2/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/uvs1/frag.js: -------------------------------------------------------------------------------- 1 | const frag = /*wgsl*/` 2 | 3 | @fragment 4 | fn main( 5 | @location(0) color: vec4, 6 | @location(1) uv: vec2, 7 | @location(2) ratio: vec2, 8 | @location(3) uvr: vec2, 9 | @location(4) mouse: vec2, 10 | @builtin(position) position: vec4 11 | ) -> @location(0) vec4 { 12 | 13 | // stretched uv if canvas dimensions are non squared 14 | let uvColor:vec4 = vec4( fract(uv * 10), 0,1); 15 | 16 | // always square dimensions 17 | let uvrColor:vec4 = vec4( fract(uvr * 20), 0,1).rbga; 18 | 19 | var factor = 0.; 20 | if(uv.x > mouse.x){ 21 | factor = 1.; 22 | } 23 | 24 | return mix(uvColor, uvrColor, factor); 25 | } 26 | `; 27 | 28 | export default frag; 29 | -------------------------------------------------------------------------------- /examples/uvs1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | 4 | const uvs1 = { 5 | vert, 6 | frag, 7 | init: async points => { 8 | 9 | }, 10 | update: points => { 11 | 12 | } 13 | } 14 | 15 | export default uvs1; -------------------------------------------------------------------------------- /examples/uvs1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/videotexture1/compute.js: -------------------------------------------------------------------------------- 1 | const compute = /*wgsl*/` 2 | 3 | const workgroupSize = 8; 4 | 5 | @compute @workgroup_size(workgroupSize,workgroupSize,1) 6 | fn main( 7 | @builtin(global_invocation_id) GlobalId: vec3, 8 | @builtin(workgroup_id) WorkGroupID: vec3, 9 | @builtin(local_invocation_id) LocalInvocationID: vec3 10 | ) { 11 | let videoDims = textureDimensions(video); 12 | 13 | //-------------------------------------------------- 14 | let numColumns:f32 = f32(videoDims.x); 15 | let numRows:f32 = f32(videoDims.y); 16 | 17 | let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); 18 | let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); 19 | 20 | for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { 21 | let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); 22 | let ux = u32(x); 23 | let ix = i32(x); 24 | let nx = x / numColumns; 25 | for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { 26 | 27 | let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); 28 | let uy = u32(y); 29 | let iy = i32(y); 30 | let ny = y / numRows; 31 | let uv = vec2(nx,ny); 32 | 33 | let pointIndex = i32(y + (x * numColumns)); 34 | 35 | var rgba = textureLoad(video, vec2(ix,iy)); 36 | 37 | let positionU = vec2(ux,uy); 38 | textureStore(outputTex, positionU, rgba); 39 | } 40 | } 41 | //-------------------------------------------------- 42 | 43 | 44 | 45 | } 46 | `; 47 | 48 | export default compute; 49 | -------------------------------------------------------------------------------- /examples/videotexture1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | import { textureExternalPosition } from 'image'; 3 | 4 | const videotexture1Frag = /*wgsl*/` 5 | 6 | ${fnusin} 7 | ${textureExternalPosition} 8 | 9 | 10 | @fragment 11 | fn main( 12 | @location(0) color: vec4, 13 | @location(1) uv: vec2, 14 | @location(2) ratio: vec2, 15 | @location(3) uvr: vec2, 16 | @location(4) mouse: vec2, 17 | @builtin(position) position: vec4 18 | ) -> @location(0) vec4 { 19 | 20 | let startPosition = vec2(0.); 21 | 22 | let rgbaCT = textureExternalPosition(video, feedbackSampler, startPosition, uvr / params.scale, true); 23 | // let rgbaCT = textureSampleBaseClampToEdge(video, feedbackSampler, uv); 24 | 25 | return rgbaCT; 26 | } 27 | `; 28 | 29 | export default videotexture1Frag; 30 | -------------------------------------------------------------------------------- /examples/videotexture1/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * video: Big Beak Bird on a Tree Branch // Costa Rica 3 | * author: https://www.pexels.com/@shubh-haque-3142953/ 4 | * https://www.pexels.com/video/big-beak-bird-on-a-tree-branch-4746616/ 5 | */ 6 | 7 | const options = { 8 | scale: 1, 9 | } 10 | 11 | import vert from './vert.js'; 12 | import frag from './frag.js'; 13 | const videotexture1 = { 14 | vert, 15 | frag, 16 | init: async (points, folder) => { 17 | points.setSampler('feedbackSampler', null); 18 | await points.setTextureVideo('video', './../img/pexels-shubh-haque-4746616-960x540-30fps.mp4'); 19 | 20 | points.setUniform('scale', options.scale, 'f32'); 21 | 22 | folder.add(options, 'scale', 0, 1, .0001).name('Scale'); 23 | folder.open(); 24 | }, 25 | update: points => { 26 | points.setUniform('scale', options.scale); 27 | } 28 | } 29 | 30 | export default videotexture1; -------------------------------------------------------------------------------- /examples/videotexture1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass0/frag.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const frag = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @fragment 8 | fn main(in : VertexOutput) -> @location(0) vec4 { 9 | var color = in.color; 10 | // Apply a circular particle alpha mask 11 | color.a = color.a * max(1.0 - length(in.quad_pos), 0.0); 12 | return color; 13 | } 14 | `; 15 | 16 | export default frag; 17 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass0/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | import compute from './compute.js'; 4 | 5 | import RenderPass from 'renderpass'; 6 | 7 | export default new RenderPass(vert, frag, compute); 8 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass0/structs.js: -------------------------------------------------------------------------------- 1 | export const structs = /*wgsl*/` 2 | 3 | struct RenderParams { 4 | modelViewProjectionMatrix : mat4x4, 5 | right : vec3, 6 | up : vec3 7 | } 8 | 9 | struct VertexInput { 10 | @location(0) position : vec3, 11 | @location(1) color : vec4, 12 | @location(2) quad_pos : vec2, // -1..+1 13 | } 14 | 15 | struct VertexOutput { 16 | @builtin(position) position : vec4, 17 | @location(0) color : vec4, 18 | @location(1) quad_pos : vec2, // -1..+1 19 | } 20 | 21 | struct SimulationParams { 22 | deltaTime : f32, 23 | seed : vec4, 24 | } 25 | 26 | struct Particle { 27 | position : vec3, 28 | lifetime : f32, 29 | color : vec4, 30 | velocity : vec3, 31 | } 32 | 33 | struct Particles { 34 | particles : array, 35 | } 36 | 37 | `; -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass0/vert.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const vert = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @vertex 8 | fn main(in : VertexInput) -> VertexOutput { 9 | var quad_pos = mat2x3(params.right, params.up) * in.quad_pos; 10 | var position = in.position + quad_pos * 0.01; 11 | var out : VertexOutput; 12 | out.position = params.modelViewProjectionMatrix * vec4(position, 1.0); 13 | out.color = in.color; 14 | out.quad_pos = in.quad_pos; 15 | return out; 16 | } 17 | `; 18 | 19 | export default vert; 20 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass1/compute.js: -------------------------------------------------------------------------------- 1 | import { structs } from '../structs.js'; 2 | 3 | const compute = /*wgsl*/` 4 | 5 | ${structs} 6 | 7 | @compute @workgroup_size(8,8,1) 8 | fn main( 9 | @builtin(global_invocation_id) coord : vec3 10 | ) { 11 | _ = &buf_in; 12 | let offset = coord.x + coord.y * params.ubo_width; 13 | buf_out.weights[offset] = textureLoad(tex_in, vec2(coord.xy), 0).w; 14 | } 15 | `; 16 | 17 | export default compute; 18 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass1/frag.js: -------------------------------------------------------------------------------- 1 | import { fnusin } from 'animation'; 2 | 3 | const frag = /*wgsl*/` 4 | 5 | ${fnusin} 6 | 7 | @fragment 8 | fn main( 9 | @location(0) color: vec4, 10 | @location(1) uv: vec2, 11 | @location(2) ratio: vec2, // relation between params.screenWidth and params.screenHeight 12 | @location(3) uvr: vec2, // uv with aspect ratio corrected 13 | @location(4) mouse: vec2, 14 | @builtin(position) position: vec4 15 | ) -> @location(0) vec4 { 16 | 17 | let cellSize = 20. + 10. * fnusin(1.); 18 | let a = sin(uvr.x * cellSize) * sin(uvr.y * cellSize); 19 | let b = sin(uvr.x * uvr.y * 10. * 9.1 * .25 ); 20 | let c = fnusin(uvr.x * uvr.y * 10.); 21 | let d = distance(a,b); 22 | let f = d * uvr.x * uvr.y; 23 | let finalColor:vec4 = vec4(a*d,f*c*a,f, 1.); 24 | 25 | return finalColor; 26 | } 27 | `; 28 | 29 | export default frag; 30 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass1/index.js: -------------------------------------------------------------------------------- 1 | import vert from './vert.js'; 2 | import frag from './frag.js'; 3 | import compute from './compute.js'; 4 | 5 | import RenderPass from 'renderpass'; 6 | 7 | export default new RenderPass(null, null, compute); 8 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/pass1/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/readme: -------------------------------------------------------------------------------- 1 | This are the particles from this demo 2 | 3 | https://webgpu.github.io/webgpu-samples/samples/particles 4 | 5 | this will not work since unifors are still f32, and they need to be reworked 6 | to support other data types -------------------------------------------------------------------------------- /examples/webgpu_particles_1/structs.js: -------------------------------------------------------------------------------- 1 | export const structs = /*wgsl*/` 2 | 3 | struct RenderParams { 4 | modelViewProjectionMatrix : mat4x4, 5 | right : vec3, 6 | up : vec3 7 | } 8 | 9 | struct VertexInput { 10 | @location(0) position : vec3, 11 | @location(1) color : vec4, 12 | @location(2) quad_pos : vec2, // -1..+1 13 | } 14 | 15 | struct VertexOutput { 16 | @builtin(position) position : vec4, 17 | @location(0) color : vec4, 18 | @location(1) quad_pos : vec2, // -1..+1 19 | } 20 | 21 | struct SimulationParams { 22 | deltaTime : f32, 23 | seed : vec4, 24 | } 25 | 26 | struct Particle { 27 | position : vec3, 28 | lifetime : f32, 29 | color : vec4, 30 | velocity : vec3, 31 | } 32 | 33 | struct Particles { 34 | particles : array, 35 | } 36 | 37 | struct UBO { 38 | width : u32, 39 | } 40 | 41 | struct Buffer { 42 | weights : array, 43 | } 44 | 45 | `; 46 | -------------------------------------------------------------------------------- /examples/webgpu_particles_1/webgpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/examples/webgpu_particles_1/webgpu.png -------------------------------------------------------------------------------- /img/45da0cdd-f0a1-4a71-aed1-217a529b225c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/45da0cdd-f0a1-4a71-aed1-217a529b225c.png -------------------------------------------------------------------------------- /img/61c6eeaf-87cf5e18.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/61c6eeaf-87cf5e18.mp4 -------------------------------------------------------------------------------- /img/6982698-hd_1440_1080_25fps_800x800.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/6982698-hd_1440_1080_25fps_800x800.mp4 -------------------------------------------------------------------------------- /img/absulit_800x800.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/absulit_800x800.jpg -------------------------------------------------------------------------------- /img/angel_600x600.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/angel_600x600.jpg -------------------------------------------------------------------------------- /img/astronaut_512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/astronaut_512x512.jpg -------------------------------------------------------------------------------- /img/carmen_lyra_2_800x800.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/carmen_lyra_2_800x800.jpg -------------------------------------------------------------------------------- /img/carmen_lyra_2_blur_800x800.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/carmen_lyra_2_blur_800x800.jpg -------------------------------------------------------------------------------- /img/carmen_lyra_423x643.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/carmen_lyra_423x643.jpg -------------------------------------------------------------------------------- /img/carmen_lyra_800x800.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/carmen_lyra_800x800.jpg -------------------------------------------------------------------------------- /img/fishing_bobbles_nelson-yiap_24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/fishing_bobbles_nelson-yiap_24x24.png -------------------------------------------------------------------------------- /img/gioconda_300x300.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/gioconda_300x300.jpg -------------------------------------------------------------------------------- /img/grace_hopper_512x600.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/grace_hopper_512x600.jpg -------------------------------------------------------------------------------- /img/grace_hopper_crop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/grace_hopper_crop.jpg -------------------------------------------------------------------------------- /img/gratia_800x800.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/gratia_800x800.jpg -------------------------------------------------------------------------------- /img/house_512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/house_512x512.jpg -------------------------------------------------------------------------------- /img/inconsolata_regular_8x22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/inconsolata_regular_8x22.png -------------------------------------------------------------------------------- /img/lr_penguin2_tamashihoshi_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/lr_penguin2_tamashihoshi_32x32.png -------------------------------------------------------------------------------- /img/noiseTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/noiseTexture.png -------------------------------------------------------------------------------- /img/noiseTexture2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/noiseTexture2.png -------------------------------------------------------------------------------- /img/old_king_100x100.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/old_king_100x100.jpg -------------------------------------------------------------------------------- /img/old_king_200x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/old_king_200x200.jpg -------------------------------------------------------------------------------- /img/old_king_600x600.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/old_king_600x600.jpg -------------------------------------------------------------------------------- /img/old_king_color_800x800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/old_king_color_800x800.png -------------------------------------------------------------------------------- /img/pexels-hannah-nelson-1037989.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/pexels-hannah-nelson-1037989.jpg -------------------------------------------------------------------------------- /img/pexels-ketut-subiyanto-4350315.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/pexels-ketut-subiyanto-4350315.jpg -------------------------------------------------------------------------------- /img/pexels-kindel-media-7149147.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/pexels-kindel-media-7149147.jpg -------------------------------------------------------------------------------- /img/pexels-shubh-haque-4746616-960x540-30fps.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/pexels-shubh-haque-4746616-960x540-30fps.mp4 -------------------------------------------------------------------------------- /img/sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite.png -------------------------------------------------------------------------------- /img/sprite_nums.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums.kra -------------------------------------------------------------------------------- /img/sprite_nums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums.png -------------------------------------------------------------------------------- /img/sprite_nums_1024x1024.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums_1024x1024.kra -------------------------------------------------------------------------------- /img/sprite_nums_1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums_1024x1024.png -------------------------------------------------------------------------------- /img/sprite_nums_640x640.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums_640x640.kra -------------------------------------------------------------------------------- /img/sprite_nums_640x640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums_640x640.png -------------------------------------------------------------------------------- /img/sprite_nums_handdrawn.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/sprite_nums_handdrawn.kra -------------------------------------------------------------------------------- /img/unnamed_horror_100x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/unnamed_horror_100x100.png -------------------------------------------------------------------------------- /img/unnamed_horror_800x800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/img/unnamed_horror_800x800.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "baseUrl": "./", 5 | "paths": { 6 | "points": ["./src/absulit.points.module.js"], 7 | 8 | "datasize": ["./src/data-size.js"], 9 | "renderpass": ["./src/RenderPass.js"], 10 | "shadertype": ["./src/ShaderType.js"], 11 | 12 | "animation": ["./src/core/animation.js"], 13 | "audio": ["./src/core/audio.js"], 14 | "color": ["./src/core/color.js"], 15 | "debug": ["./src/core/debug.js"], 16 | "effects": ["./src/core/effects.js"], 17 | "image": ["./src/core/image.js"], 18 | "math": ["./src/core/math.js"], 19 | "noise2d": ["./src/core/noise2d.js"], 20 | "classicnoise2d": ["./src/core/classicnoise2d.js"], 21 | "random": ["./src/core/random.js"], 22 | "renderpasses": ["./src/RenderPasses.js"], 23 | "sdf": ["./src/core/sdf.js"], 24 | 25 | "datgui": ["./src/vendor/datgui/dat.gui.module.js"] 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /legacy/Common/LoadShaders.js: -------------------------------------------------------------------------------- 1 | // 2 | // LoadShaders.js 3 | // 4 | 5 | function initShaders( gl, vertexShaderId, fragmentShaderId ) 6 | { 7 | var vertShdr; 8 | var fragShdr; 9 | 10 | var vertElem = document.getElementById( vertexShaderId ); 11 | if ( !vertElem ) { 12 | alert( "Unable to load vertex shader " + vertexShaderId ); 13 | return -1; 14 | } 15 | else { 16 | vertShdr = gl.createShader( gl.VERTEX_SHADER ); 17 | gl.shaderSource( vertShdr, vertElem.text ); 18 | gl.compileShader( vertShdr ); 19 | if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { 20 | var msg = "Vertex shader failed to compile. The error log is:" 21 | + "
" + gl.getShaderInfoLog( vertShdr ) + "
"; 22 | alert( msg ); 23 | return -1; 24 | } 25 | } 26 | 27 | var fragElem = document.getElementById( fragmentShaderId ); 28 | if ( !fragElem ) { 29 | alert( "Unable to load vertex shader " + fragmentShaderId ); 30 | return -1; 31 | } 32 | else { 33 | fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); 34 | gl.shaderSource( fragShdr, fragElem.text ); 35 | gl.compileShader( fragShdr ); 36 | if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { 37 | var msg = "Fragment shader failed to compile. The error log is:" 38 | + "
" + gl.getShaderInfoLog( fragShdr ) + "
"; 39 | alert( msg ); 40 | return -1; 41 | } 42 | } 43 | 44 | var program = gl.createProgram(); 45 | gl.attachShader( program, vertShdr ); 46 | gl.attachShader( program, fragShdr ); 47 | gl.linkProgram( program ); 48 | 49 | if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { 50 | var msg = "Shader program failed to link. The error log is:" 51 | + "
" + gl.getProgramInfoLog( program ) + "
"; 52 | alert( msg ); 53 | return -1; 54 | } 55 | 56 | return program; 57 | } 58 | -------------------------------------------------------------------------------- /legacy/Common/README.txt: -------------------------------------------------------------------------------- 1 | This code is originally from Prof Ed Angel 2 | Professor Emeritus of Computer Science 3 | https://www.cs.unm.edu/~angel/resume.html 4 | 5 | flatten.js is also from the professor Ed Angel. The method was extracted from 6 | the MV.js file. 7 | 8 | ----------------------------------- 9 | 10 | Common files: 11 | 12 | webgl-utils.js: standard utilities from google to set up a webgl context 13 | 14 | MV.js: our matrix/vector package. Documentation on website 15 | 16 | initShaders.js: functions to initialize shaders in the html file 17 | 18 | initShaders2.js: functions to initialize shaders that are in separate files 19 | 20 | -------------------------------------------------------------------------------- /legacy/Common/_InitShaders.js: -------------------------------------------------------------------------------- 1 | // 2 | // LoadShaders.js 3 | // 4 | 5 | function initShaders( gl, vertexShaderId, fragmentShaderId ) 6 | { 7 | var vertShdr; 8 | var fragShdr; 9 | 10 | var vertElem = document.getElementById( vertexShaderId ); 11 | if ( !vertElem ) { 12 | console.error( "Unable to load vertex shader " + vertexShaderId ); 13 | return -1; 14 | } 15 | else { 16 | vertShdr = gl.createShader( gl.VERTEX_SHADER ); 17 | gl.shaderSource( vertShdr, vertElem.text ); 18 | gl.compileShader( vertShdr ); 19 | if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { 20 | var msg = "Vertex shader failed to compile. The error log is:" 21 | + "
" + gl.getShaderInfoLog( vertShdr ) + "
"; 22 | console.error( msg ); 23 | return -1; 24 | } 25 | } 26 | 27 | var fragElem = document.getElementById( fragmentShaderId ); 28 | if ( !fragElem ) { 29 | console.error( "Unable to load vertex shader " + fragmentShaderId ); 30 | return -1; 31 | } 32 | else { 33 | fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); 34 | gl.shaderSource( fragShdr, fragElem.text ); 35 | gl.compileShader( fragShdr ); 36 | if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { 37 | var msg = "Fragment shader failed to compile. The error log is:" 38 | + "
" + gl.getShaderInfoLog( fragShdr ) + "
"; 39 | console.error( msg ); 40 | return -1; 41 | } 42 | } 43 | 44 | var program = gl.createProgram(); 45 | gl.attachShader( program, vertShdr ); 46 | gl.attachShader( program, fragShdr ); 47 | gl.linkProgram( program ); 48 | 49 | if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { 50 | var msg = "Shader program failed to link. The error log is:" 51 | + "
" + gl.getProgramInfoLog( program ) + "
"; 52 | console.error( msg ); 53 | return -1; 54 | } 55 | 56 | return program; 57 | } 58 | -------------------------------------------------------------------------------- /legacy/Common/flatten.js: -------------------------------------------------------------------------------- 1 | function flatten( v ) 2 | { 3 | if ( v.matrix === true ) { 4 | v = transpose( v ); 5 | } 6 | 7 | var n = v.length; 8 | var elemsAreArrays = false; 9 | 10 | if ( Array.isArray(v[0]) ) { 11 | elemsAreArrays = true; 12 | n *= v[0].length; 13 | } 14 | 15 | var floats = new Float32Array( n ); 16 | 17 | if ( elemsAreArrays ) { 18 | var idx = 0; 19 | for ( var i = 0; i < v.length; ++i ) { 20 | for ( var j = 0; j < v[i].length; ++j ) { 21 | floats[idx++] = v[i][j]; 22 | } 23 | } 24 | } 25 | else { 26 | for ( var i = 0; i < v.length; ++i ) { 27 | floats[i] = v[i]; 28 | } 29 | } 30 | 31 | return floats; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /legacy/Common/initShaders.js: -------------------------------------------------------------------------------- 1 | // 2 | // initShaders.js 3 | // 4 | 5 | function initShaders( gl, vertexShaderId, fragmentShaderId ) 6 | { 7 | var vertShdr; 8 | var fragShdr; 9 | 10 | var vertElem = document.getElementById( vertexShaderId ); 11 | if ( !vertElem ) { 12 | console.error( "Unable to load vertex shader " + vertexShaderId ); 13 | return -1; 14 | } 15 | else { 16 | vertShdr = gl.createShader( gl.VERTEX_SHADER ); 17 | gl.shaderSource( vertShdr, vertElem.text ); 18 | gl.compileShader( vertShdr ); 19 | if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { 20 | var msg = "Vertex shader failed to compile. The error log is:" 21 | + "
" + gl.getShaderInfoLog( vertShdr ) + "
"; 22 | console.error( msg ); 23 | return -1; 24 | } 25 | } 26 | 27 | var fragElem = document.getElementById( fragmentShaderId ); 28 | if ( !fragElem ) { 29 | console.error( "Unable to load vertex shader " + fragmentShaderId ); 30 | return -1; 31 | } 32 | else { 33 | fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); 34 | gl.shaderSource( fragShdr, fragElem.text ); 35 | gl.compileShader( fragShdr ); 36 | if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { 37 | var msg = "Fragment shader failed to compile. The error log is:" 38 | + "" + gl.getShaderInfoLog( fragShdr ) + ""; 39 | console.error( msg ); 40 | return -1; 41 | } 42 | } 43 | 44 | var program = gl.createProgram(); 45 | gl.attachShader( program, vertShdr ); 46 | gl.attachShader( program, fragShdr ); 47 | gl.linkProgram( program ); 48 | 49 | if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { 50 | var msg = "Shader program failed to link. The error log is:" 51 | + "
" + gl.getProgramInfoLog( program ) + "
"; 52 | console.error( msg ); 53 | return -1; 54 | } 55 | 56 | return program; 57 | } 58 | -------------------------------------------------------------------------------- /legacy/Common/initShaders2.js: -------------------------------------------------------------------------------- 1 | 2 | // Get a file as a string using AJAX 3 | function loadFileAJAX(name) { 4 | var xhr = new XMLHttpRequest(), 5 | okStatus = document.location.protocol === "file:" ? 0 : 200; 6 | xhr.open('GET', name, false); 7 | xhr.send(null); 8 | return xhr.status == okStatus ? xhr.responseText : null; 9 | }; 10 | 11 | 12 | function initShaders(gl, vShaderName, fShaderName) { 13 | function getShader(gl, shaderName, type) { 14 | var shader = gl.createShader(type), 15 | shaderScript = loadFileAJAX(shaderName); 16 | if (!shaderScript) { 17 | console.error("Could not find shader source: "+shaderName); 18 | } 19 | gl.shaderSource(shader, shaderScript); 20 | gl.compileShader(shader); 21 | 22 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 23 | console.error(gl.getShaderInfoLog(shader)); 24 | return null; 25 | } 26 | return shader; 27 | } 28 | var vertexShader = getShader(gl, vShaderName, gl.VERTEX_SHADER), 29 | fragmentShader = getShader(gl, fShaderName, gl.FRAGMENT_SHADER), 30 | program = gl.createProgram(); 31 | 32 | gl.attachShader(program, vertexShader); 33 | gl.attachShader(program, fragmentShader); 34 | gl.linkProgram(program); 35 | 36 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 37 | console.error("Could not initialise shaders"); 38 | return null; 39 | } 40 | 41 | 42 | return program; 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /legacy/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #202124; 3 | margin : 0px; 4 | font-family : 'Open Sans', sans-serif; 5 | overflow-x : hidden; 6 | } 7 | 8 | canvas { 9 | position: fixed; 10 | z-index : -1; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /legacy/js/arrays.txt: -------------------------------------------------------------------------------- 1 | 0 1 2 | 2 3 3 | 4 | 5 | 0,0 1,0 6 | 7 | 8 | 0,1 1,1 9 | 10 | 11 | 12 | (1), (2) 13 | 14 | ------------------ 15 | 0 1 2 16 | 3 4 5 17 | 6 7 8 18 | 19 | 20 | 0,0 1,0 2,0 21 | 22 | 0,1 1,1 2,1 23 | 24 | 0,2 1,2 2,2 25 | ------------------- 26 | 27 | 0 1 28 | 29 | 30 | 0,0 1,0 31 | 32 | x + (y * numColumns) 33 | 34 | ----- 35 | x = index % 3 36 | y = Math.floor(index / 3) 37 | 38 | -------------------------------------------------------------------------------- /legacy/js/coordinate.js: -------------------------------------------------------------------------------- 1 | class Coordinate { 2 | constructor(x = 0, y = 0, z = 0) { 3 | this._x = x; 4 | this._y = y; 5 | this._z = z; 6 | this._value = [x, y, z]; 7 | } 8 | 9 | set x(value) { 10 | this._x = value; 11 | this._value[0] = value; 12 | } 13 | 14 | set y(value) { 15 | this._y = value; 16 | this._value[1] = value; 17 | } 18 | 19 | set z(value) { 20 | this._z = value; 21 | this._value[2] = value; 22 | } 23 | 24 | get x() { 25 | return this._x; 26 | } 27 | 28 | get y() { 29 | return this._y; 30 | } 31 | 32 | get z() { 33 | return this._z; 34 | } 35 | 36 | get value() { 37 | return this._value; 38 | } 39 | 40 | set(x, y, z) { 41 | this._x = x; 42 | this._y = y; 43 | this._z = z; 44 | this._value[0] = x; 45 | this._value[1] = y; 46 | this._value[2] = z; 47 | } 48 | 49 | clone() { 50 | return new Coordinate(this._x, this._y, this._z); 51 | } 52 | } 53 | 54 | export default Coordinate; -------------------------------------------------------------------------------- /legacy/js/utils.js: -------------------------------------------------------------------------------- 1 | class Utils { 2 | /** 3 | * Shuffles an array. 4 | * based on: 5 | * https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array/2450976#2450976 6 | * @param {array} array 7 | * @returns array shuffled 8 | */ 9 | static shuffle(array) { 10 | return array 11 | .map((value) => ({ value, sort: Math.random() })) 12 | .sort((a, b) => a.sort - b.sort) 13 | .map(({ value }) => value); 14 | } 15 | 16 | 17 | } 18 | 19 | export default Utils; 20 | 21 | export const print = (...s) => console.log(s); 22 | 23 | /** 24 | * Creating a deprecated / obsolete behavior for methods in a library. 25 | * [Credits]{@link: https://stackoverflow.com/q/21726472/1333836} 26 | * 27 | * @param {function} replacementFunction 28 | * @param {string} oldFnName 29 | * @param {string} newFnName 30 | * @return {function} 31 | */ 32 | export const obsolete = function (replacementFunction, oldFnName, newFnName) { 33 | const wrapper = function () { 34 | console.warn("WARNING! Obsolete function called. Function '" + oldFnName + "' has been deprecated, please use the new '" + newFnName + "' function instead!"); 35 | 36 | replacementFunction.apply(this, arguments); 37 | } 38 | wrapper.prototype = replacementFunction.prototype; 39 | 40 | return wrapper; 41 | } 42 | -------------------------------------------------------------------------------- /legacy/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /legacy/style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: rgb(0, 0, 0); 3 | margin: 0px; 4 | overflow: hidden; 5 | font-family: 'Open Sans', sans-serif; 6 | } 7 | 8 | label{ 9 | color:white; 10 | } -------------------------------------------------------------------------------- /src/CanvasRecorder.js: -------------------------------------------------------------------------------- 1 | export default class CanvasRecorder { 2 | #canvas = null; 3 | #options = null; 4 | 5 | /** 6 | * Records video from a Canvas to a file. 7 | * @param {HTMLCanvasElement} canvas Canvas to record 8 | * @param {Object} options `MediaRecorder` options 9 | */ 10 | constructor(canvas, options) { 11 | this.#canvas = canvas; 12 | this.#options = options || { 13 | audioBitsPerSecond: 128000, 14 | videoBitsPerSecond: 6000000, 15 | mimeType: 'video/webm', 16 | }; 17 | } 18 | 19 | start() { 20 | const videoStream = this.#canvas.captureStream(60); 21 | let chunks = []; 22 | this.mediaRecorder = new MediaRecorder(videoStream, this.#options); 23 | this.mediaRecorder.ondataavailable = e => chunks.push(e.data); 24 | this.mediaRecorder.onstop = _ => { 25 | const blob = new Blob(chunks, { 'type': this.#options.mimeType }); 26 | chunks = []; 27 | const url = URL.createObjectURL(blob); 28 | this.#linkToDownload(url, 'video', 'webm') 29 | 30 | }; 31 | this.mediaRecorder.start(); 32 | } 33 | stop() { 34 | this.mediaRecorder.stop(); 35 | } 36 | 37 | getPNG() { 38 | this.#canvas.toBlob( 39 | blob => { 40 | const url = URL.createObjectURL(blob) 41 | this.#linkToDownload(url, 'image', 'png') 42 | URL.revokeObjectURL(url); 43 | }, 44 | 'image/png', 45 | 0.95, 46 | ); 47 | } 48 | 49 | #linkToDownload(url, prefix, ext){ 50 | const a = document.createElement('a'); 51 | a.href = url; 52 | a.download = `${prefix}_${(new Date()).getTime()}.${ext}`; 53 | a.click(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ShaderType.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default class ShaderType { 4 | static VERTEX = 1; 5 | static COMPUTE = 2; 6 | static FRAGMENT = 3; 7 | } 8 | -------------------------------------------------------------------------------- /src/UniformKeys.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default class UniformKeys { 4 | static TIME = 'time'; 5 | static DELTA = 'delta'; 6 | static EPOCH = 'epoch'; 7 | static SCREEN = 'screen'; 8 | static MOUSE = 'mouse'; 9 | static MOUSE_CLICK = 'mouseClick'; 10 | static MOUSE_DOWN = 'mouseDown'; 11 | static MOUSE_WHEEL = 'mouseWheel'; 12 | static MOUSE_DELTA = 'mouseDelta'; 13 | } -------------------------------------------------------------------------------- /src/VertexBufferInfo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default class VertexBufferInfo { 4 | #vertexSize 5 | #vertexOffset; 6 | #colorOffset; 7 | #uvOffset; 8 | #vertexCount; 9 | /** 10 | * Along with the vertexArray it calculates some info like offsets required for the pipeline. 11 | * @param {Float32Array} vertexArray array with vertex, color and uv data 12 | * @param {Number} triangleDataLength how many items does a triangle row has in vertexArray 13 | * @param {Number} vertexOffset index where the vertex data starts in a row of `triangleDataLength` items 14 | * @param {Number} colorOffset index where the color data starts in a row of `triangleDataLength` items 15 | * @param {Number} uvOffset index where the uv data starts in a row of `triangleDataLength` items 16 | */ 17 | constructor(vertexArray, triangleDataLength = 10, vertexOffset = 0, colorOffset = 4, uvOffset = 8) { 18 | this.#vertexSize = vertexArray.BYTES_PER_ELEMENT * triangleDataLength; // Byte size of ONE triangle data (vertex, color, uv). (one row) 19 | this.#vertexOffset = vertexArray.BYTES_PER_ELEMENT * vertexOffset; 20 | this.#colorOffset = vertexArray.BYTES_PER_ELEMENT * colorOffset; // Byte offset of triangle vertex color attribute. 21 | this.#uvOffset = vertexArray.BYTES_PER_ELEMENT * uvOffset; 22 | this.#vertexCount = vertexArray.byteLength / this.#vertexSize; 23 | } 24 | 25 | get vertexSize() { 26 | return this.#vertexSize; 27 | } 28 | 29 | get vertexOffset() { 30 | return this.#vertexOffset; 31 | } 32 | 33 | get colorOffset() { 34 | return this.#colorOffset; 35 | } 36 | 37 | get uvOffset() { 38 | return this.#uvOffset; 39 | } 40 | 41 | get vertexCount() { 42 | return this.#vertexCount; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/clock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * To manage time and delta time, 3 | * based on https://github.com/mrdoob/three.js/blob/master/src/core/Clock.js 4 | */ 5 | export default class Clock { 6 | #time = 0; 7 | #oldTime = 0; 8 | #delta = 0; 9 | constructor() { 10 | 11 | } 12 | 13 | /** 14 | * Gets the current time, it does not calculate the time, it's calcualted 15 | * when `getDelta()` is called. 16 | */ 17 | get time() { 18 | return this.#time; 19 | } 20 | 21 | /** 22 | * Gets the last delta value, it does not calculate the delta, use `getDelta()` 23 | */ 24 | get delta() { 25 | return this.#delta; 26 | } 27 | 28 | #now() { 29 | return (typeof performance === 'undefined' ? Date : performance).now(); 30 | } 31 | 32 | /** 33 | * Calculate time since last frame 34 | * It also calculates `time` 35 | */ 36 | getDelta() { 37 | this.#delta = 0; 38 | const newTime = this.#now(); 39 | this.#delta = (newTime - this.#oldTime) / 1000; 40 | this.#oldTime = newTime; 41 | this.#time += this.#delta; 42 | return this.#delta; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/coordinate.js: -------------------------------------------------------------------------------- 1 | class Coordinate { 2 | #x; 3 | #y; 4 | #z; 5 | #value; 6 | constructor(x = 0, y = 0, z = 0) { 7 | this.#x = x; 8 | this.#y = y; 9 | this.#z = z; 10 | this.#value = [x, y, z]; 11 | } 12 | 13 | set x(value) { 14 | this.#x = value; 15 | this.#value[0] = value; 16 | } 17 | 18 | set y(value) { 19 | this.#y = value; 20 | this.#value[1] = value; 21 | } 22 | 23 | set z(value) { 24 | this.#z = value; 25 | this.#value[2] = value; 26 | } 27 | 28 | get x() { 29 | return this.#x; 30 | } 31 | 32 | get y() { 33 | return this.#y; 34 | } 35 | 36 | get z() { 37 | return this.#z; 38 | } 39 | 40 | get value() { 41 | return this.#value; 42 | } 43 | 44 | set(x, y, z) { 45 | this.#x = x; 46 | this.#y = y; 47 | this.#z = z; 48 | this.#value[0] = x; 49 | this.#value[1] = y; 50 | this.#value[2] = z; 51 | } 52 | } 53 | 54 | export default Coordinate; -------------------------------------------------------------------------------- /src/core/RenderPasses/bloom/frag.js: -------------------------------------------------------------------------------- 1 | import { bloom, brightness } from '../../color.js'; 2 | import { PI } from '../../math.js'; 3 | import { texturePosition } from '../../image.js'; 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${bloom} 8 | ${brightness} 9 | ${PI} 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 16 | @location(3) uvr: vec2, // uv with aspect ratio corrected 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | let startPosition = vec2(0.,0.); 22 | let rgbaImage = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, startPosition, uvr, false); //* .998046; 23 | 24 | let input = brightness(rgbaImage); 25 | let bloomVal = bloom(input, i32(params.bloom_iterations), params.bloom_amount); 26 | let rgbaBloom = vec4(bloomVal); 27 | 28 | let finalColor:vec4 = rgbaImage + rgbaBloom; 29 | 30 | return finalColor; 31 | } 32 | `; 33 | 34 | export default frag; 35 | -------------------------------------------------------------------------------- /src/core/RenderPasses/bloom/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | import Points from '../../../absulit.points.module.js'; 4 | 5 | const bloom = { 6 | vertexShader, 7 | fragmentShader, 8 | /** 9 | * 10 | * @param {Points} points 11 | * @param {*} params 12 | */ 13 | init: async (points, params) => { 14 | points._setInternal(true); 15 | points.addSampler('renderpass_feedbackSampler', null); 16 | points.addTexture2d('renderpass_feedbackTexture', true); 17 | points.addUniform('bloom_amount', params?.amount || .5); 18 | points.addUniform('bloom_iterations', params?.iterations || 2); 19 | points._setInternal(false); 20 | 21 | }, 22 | update: points => { 23 | 24 | } 25 | } 26 | 27 | export default bloom; -------------------------------------------------------------------------------- /src/core/RenderPasses/bloom/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/blur/frag.js: -------------------------------------------------------------------------------- 1 | import { blur9 } from '../../effects.js'; 2 | import { texturePosition } from '../../image.js'; 3 | import { rotateVector, PI } from '../../math.js'; 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${PI} 8 | ${rotateVector} 9 | ${blur9} 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 16 | @location(3) uvr: vec2, // uv with aspect ratio corrected 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | 22 | 23 | let feedbackColor = blur9( 24 | renderpass_feedbackTexture, 25 | renderpass_feedbackSampler, 26 | vec2(0.,0), 27 | uvr, 28 | vec2(params.blur_resolution_x, params.blur_resolution_y), // resolution 29 | rotateVector(vec2(params.blur_direction_x, params.blur_direction_y), params.blur_radians) // direction 30 | ); 31 | 32 | let finalColor = feedbackColor; 33 | 34 | return finalColor; 35 | } 36 | `; 37 | 38 | export default frag; 39 | -------------------------------------------------------------------------------- /src/core/RenderPasses/blur/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const blur = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points.addUniform('blur_resolution_x', params?.resolution[0] || 50); 12 | points.addUniform('blur_resolution_y', params?.resolution[1] || 50); 13 | points.addUniform('blur_direction_x', params?.direction[0] || .4); 14 | points.addUniform('blur_direction_y', params?.direction[1] || .4); 15 | points.addUniform('blur_radians', params?.radians || 0); 16 | points._setInternal(false); 17 | }, 18 | update: points => { 19 | 20 | } 21 | } 22 | 23 | export default blur; -------------------------------------------------------------------------------- /src/core/RenderPasses/blur/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/chromaticAberration/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from '../../image.js'; 2 | const frag = /*wgsl*/` 3 | 4 | ${texturePosition} 5 | 6 | @fragment 7 | fn main( 8 | @location(0) color: vec4, 9 | @location(1) uv: vec2, 10 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 11 | @location(3) uvr: vec2, // uv with aspect ratio corrected 12 | @location(4) mouse: vec2, 13 | @builtin(position) position: vec4 14 | ) -> @location(0) vec4 { 15 | 16 | let imageColor = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0., 0), uvr, true); 17 | 18 | 19 | // --------- chromatic displacement vector 20 | let cdv = vec2(params.chromaticAberration_distance, 0.); 21 | let d = distance(vec2(.5,.5), uvr); 22 | let imageColorR = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0.) * ratio, uvr + cdv * d, true).r; 23 | let imageColorG = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0.) * ratio, uvr, true).g; 24 | let imageColorB = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0.) * ratio, uvr - cdv * d, true).b; 25 | 26 | let finalColor:vec4 = vec4(imageColorR, imageColorG, imageColorB, 1); 27 | 28 | return finalColor; 29 | } 30 | `; 31 | 32 | export default frag; 33 | -------------------------------------------------------------------------------- /src/core/RenderPasses/chromaticAberration/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const chromaticAberration = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points.addUniform('chromaticAberration_distance', params.distance); 12 | points._setInternal(false); 13 | }, 14 | update: points => { 15 | 16 | } 17 | } 18 | 19 | export default chromaticAberration; -------------------------------------------------------------------------------- /src/core/RenderPasses/chromaticAberration/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/color/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from '../../image.js'; 2 | const frag = /*wgsl*/` 3 | 4 | ${texturePosition} 5 | 6 | @fragment 7 | fn main( 8 | @location(0) color: vec4, 9 | @location(1) uv: vec2, 10 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 11 | @location(3) uvr: vec2, // uv with aspect ratio corrected 12 | @location(4) mouse: vec2, 13 | @builtin(position) position: vec4 14 | ) -> @location(0) vec4 { 15 | 16 | let imageColor = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0., 0), uvr, true); 17 | let colorParam = vec4(params.color_r, params.color_g, params.color_b, params.color_a); 18 | let finalColor:vec4 = (imageColor + colorParam) * params.color_blendAmount; 19 | 20 | return finalColor; 21 | } 22 | `; 23 | 24 | export default frag; 25 | -------------------------------------------------------------------------------- /src/core/RenderPasses/color/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const color = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points.addUniform('color_blendAmount', params?.blendAmount || .5); 12 | points.addUniform('color_r', params?.color[0] || 1); 13 | points.addUniform('color_g', params?.color[1] || 1); 14 | points.addUniform('color_b', params?.color[2] || 0); 15 | points.addUniform('color_a', params?.color[3] || 1); 16 | points._setInternal(false); 17 | }, 18 | update: points => { 19 | 20 | } 21 | } 22 | 23 | export default color; -------------------------------------------------------------------------------- /src/core/RenderPasses/color/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/filmgrain/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from '../../image.js'; 2 | import { rand } from '../../random.js'; 3 | import { snoise } from './../../noise2d.js'; 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${rand} 8 | ${snoise} 9 | 10 | @fragment 11 | fn main( 12 | @location(0) color: vec4, 13 | @location(1) uv: vec2, 14 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 15 | @location(3) uvr: vec2, // uv with aspect ratio corrected 16 | @location(4) mouse: vec2, 17 | @builtin(position) position: vec4 18 | ) -> @location(0) vec4 { 19 | 20 | 21 | let imageColor = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0., 0), uvr, true); 22 | 23 | rand_seed = uvr + params.time; 24 | 25 | var noise = rand(); 26 | noise = noise * .5 + .5; 27 | let finalColor = (imageColor + imageColor * noise) * .5; 28 | 29 | return finalColor; 30 | } 31 | `; 32 | 33 | export default frag; 34 | -------------------------------------------------------------------------------- /src/core/RenderPasses/filmgrain/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | import ShaderType from '../../../absulit.points.module.js'; 4 | 5 | const filmgrain = { 6 | vertexShader, 7 | fragmentShader, 8 | init: async (points, params) => { 9 | points._setInternal(true); 10 | points.addSampler('renderpass_feedbackSampler', null); 11 | points.addTexture2d('renderpass_feedbackTexture', true); 12 | points._setInternal(false); 13 | 14 | }, 15 | update: points => { 16 | 17 | } 18 | } 19 | 20 | export default filmgrain; -------------------------------------------------------------------------------- /src/core/RenderPasses/filmgrain/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/grayscale/frag.js: -------------------------------------------------------------------------------- 1 | import { texturePosition } from '../../image.js'; 2 | import { fnusin } from '../../animation.js'; 3 | import { brightness, WHITE } from '../../color.js'; 4 | const frag = /*wgsl*/` 5 | 6 | ${fnusin} 7 | ${texturePosition} 8 | ${brightness} 9 | ${WHITE} 10 | 11 | @fragment 12 | fn main( 13 | @location(0) color: vec4, 14 | @location(1) uv: vec2, 15 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 16 | @location(3) uvr: vec2, // uv with aspect ratio corrected 17 | @location(4) mouse: vec2, 18 | @builtin(position) position: vec4 19 | ) -> @location(0) vec4 { 20 | 21 | let imageColor = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0., 0), uvr, true); 22 | let finalColor:vec4 = brightness(imageColor) * WHITE; 23 | 24 | return finalColor; 25 | } 26 | `; 27 | 28 | export default frag; 29 | -------------------------------------------------------------------------------- /src/core/RenderPasses/grayscale/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const grayscale = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points._setInternal(false); 12 | }, 13 | update: points => { 14 | 15 | } 16 | } 17 | 18 | export default grayscale; -------------------------------------------------------------------------------- /src/core/RenderPasses/grayscale/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/lensDistortion/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const lensDistortion = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points.addUniform('lensDistortion_amount', params?.amount || .4) 12 | points.addUniform('lensDistortion_distance', params?.distance || .01); 13 | points._setInternal(false); 14 | }, 15 | update: async points => { 16 | 17 | } 18 | } 19 | 20 | export default lensDistortion; -------------------------------------------------------------------------------- /src/core/RenderPasses/lensDistortion/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/pixelate/frag.js: -------------------------------------------------------------------------------- 1 | import { pixelateTexturePosition, texturePosition } from '../../image.js'; 2 | const frag = /*wgsl*/` 3 | 4 | ${texturePosition} 5 | ${pixelateTexturePosition} 6 | 7 | @fragment 8 | fn main( 9 | @location(0) color: vec4, 10 | @location(1) uv: vec2, 11 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 12 | @location(3) uvr: vec2, // uv with aspect ratio corrected 13 | @location(4) mouse: vec2, 14 | @builtin(position) position: vec4 15 | ) -> @location(0) vec4 { 16 | 17 | 18 | let pixelatedColor = pixelateTexturePosition( 19 | renderpass_feedbackTexture, 20 | renderpass_feedbackSampler, 21 | vec2(0.), 22 | params.pixelate_pixelsWidth, 23 | params.pixelate_pixelsHeight, 24 | uvr 25 | ); 26 | 27 | let finalColor:vec4 = pixelatedColor; 28 | 29 | return finalColor; 30 | } 31 | `; 32 | 33 | export default frag; 34 | -------------------------------------------------------------------------------- /src/core/RenderPasses/pixelate/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const pixelate = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points.addUniform('pixelate_pixelsWidth', params.pixelsWidth); 12 | points.addUniform('pixelate_pixelsHeight', params.pixelsHeight); 13 | points._setInternal(false); 14 | }, 15 | update: points => { 16 | 17 | } 18 | } 19 | 20 | export default pixelate; -------------------------------------------------------------------------------- /src/core/RenderPasses/pixelate/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/RenderPasses/waves/frag.js: -------------------------------------------------------------------------------- 1 | import { cnoise } from '../../classicnoise2d.js'; 2 | import { texturePosition } from '../../image.js'; 3 | import { snoise } from '../../noise2d.js'; 4 | const frag = /*wgsl*/` 5 | 6 | ${texturePosition} 7 | ${snoise} 8 | 9 | @fragment 10 | fn main( 11 | @location(0) color: vec4, 12 | @location(1) uv: vec2, 13 | @location(2) ratio: vec2, // relation between params.screen.x and params.screen.y 14 | @location(3) uvr: vec2, // uv with aspect ratio corrected 15 | @location(4) mouse: vec2, 16 | @builtin(position) position: vec4 17 | ) -> @location(0) vec4 { 18 | 19 | let scale = params.waves_scale; 20 | let intensity = params.waves_intensity; 21 | let n1 = (snoise(uv / scale + vec2(.03, .4) * params.time) * .5 + .5) * intensity; 22 | let n2 = (snoise(uv / scale + vec2(.3, .02) * params.time) * .5 + .5) * intensity; 23 | let n = n1 + n2; 24 | 25 | let imageColor = texturePosition(renderpass_feedbackTexture, renderpass_feedbackSampler, vec2(0., 0), uvr + n2, true); 26 | let finalColor:vec4 = imageColor; 27 | 28 | return finalColor; 29 | } 30 | `; 31 | 32 | export default frag; 33 | -------------------------------------------------------------------------------- /src/core/RenderPasses/waves/index.js: -------------------------------------------------------------------------------- 1 | import vertexShader from './vert.js'; 2 | import fragmentShader from './frag.js'; 3 | 4 | const waves = { 5 | vertexShader, 6 | fragmentShader, 7 | init: async (points, params) => { 8 | points._setInternal(true); 9 | points.addSampler('renderpass_feedbackSampler', null); 10 | points.addTexture2d('renderpass_feedbackTexture', true); 11 | points.addUniform('waves_scale', params?.scale || .45); 12 | points.addUniform('waves_intensity', params?.intensity || .03); 13 | points._setInternal(false); 14 | }, 15 | update: points => { 16 | 17 | } 18 | } 19 | 20 | export default waves; -------------------------------------------------------------------------------- /src/core/RenderPasses/waves/vert.js: -------------------------------------------------------------------------------- 1 | const vert = /*wgsl*/` 2 | 3 | @vertex 4 | fn main( 5 | @location(0) position: vec4, 6 | @location(1) color: vec4, 7 | @location(2) uv: vec2, 8 | @builtin(vertex_index) vertexIndex: u32 9 | ) -> Fragment { 10 | 11 | return defaultVertexBody(position, color, uv); 12 | } 13 | `; 14 | 15 | export default vert; 16 | -------------------------------------------------------------------------------- /src/core/animation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Utilities for animation 3 | */ 4 | 5 | /** 6 | * @type {String} 7 | * Animates `sin()` over `params.time` and a provided `speed`. 8 | * The value is not normalized, so in the range -1..1 9 | * @param {f32} speed 10 | */ 11 | export const fusin = /*wgsl*/` 12 | fn fusin(speed: f32) -> f32{ 13 | return sin(params.time * speed); 14 | } 15 | `; 16 | 17 | /** 18 | * @type {String} 19 | * Animates `cos()` over `params.time` and a provided `speed`. 20 | * The value is not normalized, so in the range -1..1 21 | * @param {f32} speed 22 | */ 23 | export const fucos = /*wgsl*/` 24 | fn fucos(speed: f32) -> f32{ 25 | return cos(params.time * speed); 26 | } 27 | `; 28 | 29 | /** 30 | * @type {String} 31 | * Animates `sin()` over `params.time` and a provided `speed`. 32 | * The value is normalized, so in the range 0..1 33 | * @param {f32} speed 34 | */ 35 | export const fnusin = /*wgsl*/` 36 | fn fnusin(speed: f32) -> f32{ 37 | return (sin(params.time * speed) + 1.) * .5; 38 | } 39 | `; -------------------------------------------------------------------------------- /src/core/audio.js: -------------------------------------------------------------------------------- 1 | export const audioAverage = /*wgsl*/` 2 | fn audioAverage(sound:Sound) -> f32 { 3 | var audioAverage = 0.; 4 | for (var index = 0; index < i32(params.audioLength); index++) { 5 | let audioValue = sound.data[index] / 256; 6 | audioAverage += audioValue; 7 | } 8 | return audioAverage / params.audioLength; 9 | } 10 | `; 11 | 12 | export const audioAverageSegments = /*wgsl*/` 13 | fn audioAverageSegments(segmentNum:i32) -> f32{ 14 | // arrayLength(&array) 15 | return .0; 16 | } 17 | `; 18 | -------------------------------------------------------------------------------- /src/core/debug.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {Screen} 3 | * Draws an infinite cross. 4 | * Useful to draw it where the mouse is. 5 | * @param position 6 | * @param color 7 | * @param uv 8 | */ 9 | export const showDebugCross = /*wgsl*/` 10 | fn showDebugCross(position:vec2, color:vec4, uv:vec2) -> vec4{ 11 | let horizontal = sdfLine(vec2(0, position.y), vec2(10, position.y), 1., uv) * color; 12 | let vertical = sdfLine(vec2(position.x, 0), vec2(position.x, 10), 1., uv) * color; 13 | return vertical + horizontal; 14 | } 15 | `; 16 | 17 | /** 18 | * @type {Screen} 19 | * Border around the screen 20 | * @param color 21 | * @param uv 22 | */ 23 | export const showDebugFrame = /*wgsl*/` 24 | fn showDebugFrame(color:vec4, uv:vec2) -> vec4 { 25 | let ratioX = params.screen.x / params.screen.y; 26 | let ratioY = 1. / ratioX / (params.screen.y / params.screen.x); 27 | let ratio = vec2(ratioX, ratioY); 28 | 29 | let topRight = vec2(1., 1.) * ratio; 30 | let topLeft = vec2(0., 1.); 31 | let bottomLeft = vec2(0., 0.); 32 | let bottomRight = vec2(1., 0.) * ratio; 33 | 34 | let top = sdfLine(topLeft, topRight, 1., uv) * color; 35 | let bottom = sdfLine(bottomLeft, bottomRight, 1., uv) * color; 36 | let left = sdfLine(bottomLeft, topLeft, 1., uv) * color; 37 | let right = sdfLine(bottomRight, topRight, 1., uv) * color; 38 | return top + bottom + left + right; 39 | } 40 | `; 41 | -------------------------------------------------------------------------------- /src/core/defaultConstants.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/core/defaultFunctions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {string} 3 | * Default function for the Vertex shader that takes charge of automating the 4 | * creation of a few variables that are commonly used. 5 | * @param {vec4f} position 6 | * @param {vec4f} color 7 | * @param {vec2f} uv 8 | * @return {Fragment} 9 | */ 10 | export const defaultVertexBody = /*wgsl*/` 11 | fn defaultVertexBody(position: vec4, color: vec4, uv: vec2) -> Fragment { 12 | var result: Fragment; 13 | 14 | let ratioX = params.screen.x / params.screen.y; 15 | let ratioY = 1. / ratioX / (params.screen.y / params.screen.x); 16 | result.ratio = vec2(ratioX, ratioY); 17 | result.position = vec4(position); 18 | result.color = vec4(color); 19 | result.uv = uv; 20 | result.uvr = vec2(uv.x * result.ratio.x, uv.y); 21 | result.mouse = vec2(params.mouse.x / params.screen.x, params.mouse.y / params.screen.y); 22 | result.mouse = result.mouse * vec2(1.,-1.) - vec2(0., -1.); // flip and move up 23 | 24 | return result; 25 | } 26 | `; 27 | -------------------------------------------------------------------------------- /src/core/defaultStructs.js: -------------------------------------------------------------------------------- 1 | const defaultStructs = /*wgsl*/` 2 | 3 | struct Fragment { 4 | @builtin(position) position: vec4, 5 | @location(0) color: vec4, 6 | @location(1) uv: vec2, 7 | @location(2) ratio: vec2, 8 | @location(3) uvr: vec2, 9 | @location(4) mouse: vec2 10 | } 11 | 12 | struct Sound { 13 | data: array, 14 | //play 15 | //dataLength 16 | //duration 17 | //currentPosition 18 | } 19 | 20 | struct Event { 21 | updated: u32, 22 | data: array 23 | } 24 | `; 25 | 26 | export default defaultStructs; 27 | -------------------------------------------------------------------------------- /src/core/defaultVertexStructs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * non used structs unless required 3 | */ 4 | const defaultVertexStructs = /*wgsl*/` 5 | 6 | struct Color{ 7 | r: f32, 8 | g: f32, 9 | b: f32, 10 | a: f32 11 | } 12 | 13 | struct Position{ 14 | x: f32, 15 | y: f32, 16 | z: f32, 17 | w: f32 18 | } 19 | 20 | struct Vertex { 21 | position: Position, 22 | color: Color, 23 | uv: vec2, 24 | } 25 | 26 | struct Point { 27 | vertex0: Vertex, 28 | vertex1: Vertex, 29 | vertex2: Vertex, 30 | vertex3: Vertex, 31 | vertex4: Vertex, 32 | vertex5: Vertex, 33 | } 34 | 35 | struct Points { 36 | points: array 37 | } 38 | 39 | `; 40 | 41 | export default defaultVertexStructs; 42 | -------------------------------------------------------------------------------- /src/core/math.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Math utils 3 | */ 4 | 5 | export const PI = /*wgsl*/`const PI = 3.14159265;`; 6 | export const TAU = /*wgsl*/`const TAU = PI * 2;`; 7 | export const PHI = /*wgsl*/`const PHI = 1.61803398;`; 8 | export const E = /*wgsl*/`const E = 2.71828182;`; 9 | 10 | /** 11 | * @type {String} 12 | * Using polar coordinates, calculates the final point as `vec2` 13 | * @param {f32} distance distance from origin 14 | * @param {f32} radians Angle in radians 15 | */ 16 | export const polar = /*wgsl*/` 17 | fn polar(distance: f32, radians: f32) -> vec2 { 18 | return vec2(distance * cos(radians), distance * sin(radians)); 19 | } 20 | `; 21 | 22 | /** 23 | * @type {String} 24 | * Rotates a vector an amount of radians 25 | * @param {vec2f} p vector to rotate 26 | * @param {f32} rads angle in radians 27 | */ 28 | export const rotateVector = /*wgsl*/` 29 | fn rotateVector(p:vec2, rads:f32 ) -> vec2 { 30 | let s = sin(rads); 31 | let c = cos(rads); 32 | let xnew = p.x * c - p.y * s; 33 | let ynew = p.x * s + p.y * c; 34 | return vec2(xnew, ynew); 35 | } 36 | `; 37 | -------------------------------------------------------------------------------- /src/core/random.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {String} 3 | * Single random number. 4 | * Use `seed` to change seed. 5 | * @return `f32` 6 | */ 7 | export const random = /*wgsl*/` 8 | 9 | var a:i32 = 1664525; 10 | var c:i32 = 1013904223; 11 | var m = pow(2, 32); 12 | var seed:i32 = 958736; 13 | 14 | fn nextRand() -> i32 { 15 | seed = (a * seed + c) % i32(m); 16 | return seed; 17 | } 18 | 19 | fn random() -> f32 { 20 | return f32(nextRand()) / f32(m) / .5; 21 | } 22 | 23 | `; 24 | 25 | /** 26 | * @type {String} 27 | * Random number that returns a `vec2f`. 28 | * Use `rand_seed:vec2f` to change seed. 29 | * @return `f32` equivalent to `rand_seed.y` and `rand_seed` is the result. 30 | */ 31 | export const rand = /*wgsl*/` 32 | var rand_seed : vec2; 33 | 34 | fn rand() -> f32 { 35 | rand_seed.x = fract(cos(dot(rand_seed, vec2(23.14077926, 232.61690225))) * 136.8168); 36 | rand_seed.y = fract(cos(dot(rand_seed, vec2(54.47856553, 345.84153136))) * 534.7645); 37 | return rand_seed.y; 38 | } 39 | `; 40 | 41 | /** 42 | * @type {String} 43 | * Random number from `vec2f` param 44 | * @param {vec2f} co `vec2f` vector 45 | */ 46 | export const rand2 = /*wgsl*/` 47 | fn rand2(co: vec2) -> f32 { 48 | return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); 49 | } 50 | `; -------------------------------------------------------------------------------- /src/core/valuenoise.js: -------------------------------------------------------------------------------- 1 | import { rand } from './random.js'; 2 | 3 | 4 | export const valueNoise = /*wgsl*/` 5 | ${rand} 6 | 7 | const value_noise_cellsize = 64; 8 | 9 | fn valueNoise(){ 10 | let width = i32(params.screen.x); 11 | let height = i32(params.screen.y); 12 | let cellSize = 64; 13 | _ = value_noise_data[0]; 14 | 15 | 16 | for(var index = 0; index < i32(params.value_noise_data_length); index++){ 17 | let x = index % width; 18 | let y = index / width; 19 | 20 | if(x % cellSize == 0 && y % cellSize == 0){ 21 | 22 | let rx = x / cellSize; 23 | let ry = y / cellSize; 24 | 25 | let randomDataIndex = rx + (ry * width); 26 | 27 | 28 | let dataP = &value_noise_data[randomDataIndex]; 29 | (*dataP) = rand(); 30 | } 31 | 32 | 33 | } 34 | 35 | } 36 | `; -------------------------------------------------------------------------------- /src/core/voronoi.js: -------------------------------------------------------------------------------- 1 | import { rand } from './random.js'; 2 | 3 | // Created by Sebastián Sanabria Díaz absulit.com 4 | 5 | /** 6 | * @type {String} 7 | * Voronoi noise 8 | * @param {vec2f} p origin point 9 | * @param {u32} numPoints number of cells 10 | * @return `vec2f` 11 | */ 12 | export const voronoi = /*wgsl*/` 13 | 14 | ${rand} 15 | 16 | fn voronoi(p:vec2f, numPoints:u32) -> vec2f { 17 | var lastDistance = -1.; 18 | var c = 1.; 19 | for(var i:u32 = 0; i < numPoints; i++){ 20 | rand(); 21 | var d = distance(p, rand_seed); 22 | 23 | if(lastDistance != -1.){ 24 | lastDistance = min(lastDistance, d); 25 | }else{ 26 | lastDistance = d; 27 | } 28 | } 29 | if(lastDistance > .01){ 30 | c = 0.; 31 | } 32 | 33 | return vec2f(1-lastDistance, c); 34 | } 35 | `; 36 | -------------------------------------------------------------------------------- /webgpu_demo_reference/assets/old_king_600x600.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Absulit/points/e3ad5da7a1f04eef85f8eb81d0b4ea97a97fca7d/webgpu_demo_reference/assets/old_king_600x600.jpg -------------------------------------------------------------------------------- /webgpu_demo_reference/demo1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo2_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo3_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/demo6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/js/coordinate.js: -------------------------------------------------------------------------------- 1 | class Coordinate { 2 | constructor(x = 0, y = 0, z = 0) { 3 | this._x = x; 4 | this._y = y; 5 | this._z = z; 6 | this._value = [x, y, z]; 7 | } 8 | 9 | set x(value) { 10 | this._x = value; 11 | this._value[0] = value; 12 | } 13 | 14 | set y(value) { 15 | this._y = value; 16 | this._value[1] = value; 17 | } 18 | 19 | set z(value) { 20 | this._z = value; 21 | this._value[2] = value; 22 | } 23 | 24 | get x() { 25 | return this._x; 26 | } 27 | 28 | get y() { 29 | return this._y; 30 | } 31 | 32 | get z() { 33 | return this._z; 34 | } 35 | 36 | get value() { 37 | return this._value; 38 | } 39 | 40 | set(x, y, z) { 41 | this._x = x; 42 | this._y = y; 43 | this._z = z; 44 | this._value[0] = x; 45 | this._value[1] = y; 46 | this._value[2] = z; 47 | } 48 | } 49 | 50 | export default Coordinate; -------------------------------------------------------------------------------- /webgpu_demo_reference/shader_loader.js: -------------------------------------------------------------------------------- 1 | export function getShaderSource(url) { 2 | var result = new Promise((resolve, reject) => { 3 | 4 | var req = new XMLHttpRequest(); 5 | 6 | req.onload = () => { 7 | resolve(req.responseText); 8 | }; 9 | 10 | req.onerror = () => { 11 | console.error("Failed to get shader source for " + relativePath + ": " + this.statusText); 12 | reject(req); 13 | } 14 | 15 | req.open("GET", url, true); 16 | req.send(null); 17 | }); 18 | 19 | return result; 20 | }; 21 | 22 | export async function getShaderProgram(context, url) { 23 | 24 | const source = await getShaderSource(url); 25 | 26 | //=> Compile the program. 27 | const shader = context.createShader(context.COMPUTE_SHADER); 28 | context.shaderSource(shader, source); 29 | context.compileShader(shader); 30 | 31 | if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) { 32 | console.error("compute shader build failed", url); 33 | console.error(context.getShaderInfoLog(shader)); 34 | return null; 35 | } 36 | 37 | //=> Create the program. 38 | const program = context.createProgram(); 39 | context.attachShader(program, shader); 40 | context.linkProgram(program); 41 | 42 | if (!context.getProgramParameter(program, context.LINK_STATUS)) { 43 | console.error("compute shader program initialization failed.", url); 44 | console.error(context.getProgramInfoLog(program)); 45 | return; 46 | } 47 | 48 | return program; 49 | } -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/demo6_colors.frag.wgsl: -------------------------------------------------------------------------------- 1 | @fragment 2 | fn main(@location(0) Color: vec4) -> @location(0) vec4 { 3 | return Color; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/demo6_colors.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Fragment { 2 | @builtin(position) Position: vec4, 3 | @location(0) Color: vec4 4 | } 5 | 6 | 7 | @vertex 8 | fn main( 9 | @location(0) position: vec4, 10 | @location(1) color: vec4, 11 | @builtin(vertex_index) VertexIndex: u32 12 | ) -> Fragment { 13 | 14 | var result: Fragment; 15 | 16 | result.Position = vec4(position); 17 | result.Color = vec4(color); 18 | 19 | return result; 20 | } 21 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/demo6_texture.frag.wgsl: -------------------------------------------------------------------------------- 1 | @group(0) @binding(0) var texture: texture_2d; 2 | @group(0) @binding(1) var samp: sampler; 3 | 4 | @fragment 5 | fn main(@location(0) Color: vec4, @location(1) uv: vec2) -> @location(0) vec4 { 6 | //return Color; 7 | //return vec4(sin(3.0), 0.0, 0.0, 1.0); 8 | return textureSample(texture, samp, uv); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/demo6_texture.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Fragment { 2 | @builtin(position) Position: vec4, 3 | @location(0) Color: vec4, 4 | @location(1) uv: vec2 5 | } 6 | 7 | 8 | @vertex 9 | fn main(@location(0) position: vec4, @location(1) color: vec4, @location(2) uv: vec2, @builtin(vertex_index) VertexIndex: u32) -> Fragment { 10 | 11 | var result: Fragment; 12 | 13 | result.Position = vec4(position); 14 | result.uv = uv; 15 | result.Color = vec4(color); 16 | 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/demo6_update.points.wgsl: -------------------------------------------------------------------------------- 1 | 2 | @compute @workgroup_size(64) 3 | fn main() { 4 | //return Color; 5 | //return vec4(sin(3.0), 0.0, 0.0, 1.0); 6 | //return textureSample(texture, samp, uv); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/red.frag.wgsl: -------------------------------------------------------------------------------- 1 | @fragment 2 | fn main() -> @location(0) vec4 { 3 | return vec4(1.0, 0.0, 0.0, 1.0); 4 | } 5 | 6 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/red3_1.frag.wgsl: -------------------------------------------------------------------------------- 1 | @fragment 2 | fn main(@location(0) Color: vec4) -> @location(0) vec4 { 3 | return Color; 4 | //return vec4(sin(3.0), 0.0, 0.0, 1.0); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/red4.frag.wgsl: -------------------------------------------------------------------------------- 1 | @fragment 2 | fn main(@location(0) Color: vec4) -> @location(0) vec4 { 3 | return Color; 4 | //return vec4(sin(3.0), 0.0, 0.0, 1.0); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/red5.frag.wgsl: -------------------------------------------------------------------------------- 1 | @group(0) @binding(0) var texture: texture_2d; 2 | @group(0) @binding(1) var samp: sampler; 3 | 4 | @fragment 5 | fn main(@location(0) Color: vec4, @location(1) uv: vec2) -> @location(0) vec4 { 6 | //return Color; 7 | //return vec4(sin(3.0), 0.0, 0.0, 1.0); 8 | return textureSample(texture, samp, uv); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/red5_colors.frag.wgsl: -------------------------------------------------------------------------------- 1 | //@group(0) @binding(0) var texture: texture_2d; 2 | //@group(0) @binding(1) var samp: sampler; 3 | 4 | @fragment 5 | fn main(@location(0) Color: vec4) -> @location(0) vec4 { 6 | return Color; 7 | //return vec4(sin(3.0), 0.0, 0.0, 1.0); 8 | //return textureSample(texture, samp, uv); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/texture_example.frag.wgsl: -------------------------------------------------------------------------------- 1 | @group(0) @binding(0) var samp: sampler; 2 | @group(0) @binding(1) var tex: texture_2d; 3 | @stage(fragment)fn main(@location(0) uv: vec2) -> @location(0) vec4 { 4 | return textureSample(tex, samp, uv); 5 | //return vec4(1.0, 0.0, 0.0, 1.0); 6 | } -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/texture_example.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Out { 2 | @builtin(position) pos: vec4, 3 | @location(0) uv: vec2 4 | }; 5 | @stage(vertex)fn main(@location(0) xy: vec2, @location(1) uv: vec2) -> Out { 6 | return Out(vec4(xy, 0.0, 1.0), uv); 7 | } -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/triangle.vert.wgsl: -------------------------------------------------------------------------------- 1 | @vertex 2 | fn main(@builtin(vertex_index) VertexIndex: u32) -> @builtin(position) vec4 { 3 | var pos = array, 3>( 4 | vec2(0.0, 0.5), 5 | vec2(-0.5, -0.5), 6 | vec2(0.5, -0.5) 7 | ); 8 | 9 | return vec4(pos[VertexIndex], 0., 1.0); 10 | } -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/triangle3_1.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Fragment { 2 | @builtin(position) Position: vec4, 3 | @location(0) Color: vec4, 4 | //@location(1) fragUV: vec2 5 | } 6 | 7 | 8 | @vertex 9 | fn main(@location(0) position: vec4, @location(1) color: vec4, @builtin(vertex_index) VertexIndex: u32) -> Fragment { 10 | 11 | var output: Fragment; 12 | 13 | output.Position = vec4(position); 14 | //output.fragUV = uv; 15 | output.Color = vec4(color); 16 | 17 | return output; 18 | } 19 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/triangle4.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Fragment { 2 | @builtin(position) Position: vec4, 3 | @location(0) Color: vec4, 4 | //@location(1) fragUV: vec2 5 | } 6 | 7 | 8 | @vertex 9 | fn main(@location(0) position: vec4, @location(1) color: vec4, @builtin(vertex_index) VertexIndex: u32) -> Fragment { 10 | 11 | var result: Fragment; 12 | 13 | result.Position = vec4(position); 14 | //output.fragUV = uv; 15 | result.Color = vec4(color); 16 | 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/triangle5.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Fragment { 2 | @builtin(position) Position: vec4, 3 | @location(0) Color: vec4, 4 | @location(1) uv: vec2 5 | } 6 | 7 | 8 | @vertex 9 | fn main(@location(0) position: vec4, @location(1) color: vec4, @location(2) uv: vec2, @builtin(vertex_index) VertexIndex: u32) -> Fragment { 10 | 11 | var result: Fragment; 12 | 13 | result.Position = vec4(position); 14 | result.uv = uv; 15 | result.Color = vec4(color); 16 | 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /webgpu_demo_reference/shaders/triangle5_colors.vert.wgsl: -------------------------------------------------------------------------------- 1 | struct Fragment { 2 | @builtin(position) Position: vec4, 3 | @location(0) Color: vec4, 4 | //@location(1) uv: vec2 5 | } 6 | 7 | 8 | @vertex 9 | fn main(@location(0) position: vec4, @location(1) color: vec4, @builtin(vertex_index) VertexIndex: u32) -> Fragment { 10 | 11 | var result: Fragment; 12 | 13 | result.Position = vec4(position); 14 | //result.uv = uv; 15 | result.Color = vec4(color); 16 | 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /webgpu_demo_reference/snail1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webgpu_demo_reference/style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: rgb(0, 0, 0); 3 | margin: 0px; 4 | overflow: hidden; 5 | font-family: 'Open Sans', sans-serif; 6 | } 7 | -------------------------------------------------------------------------------- /webgpu_demo_reference/texture_example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Oops ... your browser doesn't support the HTML5 canvas element 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | --------------------------------------------------------------------------------