├── public ├── textures │ ├── text_map.png │ ├── unsplash_1.webp │ ├── uv_checker_1.png │ ├── uv_checker_2.png │ └── lancellotti_chapel │ │ ├── nx.webp │ │ ├── ny.webp │ │ ├── nz.webp │ │ ├── px.webp │ │ ├── py.webp │ │ └── pz.webp └── vite.svg ├── src ├── 20240202 │ ├── sketch.fs │ └── index.html ├── 20240203 │ ├── index.html │ └── sketch.fs ├── 20240204 │ ├── sketch.fs │ └── index.html ├── 20240205 │ ├── index.html │ └── sketch.fs ├── 20240206 │ ├── index.html │ └── sketch.fs ├── 20240207 │ ├── index.html │ └── sketch.fs ├── 20240208 │ ├── index.html │ └── sketch.fs ├── 20240210 │ ├── index.html │ └── sketch.fs ├── 20240211 │ ├── index.html │ └── sketch.fs ├── 20240213 │ ├── index.html │ └── sketch.fs ├── 20240214 │ ├── index.html │ └── sketch.fs ├── 20240217 │ ├── index.html │ └── sketch.fs ├── 20240218 │ ├── index.html │ └── sketch.fs ├── 20240219 │ ├── index.html │ └── sketch.fs ├── 20240221 │ ├── index.html │ └── sketch.fs ├── 20240225 │ ├── index.html │ └── sketch.fs ├── 20240303 │ ├── sketch.fs │ ├── index.html │ └── output.fs ├── 20240304 │ ├── index.html │ └── sketch.fs ├── 20240306 │ ├── index.html │ └── sketch.fs ├── 20240308 │ ├── index.html │ └── sketch.fs ├── 20240311 │ ├── index.html │ └── sketch.fs ├── 20240312 │ ├── index.html │ └── sketch.fs ├── 20240401 │ ├── index.html │ └── sketch.fs ├── 20240418 │ ├── index.html │ └── sketch.fs ├── 20240419 │ ├── index.html │ └── sketch.fs ├── 20240422 │ ├── index.html │ └── sketch.fs ├── 20240425 │ ├── index.html │ └── sketch.fs ├── vite-env.d.ts ├── scripts │ ├── shader │ │ ├── quad.vs │ │ └── output.fs │ ├── core │ │ ├── ExtendedMaterials.ts │ │ ├── BackBuffer.ts │ │ ├── FrameBuffer.ts │ │ └── Three.ts │ ├── entry.ts │ ├── Params.ts │ ├── Mouse2D.ts │ ├── MainScene.ts │ └── Canvas.ts ├── template │ ├── sketch.fs │ └── index.html ├── template_postprocessing │ ├── sketch.fs │ ├── output.fs │ └── index.html ├── 20240203_2 │ ├── index.html │ └── sketch.fs ├── 20240206_2 │ ├── index.html │ └── sketch.fs ├── 20240204_2 │ ├── index.html │ └── sketch.fs ├── 20240306_2 │ ├── index.html │ └── sketch.fs ├── 20240207_2 │ ├── index.html │ └── sketch.fs ├── 20240213_2 │ ├── index.html │ └── sketch.fs ├── style.css └── index.html ├── README.md ├── .prettierrc.cjs ├── .gitignore ├── package.json ├── tsconfig.json ├── vite.config.ts └── .github └── workflows └── deploy.yml /public/textures/text_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/text_map.png -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /public/textures/unsplash_1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/unsplash_1.webp -------------------------------------------------------------------------------- /public/textures/uv_checker_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/uv_checker_1.png -------------------------------------------------------------------------------- /public/textures/uv_checker_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/uv_checker_2.png -------------------------------------------------------------------------------- /public/textures/lancellotti_chapel/nx.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/lancellotti_chapel/nx.webp -------------------------------------------------------------------------------- /public/textures/lancellotti_chapel/ny.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/lancellotti_chapel/ny.webp -------------------------------------------------------------------------------- /public/textures/lancellotti_chapel/nz.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/lancellotti_chapel/nz.webp -------------------------------------------------------------------------------- /public/textures/lancellotti_chapel/px.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/lancellotti_chapel/px.webp -------------------------------------------------------------------------------- /public/textures/lancellotti_chapel/py.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/lancellotti_chapel/py.webp -------------------------------------------------------------------------------- /public/textures/lancellotti_chapel/pz.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/webgl-sketch/HEAD/public/textures/lancellotti_chapel/pz.webp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | move to https://github.com/nemutas/fs-sketch 2 | 3 | # About 4 | fragmentShaderの復習やちょっとした試し書き用のリポジトリ。twiglみたいな感じ。 5 | 6 | https://nemutas.github.io/webgl-sketch/ 7 | -------------------------------------------------------------------------------- /src/scripts/shader/quad.vs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | 3 | in vec3 position; 4 | in vec2 uv; 5 | 6 | out vec2 vUv; 7 | 8 | void main() { 9 | vUv = uv; 10 | gl_Position = vec4(position, 1.0); 11 | } -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | module.exports = { 3 | tabWidth: 2, 4 | useTabs: false, 5 | semi: false, 6 | trailingComma: 'all', 7 | singleQuote: true, 8 | printWidth: 160, 9 | } 10 | -------------------------------------------------------------------------------- /src/scripts/shader/output.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D source; 5 | 6 | in vec2 vUv; 7 | out vec4 outColor; 8 | 9 | void main() { 10 | outColor = vec4(texture(source, vUv).rgb, 1.0); 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/scripts/core/ExtendedMaterials.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | export class RawShaderMaterial extends THREE.RawShaderMaterial { 4 | constructor(parameters: THREE.ShaderMaterialParameters) { 5 | super(parameters) 6 | this.preprocess() 7 | } 8 | 9 | private preprocess() { 10 | if (this.glslVersion === '300 es') { 11 | this.vertexShader = this.vertexShader.replace('#version 300 es', '') 12 | this.fragmentShader = this.fragmentShader.replace('#version 300 es', '') 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/template/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | const float SEED = SEED_VALUE; 15 | 16 | void main() { 17 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 18 | outColor = vec4(uv, 0.0, 1.0); 19 | } 20 | 21 | //---------------------------- 22 | // Reference 23 | //---------------------------- -------------------------------------------------------------------------------- /src/scripts/entry.ts: -------------------------------------------------------------------------------- 1 | import { Canvas } from './Canvas' 2 | 3 | export function entry(fragmentShader: string, outputFs?: string) { 4 | setSourceLink() 5 | new Canvas(document.querySelector('canvas')!, fragmentShader, outputFs) 6 | } 7 | 8 | function setSourceLink() { 9 | const source = document.querySelector('.links .source') 10 | if (source) { 11 | const page = location.href.split('/').at(-2) 12 | source.href = `https://github.com/nemutas/webgl-sketch/blob/main/src/${page}/sketch.fs` 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/template_postprocessing/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | const float SEED = SEED_VALUE; 15 | 16 | void main() { 17 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 18 | outColor = vec4(uv, 0.0, 1.0); 19 | } 20 | 21 | //---------------------------- 22 | // Reference 23 | //---------------------------- -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webgl-sketch", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "start": "vite", 9 | "build": "tsc && vite build", 10 | "preview": "vite preview" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "^20.11.16", 14 | "@types/three": "^0.160.0", 15 | "prettier": "^3.0.3", 16 | "typescript": "^5.0.2", 17 | "vite": "^4.4.5", 18 | "vite-plugin-glsl": "^1.1.2" 19 | }, 20 | "dependencies": { 21 | "three": "^0.160.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/template_postprocessing/output.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D source; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | void main() { 14 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 15 | 16 | float n = 20.0; 17 | uv = floor(uv * asp * n) / asp / n; 18 | vec3 source = texture(source, uv).rgb; 19 | float gray = dot(source, vec3(0.333333)); 20 | 21 | outColor = vec4(vec3(gray), 1.0); 22 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2023", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /src/20240204/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | const float PI = acos(-1.0); 13 | 14 | void main() { 15 | vec2 uv = vUv, asp = vec2(resolution.x / resolution.y, 1.0), suv = (uv * 2.0 - 1.0) * asp; 16 | 17 | vec2 puv = vec2(atan(suv.y, suv.x), length(suv)); 18 | float c = step(fract(puv.x / PI * 5.0 + sin(puv.y * 10.0 - time)), 0.5); 19 | 20 | vec4 b = texture(backBuffer, vUv); 21 | vec3 col = mix(vec3(c), b.rgb, 0.5); 22 | 23 | outColor = vec4(col, 1.0); 24 | } -------------------------------------------------------------------------------- /src/20240202/sketch.fs: -------------------------------------------------------------------------------- 1 | // https://scrapbox.io/0b5vr/Cyclic_Noise 2 | 3 | #version 300 es 4 | precision highp float; 5 | 6 | uniform sampler2D backBuffer; 7 | uniform vec2 resolution; 8 | uniform vec2 mouse; 9 | uniform float time; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | #define loop(i, n) for(int i; i < n; i++) 15 | 16 | vec3 cyc(vec3 p) { 17 | vec4 n; 18 | loop(i, 8) { 19 | p += sin(p.yzx); 20 | n = 2.0 * n + vec4(cross(cos(p), sin(p.zxy)), 1.0); 21 | p *= 2.0; 22 | } 23 | return n.xyz / n.w; 24 | } 25 | 26 | void main() { 27 | vec2 uv = vUv, suv = uv * 2.0 - 1.0; 28 | vec3 color = cyc(vec3(suv * 3.0, time)) * 0.5 + 0.5; 29 | 30 | outColor = vec4(color, 1.0); 31 | } -------------------------------------------------------------------------------- /src/20240203_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 120bpm 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240205/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0x👾👾u 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240206_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | IFS 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240419/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | old view 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | template 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240202/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cyclic Noise 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240204/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | polar coords 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240207/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | (👾<<16)+👾 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240306/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fake fluid 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240204_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | learning bit calc 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240208/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 👾 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240211/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 山岳 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240214/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cross 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240306_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Lissajous curve 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240207_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | polar👾 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240213/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | voronoi 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240217/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | hash shape 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240218/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Conway's Game of Life 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240308/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 75fps torusknot star 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240206/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | phantom mode 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240210/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | quadtree + pmod 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240213_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | menger sponge 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240221/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | mandelbrot set 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240304/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pattern shading 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240311/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | unshift pattern☐ 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240312/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | unshift pattern○ 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240422/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | quad tree detail 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240425/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | annual tree ring 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240203/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | hemisphere 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240219/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | アルキメデス立体 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240401/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | spread 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240225/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | raymarching study 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240303/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | #define loop(n) for(int i=0;i 2 | 3 | 4 | 5 | 6 | 7 | quad tree text 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /src/20240303/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | dither 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /src/template_postprocessing/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | template 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /src/20240205/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | precision highp int; 4 | 5 | uniform sampler2D backBuffer; 6 | uniform vec2 resolution; 7 | uniform vec2 mouse; 8 | uniform float time; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | void main() { 14 | vec2 uv = vUv, asp = vec2(resolution.x / resolution.y, 1.0); 15 | vec2 iuv = floor(uv * vec2(32.0, 32.0 / asp.x)); 16 | float x = floor(iuv.y / 8.0) * 8.0; 17 | iuv.y = fract(iuv.y / 8.0) * 8.0; 18 | 19 | uint[8] rows = uint[]( 20 | 0x00d800d8u, 21 | 0x05050505u, 22 | 0x05fd05fdu, 23 | 0x07ff07ffu, 24 | 0x03760376u, 25 | 0x01fc01fcu, 26 | 0x00880088u, 27 | 0x01040104u 28 | ); 29 | 30 | float t = time * 100.0 / 60.0 + x; 31 | 32 | float c; 33 | uint b = rows[int(iuv.y)]; 34 | b = (b << uint(iuv.x + t)) >> 31; 35 | c = float(b); 36 | 37 | outColor = vec4(vec3(c), 1.0); 38 | } -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | font-size: 62.5%; 9 | background: #0e0e0e; 10 | } 11 | 12 | a { 13 | position: relative; 14 | display: inline-block; 15 | padding: 5px 3px; 16 | font-size: 15px; 17 | line-height: 1; 18 | text-underline-offset: 2px; 19 | color: #f0f0f0; 20 | } 21 | 22 | canvas { 23 | position: fixed; 24 | top: 0; 25 | width: 100%; 26 | height: 100lvh; 27 | background: #0e0e0e; 28 | } 29 | 30 | .links { 31 | position: absolute; 32 | bottom: 5px; 33 | right: 10px; 34 | } 35 | 36 | .tmp { 37 | color: #fff4; 38 | } 39 | 40 | .sketches { 41 | padding: 5px; 42 | } 43 | 44 | .sketches a::before { 45 | position: absolute; 46 | content: ''; 47 | width: 1px; 48 | height: 50vh; 49 | /* height: 90vh; */ 50 | background: linear-gradient(to bottom, #fff1 80%, transparent 100%); 51 | right: 2px; 52 | top: calc(100% - 7px); 53 | pointer-events: none; 54 | } 55 | -------------------------------------------------------------------------------- /src/20240306_2/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | #define sat(v) clamp(v, 0.0, 1.0) 15 | 16 | void main() { 17 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 18 | 19 | float dt = time - prevTime; 20 | float d, n = 15.0; 21 | for (float i = 0.0; i < n; i++) { 22 | float t = prevTime + dt * (i / n); 23 | vec2 coord = sin(vec2(4, 5) * t * 1.); 24 | d += smoothstep(0.02, 0.01, distance(suv * 1.5, coord)); 25 | } 26 | 27 | vec3 b = texture(backBuffer, uv).rgb; 28 | b *= step(0.08, b); 29 | vec3 col = vec3(d, b.rg); 30 | col = sat(mix(b, col * 2.0, 0.1)); 31 | 32 | outColor = vec4(col, 1.0); 33 | } 34 | 35 | //---------------------------- 36 | // Reference 37 | //---------------------------- 38 | // https://zenn.dev/k_kuroguro/articles/b73e4e6e3d2c13 -------------------------------------------------------------------------------- /src/scripts/core/BackBuffer.ts: -------------------------------------------------------------------------------- 1 | import { FrameBuffer, Options } from './FrameBuffer' 2 | 3 | export abstract class BackBuffer extends FrameBuffer { 4 | private readonly rt2: THREE.WebGLRenderTarget 5 | private prev: THREE.WebGLRenderTarget 6 | private current: THREE.WebGLRenderTarget 7 | 8 | constructor(renderer: THREE.WebGLRenderer, material: THREE.RawShaderMaterial, options?: Options) { 9 | super(renderer, material, options) 10 | 11 | this.rt2 = this.createRenderTarget() 12 | this.prev = this.renderTarget 13 | this.current = this.rt2 14 | } 15 | 16 | resize() { 17 | super.resize() 18 | this.rt2.setSize(this.size.width, this.size.height) 19 | } 20 | 21 | get backBuffer() { 22 | return this.prev.texture 23 | } 24 | 25 | private swap() { 26 | this.current = this.current === this.renderTarget ? this.rt2 : this.renderTarget 27 | this.prev = this.current === this.renderTarget ? this.rt2 : this.renderTarget 28 | } 29 | 30 | render(..._args: any[]) { 31 | this.renderer.setRenderTarget(this.current) 32 | this.renderer.render(this.scene, this.camera) 33 | 34 | this.swap() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/20240203/sketch.fs: -------------------------------------------------------------------------------- 1 | // https://twitter.com/cmzw_/status/1616708959506948096 2 | 3 | #version 300 es 4 | precision highp float; 5 | 6 | uniform sampler2D backBuffer; 7 | uniform vec2 resolution; 8 | uniform vec2 mouse; 9 | uniform float time; 10 | uniform sampler2D textureUnit; 11 | 12 | in vec2 vUv; 13 | out vec4 outColor; 14 | 15 | vec2 coveredUv() { 16 | ivec2 imgSize = textureSize(textureUnit, 0); 17 | float imgAsp = float(imgSize.x) / float(imgSize.y); 18 | float screenAsp = resolution.x / resolution.y; 19 | vec2 covered = imgAsp < screenAsp ? vec2(1.0, imgAsp / screenAsp) : vec2(screenAsp / imgAsp, 1.0); 20 | return (vUv - 0.5) * covered + 0.5; 21 | } 22 | 23 | void main() { 24 | vec2 asp = vec2(resolution.x / resolution.y, 1.0); 25 | vec2 suv = vUv * 2.0 - 1.0; 26 | suv *= asp * 1.5; 27 | vec3 hemiSphereNormal = normalize(vec3(suv, (sqrt(1.0 - dot(suv, suv)) + 0.5) / 0.5)); 28 | vec2 distortion = hemiSphereNormal.xy * (1.0 - hemiSphereNormal.z); 29 | 30 | vec2 uv = coveredUv(); 31 | uv.x += time * 0.1; 32 | vec4 col = mix(texture(textureUnit, uv), texture(textureUnit, uv + distortion), smoothstep(1.0, 0.99, length(suv))); 33 | 34 | outColor = col; 35 | } -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { defineConfig } from 'vite' 3 | import glsl from 'vite-plugin-glsl' 4 | 5 | function resolvedPath(root: string) { 6 | const r = root !== '' ? `/${root}` : '' 7 | return path.resolve(__dirname, `./src${r}/index.html`) 8 | } 9 | 10 | export default defineConfig(() => { 11 | return { 12 | root: './src', 13 | publicDir: '../public', 14 | base: '/webgl-sketch/', 15 | build: { 16 | outDir: '../dist', 17 | rollupOptions: { 18 | // prettier-ignore 19 | input: [ 20 | '', 21 | 'template', 'template_postprocessing', 22 | '20240202', '20240203', '20240203_2', '20240204', '20240204_2', '20240205', '20240206', '20240206_2', '20240207', '20240207_2', '20240208', '20240210', '20240211', '20240213', '20240213_2', '20240214', '20240217', '20240218', '20240219', '20240221', '20240225', 23 | '20240303', '20240304', '20240306', '20240306_2', '20240308', '20240311', '20240312', 24 | '20240401', '20240418', '20240419', '20240422', '20240425', 25 | ].map((str) => resolvedPath(str)), 26 | }, 27 | }, 28 | plugins: [glsl()], 29 | server: { 30 | host: true, 31 | }, 32 | } 33 | }) 34 | -------------------------------------------------------------------------------- /src/20240419/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | const float SEED = SEED_VALUE; 15 | 16 | #define h21(f2, f1) hash(vec3(f2, f1)) 17 | 18 | vec3 hash(vec3 v) { 19 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 20 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 21 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 22 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 23 | return vec3(x) / vec3(-1u); 24 | } 25 | 26 | void main() { 27 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 28 | 29 | float lt = time * 180.0 / 60.0; 30 | float bt = floor(lt); 31 | float tt = tanh(fract(lt) * 5.0); 32 | lt = bt + tt; 33 | 34 | vec3 h1 = h21(floor(uv * asp * vec2(1000, 0)), floor(time * 30.0)); 35 | vec3 h2 = h21(floor(floor(uv * asp * 400.0)), floor(time * 30.0)); 36 | float c = step(h1.x, 0.995); 37 | c *= step(h2.x, 0.9999); 38 | c = 1.0 - clamp(c, 0.0, 1.0); 39 | c *= 0.2; 40 | 41 | outColor = vec4(vec3(c), 1.0); 42 | } 43 | 44 | //---------------------------- 45 | // Reference 46 | //---------------------------- -------------------------------------------------------------------------------- /src/20240203_2/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define sat(v) clamp(v, 0.0, 1.0) 13 | 14 | const float PI = acos(-1.0); 15 | 16 | mat2 rot(float a) { 17 | float s = sin(a), c = cos(a); 18 | return mat2(c, s, -s, c); 19 | } 20 | 21 | void main() { 22 | vec2 uv = vUv, asp = vec2(resolution.x / resolution.y, 1.0), suv = (uv * 2.0 - 1.0) * asp; 23 | 24 | vec4 b = texture(backBuffer, uv); 25 | 26 | float lt = time * 120.0 / 60.0; // 120bpm 27 | float bt = floor(lt); 28 | float tt = tanh(fract(lt) * 5.0); 29 | lt = bt + tt; 30 | 31 | suv *= rot(PI * 0.25 * lt); 32 | 33 | vec2 auv = abs(suv), ruv = abs(rot(PI * 0.25) * suv); 34 | float c = step(auv.x + auv.y * 0.18, 0.12) + step(auv.y + auv.x * 0.18, 0.12); 35 | c += step(ruv.x + ruv.y * 0.18, 0.08) + step(ruv.y + ruv.x * 0.18, 0.08); 36 | auv = abs(rot(PI * 1.0 / 6.2) * suv), ruv = abs(rot(PI * 1.0 / 2.95) * suv); 37 | c *= step(0.008, auv.x) * step(0.008, auv.y) * step(0.008, ruv.x) * step(0.008, ruv.y); 38 | 39 | vec3 col = vec3(sat(c), b.rg); 40 | col = mix(col, b.rgb, 0.5); 41 | 42 | outColor = vec4(col, 1.0); 43 | } -------------------------------------------------------------------------------- /src/scripts/Params.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | class Params { 4 | private data_texture?: string 5 | private data_dpr?: string 6 | private data_stats?: string 7 | private data_cubemap?: string 8 | private data_filter?: string 9 | 10 | constructor() { 11 | const canvas = document.querySelector('canvas')! 12 | this.data_texture = canvas.dataset.texture 13 | this.data_dpr = canvas.dataset.dpr 14 | this.data_stats = canvas.dataset.stats 15 | this.data_cubemap = canvas.dataset.cubemap 16 | this.data_filter = canvas.dataset.filter 17 | } 18 | 19 | get texturePath() { 20 | if (this.data_texture) { 21 | return import.meta.env.BASE_URL + `textures/${this.data_texture}` 22 | } else { 23 | return null 24 | } 25 | } 26 | 27 | get cubeMapPath() { 28 | if (this.data_cubemap) { 29 | return import.meta.env.BASE_URL + `textures/${this.data_cubemap}/` 30 | } else { 31 | return null 32 | } 33 | } 34 | 35 | get dpr() { 36 | const d = Number(this.data_dpr ?? window.devicePixelRatio) 37 | return Math.min(d, 2) 38 | } 39 | 40 | get enableStats() { 41 | return Boolean(this.data_stats) 42 | } 43 | 44 | get filterType() { 45 | return this.data_filter === 'linear' ? THREE.LinearFilter : THREE.NearestFilter 46 | } 47 | } 48 | 49 | export const params = new Params() 50 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | # 静的コンテンツを GitHub Pages にデプロイするためのシンプルなワークフロー 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # デフォルトブランチを対象としたプッシュ時にで実行されます 6 | push: 7 | branches: ['main'] 8 | paths-ignore: ['**/README.md'] 9 | 10 | # Actions タブから手動でワークフローを実行できるようにします 11 | workflow_dispatch: 12 | 13 | # GITHUB_TOKEN のパーミッションを設定し、GitHub Pages へのデプロイを許可します 14 | permissions: 15 | contents: read 16 | pages: write 17 | id-token: write 18 | 19 | # 1 つの同時デプロイメントを可能にする 20 | concurrency: 21 | group: 'pages' 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | # デプロイするだけなので、単一のデプロイジョブ 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v3 34 | - name: Set up Node 35 | uses: actions/setup-node@v3 36 | with: 37 | node-version: 18 38 | cache: 'npm' 39 | - name: Install dependencies 40 | run: npm install 41 | - name: Build 42 | run: npm run build 43 | - name: Setup Pages 44 | uses: actions/configure-pages@v3 45 | - name: Upload artifact 46 | uses: actions/upload-pages-artifact@v1 47 | with: 48 | # dist リポジトリのアップロード 49 | path: './dist' 50 | - name: Deploy to GitHub Pages 51 | id: deployment 52 | uses: actions/deploy-pages@v1 53 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/scripts/Mouse2D.ts: -------------------------------------------------------------------------------- 1 | class Mouse2D { 2 | readonly position: [number, number] = [99999, 99999] 3 | readonly prevPosition: [number, number] = [99999, 99999] 4 | 5 | constructor() { 6 | window.addEventListener('mousemove', this.handleMouseMove) 7 | window.addEventListener('touchmove', this.handleTouchMove) 8 | } 9 | 10 | private handleMouseMove = (e: MouseEvent) => { 11 | this.prevPosition[0] = this.position[0] 12 | this.prevPosition[1] = this.position[1] 13 | this.position[0] = (e.clientX / window.innerWidth) * 2 - 1 14 | this.position[1] = -1 * ((e.clientY / window.innerHeight) * 2 - 1) 15 | } 16 | 17 | private handleTouchMove = (e: TouchEvent) => { 18 | const { pageX, pageY } = e.touches[0] 19 | this.prevPosition[0] = this.position[0] 20 | this.prevPosition[1] = this.position[1] 21 | this.position[0] = (pageX / window.innerWidth) * 2 - 1 22 | this.position[1] = -1 * ((pageY / window.innerHeight) * 2 - 1) 23 | } 24 | 25 | lerp(t: number) { 26 | this.prevPosition[0] = this.prevPosition[0] * (1 - t) + this.position[0] * t 27 | this.prevPosition[1] = this.prevPosition[1] * (1 - t) + this.position[1] * t 28 | return [this.position[0] - this.prevPosition[0], this.position[1] - this.prevPosition[1]] 29 | } 30 | 31 | dispose() { 32 | window.removeEventListener('mousemove', this.handleMouseMove) 33 | window.removeEventListener('touchmove', this.handleTouchMove) 34 | } 35 | } 36 | 37 | export const mouse2d = new Mouse2D() 38 | -------------------------------------------------------------------------------- /src/scripts/MainScene.ts: -------------------------------------------------------------------------------- 1 | import { mouse2d } from './Mouse2D' 2 | import { BackBuffer } from './core/BackBuffer' 3 | import { RawShaderMaterial } from './core/ExtendedMaterials' 4 | import vertexShader from './shader/quad.vs' 5 | 6 | export class MainScene extends BackBuffer { 7 | constructor(renderer: THREE.WebGLRenderer, fragmentShader: string) { 8 | fragmentShader = fragmentShader.replace('SEED_VALUE', Math.random().toFixed(5)) 9 | 10 | const material = new RawShaderMaterial({ 11 | uniforms: { 12 | backBuffer: { value: null }, 13 | resolution: { value: [renderer.domElement.width, renderer.domElement.height] }, 14 | mouse: { value: mouse2d.position }, 15 | time: { value: 0 }, 16 | prevTime: { value: 0 }, 17 | frame: { value: 0 }, 18 | }, 19 | vertexShader, 20 | fragmentShader, 21 | glslVersion: '300 es', 22 | }) 23 | 24 | super(renderer, material) 25 | } 26 | 27 | resize() { 28 | super.resize() 29 | this.uniforms.resolution.value = [this.size.width, this.size.height] 30 | this.uniforms.time.value = 0 31 | this.uniforms.prevTime.value = 0 32 | this.uniforms.frame.value = 0 33 | } 34 | 35 | render(dt: number) { 36 | this.uniforms.backBuffer.value = this.backBuffer 37 | this.uniforms.mouse.value = mouse2d.position 38 | this.uniforms.prevTime.value = this.uniforms.time.value 39 | this.uniforms.time.value += dt 40 | this.uniforms.frame.value += 1 41 | super.render() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/20240213/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | vec2 hash(vec2 v) { 13 | uvec2 x = floatBitsToUint(v + vec2(0.1, 0.2)); 14 | x = (x >> 8 ^ x.yx) * 0x456789ABu; 15 | x = (x >> 8 ^ x.yx) * 0x6789AB45u; 16 | x = (x >> 8 ^ x.yx) * 0x89AB4567u; 17 | return vec2(x) / vec2(-1u); 18 | } 19 | 20 | mat2 rot(float a) { 21 | float s = sin(a), c = cos(a); 22 | return mat2(c, s, -s, c); 23 | } 24 | 25 | vec3 voronoi(vec2 p) { 26 | vec2 n = floor(p + 0.5); 27 | float dist = sqrt(2.0); 28 | vec2 id; 29 | for (float j = -1.0; j <= 1.0; j++) { 30 | for (float i = -1.0; i <= 1.0; i++) { 31 | vec2 grid = n + vec2(i, j); 32 | vec2 h = hash(grid) - 0.5; 33 | vec2 jitter = rot(time * sign(h).x * h.y * 5.0) * h; 34 | if (distance(grid + jitter, p) <= dist) { 35 | dist = distance(grid + jitter, p); 36 | id = grid; 37 | } 38 | } 39 | } 40 | return vec3(id, dist); 41 | } 42 | 43 | void main() { 44 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 45 | vec3 v = voronoi(uv * asp * 10.0); 46 | vec2 vid = hash(v.xy); 47 | vec3 col = vec3(vid, 0.9) + pow(v.z, 5.0); 48 | outColor = vec4(col, 1.0); 49 | } 50 | 51 | //---------------------------- 52 | // Reference 53 | //---------------------------- 54 | // リアルタイムグラフィックスの数学 ― GLSLではじめるシェーダプログラミング 55 | // https://amzn.asia/d/9rQTjZC -------------------------------------------------------------------------------- /src/20240211/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | 14 | float lt, bt, tt; 15 | 16 | vec3 cyc(vec3 p) { 17 | vec4 n; 18 | loop(8) { 19 | p += sin(p.yzx); 20 | n = 2.0 * n + vec4(cross(cos(p), sin(p.zxy)), 1.0); 21 | p *= 2.0; 22 | } 23 | return n.xyz / n.w; 24 | } 25 | 26 | mat2 rot(float a) { 27 | float s = sin(a), c = cos(a); 28 | return mat2(c, s, -s, c); 29 | } 30 | 31 | float sdf(vec3 p) { 32 | p.y += 13.0; 33 | p.yz *= rot(-time * 0.01); 34 | p += cyc(p * 2.0 + lt) * 0.25; 35 | float final = length(p) - 13.0; 36 | return final * 0.6; 37 | } 38 | 39 | void main() { 40 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 41 | vec3 rd = normalize(vec3(suv, -5.0)), ro = vec3(0.0, 0.0, 7.0); 42 | 43 | lt = time * 30.0 / 60.0; 44 | bt = floor(lt); 45 | tt = tanh(fract(lt) * 5.0); 46 | lt = bt + tt; 47 | 48 | float t, acc; 49 | loop(80) { 50 | vec3 p = rd * t + ro; 51 | float d = sdf(p); 52 | if (d < 1e-4 || 1e4 < t) break; 53 | t += d; 54 | acc += exp(abs(d) * -5.0); 55 | } 56 | 57 | float c = acc / 80.0; 58 | 59 | vec4 b = texture(backBuffer, vUv); 60 | vec3 col = mix(vec3(c), b.rgb, 0.7); 61 | 62 | outColor = vec4(col, 1.0); 63 | } 64 | 65 | //---------------------------- 66 | // Reference 67 | //---------------------------- -------------------------------------------------------------------------------- /src/20240206/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | 14 | mat2 rot(float a) { 15 | float s = sin(a), c = cos(a); 16 | return mat2(c, s, -s, c); 17 | } 18 | 19 | float box(vec3 p, vec3 b) { 20 | p = abs(p) - b; 21 | return max(p.x, max(p.y, p.z)); 22 | } 23 | 24 | float sdf(vec3 p) { 25 | float final = 1e9; 26 | 27 | p.xz *= rot(time); 28 | p.zy *= rot(time); 29 | 30 | p = abs(p); 31 | vec3 edge = 0.5 - max(vec3(0.5), p) * 0.2; 32 | float b1 = box(p, vec3(2.5, edge.x, edge.x)); 33 | float b2 = box(p, vec3(edge.y, 2.5, edge.y)); 34 | float b3 = box(p, vec3(edge.z, edge.z, 2.5)); 35 | final = min(b1, min(b2, b3)); 36 | return final; 37 | } 38 | 39 | void main() { 40 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv - 0.5) * asp * 2.0; 41 | vec3 rd = normalize(vec3(suv, -4.0 + length(suv) * 5.0)), ro = vec3(0.0, 0.0, 8.0); 42 | 43 | float t, acc; 44 | loop(64) { 45 | vec3 p = rd * t + ro; 46 | float d = sdf(p); 47 | d = max(abs(d), 0.01); 48 | acc += exp(-d * 3.0); 49 | t += d; 50 | } 51 | 52 | acc *= 0.03; 53 | vec3 col = vec3(0.00, 0.56, 1.00) * acc; 54 | outColor = vec4(col, 1.0); 55 | } 56 | 57 | //---------------------------- 58 | // Reference 59 | //---------------------------- 60 | // 魔法使いになりたい人のためのシェーダーライブコーディング入門 61 | // https://qiita.com/kaneta1992/items/21149c78159bd27e0860 -------------------------------------------------------------------------------- /src/20240312/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | const float PI = acos(-1.0); 15 | 16 | vec3 hash(vec3 v) { 17 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 18 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 19 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 20 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 21 | return vec3(x) / vec3(-1u); 22 | } 23 | 24 | float pattern(vec2 uv, float n) { 25 | vec2 suv = uv * 2.0 - 1.0; 26 | float len = length(suv); 27 | float p = step(sin(len * PI * n), 0.0); 28 | if (mod(n, 2.0) == 1.0) p = 1.0 - p; 29 | p *= step(len, 1.0) * step(0.1, n); 30 | return p; 31 | } 32 | 33 | void main() { 34 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 35 | 36 | float bt = floor(time * 30.0 / 60.0); 37 | 38 | vec2 quv = uv * asp * 1.1, fuv, iuv; 39 | vec3 h; 40 | for (int i = 0; i < 5; i++) { 41 | fuv = fract(quv); 42 | iuv = floor(quv); 43 | if (0 < i && (h = hash(vec3(iuv, bt))).x < (0.3 + float(i) * 0.1)) break; 44 | quv *= 2.0; 45 | } 46 | 47 | float n = floor(h.y * 6.0); 48 | float c = pattern(fuv, n); 49 | 50 | if (h.z < 0.5) c = 1.0 - c; 51 | 52 | vec3 col = mix(vec3(1) * 0.93, vec3(1), c); 53 | 54 | vec3 b = texture(backBuffer, uv).rgb; 55 | col = mix(b, col, 0.5); 56 | 57 | outColor = vec4(col, 1.0); 58 | } 59 | 60 | //---------------------------- 61 | // Reference 62 | //---------------------------- -------------------------------------------------------------------------------- /src/20240221/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | #define loop(n) for(int i; i < n; i++) 14 | 15 | const float PI = acos(-1.0); 16 | 17 | mat2 rot(float a) { 18 | float s = sin(a), c = cos(a); 19 | return mat2(c, s, -s, c); 20 | } 21 | 22 | void main() { 23 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 24 | 25 | float lt = time * 30.0 / 60.0; 26 | float bt = floor(lt); 27 | float tt = tanh(fract(lt) * 5.0); 28 | 29 | suv *= 1.0 - length(suv) * (1.0 - tt); 30 | 31 | vec2 z, c; 32 | if (mod(bt, 3.0) == 0.0) { 33 | z = vec2(0) + ((1.0 - tt * tt) * 0.5); 34 | c = suv + vec2(-0.5, 0.0); 35 | } else if (mod(bt, 3.0) == 1.0) { 36 | z = suv * rot(PI * 0.5) * 0.5; 37 | c = vec2(0.25, 0.58) * (tt * tt * 0.05 + 0.95); 38 | } else { 39 | z = suv * rot(PI * 0.5) * 0.5; 40 | c = vec2(0.25, 0.6) * (tt * tt * 0.05 + 0.95) + (suv + 0.3) * 0.07; 41 | } 42 | 43 | float j; 44 | loop(70) { 45 | z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c; 46 | if (4.0 < dot(z, z)) break; 47 | j++; 48 | } 49 | 50 | float lum = j / 60.0; 51 | lum = smoothstep(0.35, 1.0, lum); 52 | 53 | outColor = vec4(vec3(lum), 1.0); 54 | } 55 | 56 | //---------------------------- 57 | // Reference 58 | //---------------------------- 59 | // z(n+1) = z(n)^2 + c. z, c: complex number 60 | // https://wgld.org/d/glsl/g005.html 61 | // https://wgld.org/d/glsl/g006.html -------------------------------------------------------------------------------- /src/20240207/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | precision highp int; 4 | 5 | uniform sampler2D backBuffer; 6 | uniform vec2 resolution; 7 | uniform vec2 mouse; 8 | uniform float time; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | #define loop(i, n) for(int i; i < n; i++) 14 | 15 | vec3 hash(vec3 v) { 16 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 17 | x = (x >> 8 ^ x.zxy) * 0x456789ABu; 18 | x = (x >> 8 ^ x.zxy) * 0x6789AB45u; 19 | x = (x >> 8 ^ x.zxy) * 0x89AB4567u; 20 | return vec3(x) / vec3(-1u); 21 | } 22 | 23 | void main() { 24 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 25 | 26 | float lt = time * 30.0 / 60.0; 27 | float bt = floor(lt); 28 | 29 | float sp = 32.0; 30 | loop(i, 3) { 31 | if(hash(vec3(vec2(0.1, 0.2) * float(i), bt)).x < 0.5) break; 32 | sp *= 1.5; 33 | } 34 | 35 | vec2 iuv = floor(uv * asp * sp); 36 | float x = mod(floor(iuv.y / 9.0), 2.0) * 8.0; 37 | iuv = mod(iuv, vec2(32.0, 9.0)); 38 | 39 | uint[8] rows = uint[]( 40 | (0x0d8u << 16) + 0x0d8u, 41 | (0x505u << 16) + 0x505u, 42 | (0x5fdu << 16) + 0x5fdu, 43 | (0x7ffu << 16) + 0x7ffu, 44 | (0x376u << 16) + 0x376u, 45 | (0x1fcu << 16) + 0x1fcu, 46 | (0x088u << 16) + 0x088u, 47 | (0x104u << 16) + 0x104u 48 | ); 49 | 50 | float c; 51 | if (int(iuv.y) < rows.length()) { 52 | uint b = rows[int(iuv.y)]; 53 | float shift = 0.0 < sign(x) ? iuv.x : 32.0 - iuv.x; 54 | b = (b << uint(shift + x + lt * 4.0)) >> 31; 55 | c = float(b); 56 | } 57 | 58 | vec4 b = texture(backBuffer, uv); 59 | vec3 col = vec3(c, b.rg); 60 | 61 | outColor = vec4(col, 1.0); 62 | } -------------------------------------------------------------------------------- /src/20240214/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | #define sat(v) clamp(v, 0.0, 1.0) 14 | 15 | const float PI = acos(-1.0); 16 | 17 | mat2 rot(float a) { 18 | float s = sin(a), c = cos(a); 19 | return mat2(c, s, -s, c); 20 | } 21 | 22 | float box(vec3 p, vec3 b) { 23 | p = abs(p) - b; 24 | return max(p.x, max(p.y, p.z)); 25 | // return length(max(p, 0.0)) + min(max(p.x, max(p.y, p.z)), 0.0); 26 | } 27 | 28 | float sdf(vec3 p) { 29 | p.xy *= rot(-p.z * PI * 0.03); 30 | p.z += fract(-time) * 3.0; 31 | 32 | p = mod(p, 3.0) - 1.5; 33 | 34 | float d = 1e4; 35 | d = min(d, length(p.xz) - 0.05); 36 | d = min(d, length(p.yz) - 0.05); 37 | d = min(d, length(p.xy) - 0.05); 38 | d = max(d, box(p, vec3(0.5))); 39 | return d; 40 | } 41 | 42 | void main() { 43 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 44 | vec3 rd = normalize(vec3(suv, -2.0 - length(suv) * 0.5)), ro = vec3(0.0, 0.0, 10.0); 45 | 46 | float t, acc; 47 | loop(64) { 48 | vec3 p = rd * t + ro; 49 | float d = sdf(p) * 0.7; 50 | if (d < 1e-4 || 1e4 < t) break; 51 | t += d; 52 | acc += exp(abs(d) * -20.0); 53 | } 54 | 55 | float c = acc / 64.0; 56 | 57 | vec4 b = texture(backBuffer, uv); 58 | vec3 col = vec3(sat(c), b.rg); 59 | col = mix(col, b.rgb, 0.3) * 1.1; 60 | 61 | outColor = vec4(col, 1.0); 62 | } 63 | 64 | //---------------------------- 65 | // Reference 66 | //---------------------------- -------------------------------------------------------------------------------- /src/20240308/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | #define sat(v) clamp(v, 0.0, 1.0) 15 | 16 | const float PI = acos(-1.0); 17 | const float p = 3.0, q = 10.0; 18 | 19 | float sdSegment(in vec2 p, in vec2 a, in vec2 b) { 20 | vec2 pa = p - a, ba = b - a; 21 | float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); 22 | return length(pa - ba * h); 23 | } 24 | 25 | vec3 torusknot(float t) { 26 | float r = 1.0 + 0.5 * cos(2.0 * PI * p * t); 27 | float theta = 2.0 * PI * q * t; 28 | float z = 0.5 * sin(2.0 * PI * p * t); 29 | return vec3(r * cos(theta), r * sin(theta), z); 30 | } 31 | 32 | void main() { 33 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 34 | vec4 b = texture(backBuffer, uv); 35 | 36 | float fps = round(1.0 / (time - prevTime)); 37 | // float speed = 0.1; 38 | float speed = 3.0; // star 39 | // float speed = 2.0; // rectangle 40 | vec2 p1 = torusknot(fract(prevTime * speed)).xy; 41 | vec2 p2 = torusknot(fract(time * speed)).xy; 42 | float l = smoothstep(0.01, 0.00, sdSegment(suv * 2.0, p1, p2)); 43 | 44 | b.rgb *= step(0.1, b.rgb); 45 | vec3 col = vec3(sat(l), b.rg); 46 | col = mix(b.rgb, col * 5.0, 0.2); 47 | 48 | outColor = vec4(col, 1.0); 49 | } 50 | 51 | //---------------------------- 52 | // Reference 53 | //---------------------------- 54 | // https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%BC%E3%83%A9%E3%82%B9%E7%B5%90%E3%81%B3%E7%9B%AE 55 | // https://iquilezles.org/articles/distfunctions2d/ -------------------------------------------------------------------------------- /src/20240217/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | 14 | mat2 rot(float a) { 15 | float s = sin(a), c = cos(a); 16 | return mat2(c, s, -s, c); 17 | } 18 | 19 | vec3 hash(vec3 v) { 20 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 21 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 22 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 23 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 24 | return vec3(x) / vec3(-1u); 25 | } 26 | 27 | float box(vec3 p, vec3 b) { 28 | p = abs(p) - b; 29 | return max(p.x, max(p.y, p.z)); 30 | } 31 | 32 | float sdf(vec3 p) { 33 | float d = 1e9; 34 | 35 | p.xy *= rot(time * 0.5); 36 | p.yz *= rot(time * 0.4); 37 | p.zx *= rot(time * 0.3); 38 | 39 | vec2 cb = vec2(0.48, 1.0); 40 | d = min(d, box(p, cb.xxy)); 41 | d = min(d, box(p, cb.xyx)); 42 | d = min(d, box(p, cb.yxx)); 43 | d = max(-d, box(p, vec3(0.5))); 44 | return d; 45 | } 46 | 47 | void main() { 48 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 49 | suv = floor(suv * 50.0) / 50.0; 50 | vec3 rd = normalize(vec3(suv, -5.0)), ro = vec3(0.0, 0.0, 5.0); 51 | 52 | float t; 53 | loop(64) { 54 | vec3 p = rd * t + ro; 55 | float d = sdf(p); 56 | if (d < 1e-4 || 1e4 < t) break; 57 | t += d; 58 | } 59 | 60 | vec3 h = hash(vec3(suv, step(t, 1e4))); 61 | outColor = vec4(vec3(step(h.x, 0.5)), 1.0); 62 | } 63 | 64 | //---------------------------- 65 | // Reference 66 | //---------------------------- 67 | // https://x.com/matthen2/status/1758504190987423850?s=20 -------------------------------------------------------------------------------- /src/20240311/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | vec3 hash(vec3 v) { 15 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 16 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 17 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 18 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 19 | return vec3(x) / vec3(-1u); 20 | } 21 | 22 | float pattern(vec2 uv, float n) { 23 | float c = 0.0; 24 | vec2 auv = abs(uv * 2.0 - 1.0); 25 | float s = 1.0 / n; 26 | for (float i = 1.0; i < n; i++) { 27 | float a = step(auv.x, 1.0 - s * i) * step(auv.y, 1.0 - s * i); 28 | c = mix(c, mod(i, 2.0) == 0.0 ? 0.0 : 1.0, a); 29 | } 30 | return c; 31 | } 32 | 33 | void main() { 34 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 35 | 36 | float bt = floor(time * 30.0 / 60.0); 37 | 38 | vec2 quv = uv * asp * 1.1, fuv, iuv; 39 | vec3 h; 40 | for (int i = 0; i < 5; i++) { 41 | fuv = fract(quv); 42 | iuv = floor(quv); 43 | if (0 < i && (h = hash(vec3(iuv, bt))).x < (0.2 + float(i) * 0.1)) break; 44 | quv *= 2.0; 45 | } 46 | 47 | // 1, 3, 4, 5, 6 48 | float n = ceil(h.y * 6.0); 49 | if (n == 2.0) n = 1.0; 50 | float c = pattern(fuv, n); 51 | 52 | if (h.z < 0.5) c = 1.0 - c; 53 | 54 | vec3 col = mix(vec3(1) * 0.93, vec3(1), c); 55 | 56 | vec3 b = texture(backBuffer, uv).rgb; 57 | col = mix(b, col, 0.5); 58 | 59 | outColor = vec4(col, 1.0); 60 | } 61 | 62 | //---------------------------- 63 | // Reference 64 | //---------------------------- 65 | // https://unshift.jp/ -------------------------------------------------------------------------------- /src/20240303/output.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D source; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | // const float BAYER[16] = float[]( 14 | // 0.0, 8.0, 2.0, 10.0, 15 | // 12.0, 4.0, 14.0, 6.0, 16 | // 3.0, 11.0, 1.0, 9.0, 17 | // 15.0, 7.0, 13.0, 5.0 18 | // ); 19 | 20 | const float BAYER[64] = float[]( 21 | 0.0, 32.0, 8.0, 40.0, 2.0, 34.0, 10.0, 42.0, 22 | 48.0, 16.0, 56.0, 24.0, 50.0, 18.0, 58.0, 26.0, 23 | 12.0, 44.0, 4.0, 36.0, 14.0, 46.0, 6.0, 38.0, 24 | 60.0, 28.0, 52.0, 20.0, 62.0, 30.0, 54.0, 22.0, 25 | 3.0, 35.0, 11.0, 43.0, 1.0, 33.0, 9.0, 41.0, 26 | 51.0, 19.0, 59.0, 27.0, 49.0, 17.0, 57.0, 25.0, 27 | 15.0, 47.0, 7.0, 39.0, 13.0, 45.0, 5.0, 37.0, 28 | 63.0, 31.0, 55.0, 23.0, 61.0, 29.0, 53.0, 21.0 29 | ); 30 | 31 | void main() { 32 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 33 | 34 | vec3 col = texture(source, uv).rgb; 35 | float luma = dot(col, vec3(0.299, 0.587, 0.114)); 36 | 37 | // ivec2 bayerCoord = ivec2(mod(gl_FragCoord.xy, 4.0)); 38 | // float threshold = BAYER[bayerCoord.y * 4 + bayerCoord.x] / 16.0; 39 | 40 | ivec2 bayerCoord = ivec2(mod(gl_FragCoord.xy, 8.0)); 41 | float threshold = BAYER[bayerCoord.y * 8 + bayerCoord.x] / 64.0; 42 | 43 | float g = step(threshold, luma); 44 | outColor = vec4(vec3(g), 1.0); 45 | } 46 | 47 | //---------------------------- 48 | // Reference 49 | //---------------------------- 50 | // https://scrapbox.io/0b5vr/Bayer_matrix 51 | // https://github.com/hughsk/glsl-dither/tree/master 52 | // https://ja.wikipedia.org/wiki/%E9%85%8D%E5%88%97%E3%83%87%E3%82%A3%E3%82%B6%E3%83%AA%E3%83%B3%E3%82%B0 -------------------------------------------------------------------------------- /src/20240210/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | 14 | const float PI = acos(-1.0); 15 | 16 | mat2 rot(float a) { 17 | float s = sin(a), c = cos(a); 18 | return mat2(c, s, -s, c); 19 | } 20 | 21 | vec2 pmod(vec2 p, float r) { 22 | float n = PI * 2.0 / r; 23 | float a = atan(p.x, p.y) + n * 0.5; 24 | a = floor(a / n) * n; 25 | return rot(a) * p; 26 | } 27 | 28 | vec3 hash(vec3 v) { 29 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 30 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 31 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 32 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 33 | return vec3(x) / vec3(-1u); 34 | } 35 | 36 | void main() { 37 | vec2 uv = vUv; 38 | vec2 asp = resolution / min(resolution.x, resolution.y); 39 | 40 | float lt = time * 120.0 / 60.0; 41 | float bt = floor(lt); 42 | float tt = tanh(fract(lt) * 5.0); 43 | lt = bt + tt; 44 | 45 | vec2 quv = uv * asp, fuv, iuv; 46 | float n = 2.0; 47 | loop(4) { 48 | n += 1.0; 49 | fuv = fract(quv); 50 | iuv = floor(quv); 51 | if (hash(vec3(iuv, bt)).x < 0.5) break; 52 | quv *= 2.0; 53 | } 54 | 55 | vec2 suv = fuv * 2.0 - 1.0; 56 | suv *= rot(PI / n * lt); 57 | 58 | float scale = 1.5 + exp((-n + 3.0) * 3.0) * 0.5; 59 | vec2 puv = pmod(-suv * scale, n); 60 | float c = step(fract(puv.x * 10.0 + puv.y * 10.0 - time * 5.0), 0.3) * step(0.5, puv.y) * step(puv.y, 0.7); 61 | 62 | vec4 b = texture(backBuffer, vUv); 63 | vec3 col = vec3(c, b.rg); 64 | 65 | outColor = vec4(col, 1.0); 66 | } 67 | 68 | //---------------------------- 69 | // Reference 70 | //---------------------------- -------------------------------------------------------------------------------- /src/20240219/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | uniform samplerCube cubeTextureUnit; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | #define loop(n) for(int i; i < n; i++) 15 | 16 | const float PI = acos(-1.0); 17 | float lt, bt, tt; 18 | 19 | mat2 rot(float a) { 20 | float s = sin(a), c = cos(a); 21 | return mat2(c, s, -s, c); 22 | } 23 | 24 | float sdf(vec3 p) { 25 | p.xy *= rot(lt * PI * 0.05); 26 | p.yz *= rot(lt * PI * 0.10); 27 | p.zx *= rot(lt * PI * 0.15); 28 | 29 | vec3 bp = abs(p) - 0.5 + sin(lt * PI * 0.25) * 0.25; 30 | float b = max(bp.x, max(bp.y, bp.z)); 31 | 32 | return max(b, dot(normalize(vec3(1)), abs(p)) - 0.43); 33 | } 34 | 35 | void main() { 36 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 37 | vec3 rd = normalize(vec3(suv, -5.0)), ro = vec3(0.0, 0.0, 5.0); 38 | 39 | lt = time * 120.0 / 60.0; 40 | bt = floor(lt); 41 | tt = tanh(fract(lt) * 5.0); 42 | lt = bt + tt; 43 | 44 | float t; 45 | loop(64) { 46 | vec3 p = rd * t + ro; 47 | float d = sdf(p); 48 | if (d < 1e-4 || 1e4 < t) break; 49 | t += d; 50 | } 51 | 52 | vec3 col; 53 | if (t < 1e4) { 54 | vec3 p = rd * t + ro; 55 | vec2 e = vec2(1e-2, 0.0); 56 | vec3 n = normalize(vec3( 57 | sdf(p + e.xyy) - sdf(p - e.xyy), 58 | sdf(p + e.yxy) - sdf(p - e.yxy), 59 | sdf(p + e.yyx) - sdf(p - e.yyx) 60 | )); 61 | vec3 reflection = reflect(rd, n); 62 | col = texture(cubeTextureUnit, reflection).rgb; 63 | } 64 | 65 | outColor = vec4(col, 1.0); 66 | } 67 | 68 | //---------------------------- 69 | // Reference 70 | //---------------------------- 71 | // リアルタイムグラフィックスの数学 ― GLSLではじめるシェーダプログラミング 72 | // hash関数:https://www.shadertoy.com/view/XlXcW4 -------------------------------------------------------------------------------- /src/20240306/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | void main() { 14 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 15 | vec2 p = uv * asp * 6.0; 16 | 17 | for (float i = 0.0; i < 8.0; i++) { 18 | p.x += sin(p.y + i + time * 0.3); 19 | p *= mat2(6, -8, 8, 6) / 8.0; 20 | } 21 | 22 | vec3 col = sin(p.xyx * 0.3 + vec3(0, 1, 2)) * 0.5 + 0.5; 23 | outColor = vec4(col, 1.0); 24 | } 25 | 26 | //---------------------------- 27 | // Reference 28 | //---------------------------- 29 | // https://twitter.com/XorDev/status/1765032092721648044 30 | // https://www.shadertoy.com/view/lXXXzS 31 | 32 | //---------------------------- 33 | // Commnets by @XorDev 34 | //---------------------------- 35 | /** 36 | "Cheap Turbulence" by @XorDev 37 | 38 | Simulating proper fluid dynamics can be complicated and requires a back buffer or multi-pass setup. 39 | 40 | Sometimes, you just want to emulate some smoke or something simple, and you don't want to go through all that trouble. 41 | 42 | This method is very simple! Start with pixel coordinates and scale them down as desired, then with a for loop, 43 | you should do a sine wave offset. In my case I'm doing "p.x+=sin(p.y)". 44 | To animate it, you can add a time offset to the sine wave, and it also helps to shift each iteration with the 45 | iterator "i" to break up visible patterns. 46 | 47 | Next, you want to rotate the coordinates and scale down. It could be as simple as p=p.yx/0.8 or a rotation matrix like mat2(.8,-.6,.6,.8). 48 | 49 | Now the resulting p coordinates will appear turbulent, and you can use these coordinates in color function. 50 | My color equation looks like this: 51 | 52 | fragColor=sin(p.xyxy*.3+vec4(0,1,2,3))*.5+.5 53 | 54 | Smooth, continious equations look best 55 | */ 56 | -------------------------------------------------------------------------------- /src/20240204_2/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | precision highp int; 4 | 5 | uniform sampler2D backBuffer; 6 | uniform vec2 resolution; 7 | uniform vec2 mouse; 8 | uniform float time; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | uvec3 uhash(vec3 p) { 14 | uvec3 x = floatBitsToUint(p + vec3(0.1, 0.2, 0.3)); 15 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 16 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 17 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 18 | return x; 19 | } 20 | 21 | // vec3 hash(vec3 p) { 22 | // uvec3 x = floatBitsToUint(p + vec3(0.1, 0.2, 0.3)); 23 | // x = (x >> 8 ^ x.yzx) * 0x456789ABu; 24 | // x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 25 | // x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 26 | // return vec3(x) / vec3(-1u); 27 | // } 28 | 29 | void main() { 30 | vec2 uv = vUv, asp = vec2(resolution.x / resolution.y, 1.0); 31 | uv *= vec2(32.0, 32.0 / asp); 32 | 33 | uint[16] a = uint[]( 34 | uint(time), 35 | 0xbu, 36 | 9u, 37 | 0xbu ^ 9u, 38 | 0xffffffffu, 39 | 0xffffffffu + uint(time), 40 | floatBitsToUint(floor(time)), 41 | floatBitsToUint(-floor(time)), 42 | floatBitsToUint(11.5625), 43 | // --- 44 | floatBitsToUint(1.0), 45 | floatBitsToUint(2.0), 46 | floatBitsToUint(3.0), 47 | 3u, 48 | uint(3.0), 49 | -1u, 50 | uhash(vec3(floor(time * 10.0))).x 51 | ); 52 | 53 | float c; 54 | if (a.length() - 1 < int(uv.y)) c = 0.0; 55 | else { 56 | uint b = a[int(uv.y)]; 57 | b = (b << uint(uv.x)) >> 31; 58 | c = float(b); 59 | } 60 | 61 | if (fract(uv.x) < 0.05 || fract(uv.y) < 0.05) c = 0.1; 62 | if (int(uv.x) == 1 && fract(uv.x) < 0.05) c = 0.5; 63 | if (int(uv.x) == 9 && fract(uv.x) < 0.05) c = 0.5; 64 | if (int(uv.y) == 9 && fract(uv.y) < 0.05) c = 0.5; 65 | 66 | outColor = vec4(vec3(c), 1.0); 67 | } 68 | 69 | //---------------------------- 70 | // Reference 71 | //---------------------------- 72 | // リアルタイムグラフィックスの数学 ― GLSLではじめるシェーダプログラミング 73 | // hash関数:https://www.shadertoy.com/view/XlXcW4 -------------------------------------------------------------------------------- /src/20240218/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | #define sat(v) clamp(v, 0.0, 1.0) 14 | 15 | vec3 hash(vec3 v) { 16 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 17 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 18 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 19 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 20 | return vec3(x) / vec3(-1u); 21 | } 22 | 23 | void main() { 24 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 25 | float n = 100.0; 26 | vec2 fuv = (floor(uv * asp * n) + 0.5) / n / asp; 27 | vec2 px = 1.0 / n / asp; 28 | 29 | float cell; 30 | if (frame == 1) { 31 | cell = step(hash(vec3(fuv, 0.1)).x, 0.5); 32 | } else { 33 | if (frame % 5 == 0) { 34 | float r; 35 | for (float ix = -1.0; ix <= 1.0; ix++) { 36 | for (float iy = -1.0; iy <= 1.0; iy++) { 37 | if (ix == 0.0 && iy == 0.0) continue; 38 | r += texture(backBuffer, fuv + px * vec2(ix, iy)).a; 39 | } 40 | } 41 | 42 | if (0.5 < texture(backBuffer, fuv).a) { 43 | if (r == 2.0 || r == 3.0) cell = 1.0; 44 | else if (r <= 1.0) cell = 0.0; 45 | else if (4.0 <= r) cell = 0.0; 46 | } else { 47 | cell = float(r == 3.0); 48 | } 49 | } else { 50 | cell = texture(backBuffer, fuv).a; 51 | } 52 | } 53 | 54 | vec4 b = texture(backBuffer, uv); 55 | vec3 col = vec3(cell, b.rg); 56 | col = mix(col, b.rgb, 0.5); 57 | 58 | if (frame % 5 == 0) { 59 | vec2 m = (floor((mouse * 0.5 + 0.5) * asp * n) + 0.5) / n / asp; 60 | vec2 d = step(distance(m * asp, fuv * asp), px * 2.0); 61 | cell += float(hash(vec3(d, float(frame))).x < 0.5) * length(d); 62 | cell = sat(cell); 63 | } 64 | 65 | outColor = vec4(col, cell); 66 | } 67 | 68 | //---------------------------- 69 | // Reference 70 | //---------------------------- -------------------------------------------------------------------------------- /src/20240422/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | const float SEED = SEED_VALUE; 15 | const float PI = acos(-1.0); 16 | 17 | #define h21(f2, f1) hash(vec3(f2, f1)) 18 | 19 | vec3 hash(vec3 v) { 20 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 21 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 22 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 23 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 24 | return vec3(x) / vec3(-1u); 25 | } 26 | 27 | mat2 rot(float a) { 28 | float s = sin(a), c = cos(a); 29 | return mat2(c, s, -s, c); 30 | } 31 | 32 | void main() { 33 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = uv * 2.0 - 1.0; 34 | 35 | float lt = time * 100.0 / 60.0; 36 | float bt = floor(lt); 37 | float tt = tanh(fract(lt) * 3.0); 38 | lt = bt + tt; 39 | 40 | vec2 quv = suv * asp, fuv, iuv; 41 | // quv *= rot(PI * 0.1 + quv.y * 0.315); 42 | quv *= rot(PI * SEED + quv.y * 0.315); 43 | quv.x -= lt * 0.5; 44 | 45 | vec3 h; 46 | float i, n = 4.0; 47 | for (; i < n; i++) { 48 | fuv = fract(quv); 49 | iuv = floor(quv); 50 | 51 | if ((h = h21(iuv, 0.2)).x < 0.3) break; 52 | 53 | quv *= 2.0; 54 | } 55 | 56 | i = clamp(i, 0.0, n - 1.0); 57 | float qScale = pow(2.0, i); 58 | 59 | vec2 sfuv = fuv * 2.0 - 1.0, auv = abs(sfuv); 60 | float thin = 1.0 - 0.005 * qScale; 61 | float edge = smoothstep(thin, thin - 0.01 * qScale, auv.x) * smoothstep(thin, thin - 0.01 * qScale, auv.y); 62 | float disc = smoothstep(0.015 * qScale, (0.015 + 0.005) * qScale, length(sfuv)); 63 | float marker = edge * disc; 64 | if (h.y < 0.1) marker = 0.0; 65 | 66 | vec3 c = mix(vec3(0.01, 0.04, 0.09), vec3(0.99, 0.97, 0.91), marker); 67 | 68 | vec4 b = texture(backBuffer, uv); 69 | vec3 col = mix(b.rgb, c, 0.5); 70 | 71 | outColor = vec4(vec3(marker), 1.0); 72 | outColor = vec4(col, 1.0); 73 | } 74 | 75 | //---------------------------- 76 | // Reference 77 | //---------------------------- -------------------------------------------------------------------------------- /src/20240208/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | precision highp int; 4 | 5 | uniform sampler2D backBuffer; 6 | uniform vec2 resolution; 7 | uniform vec2 mouse; 8 | uniform float time; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | const float PI = acos(-1.0); 14 | 15 | mat2 rot(float a) { 16 | float s = sin(a), c = cos(a); 17 | return mat2(c, s, -s, c); 18 | } 19 | 20 | void main() { 21 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 22 | 23 | vec2 suv = (uv * 2.0 - 1.0) * asp * 1.5; 24 | vec3 pos = vec3(suv, (sqrt(1.0 - dot(suv, suv)) + 0.5) / 0.5); 25 | vec3 normal = normalize(pos); 26 | if (0.0 < step(length(suv), 1.0)) uv += normal.xy * (1.0 - normal.z); 27 | else uv *= 1.5; 28 | 29 | vec2 iuv = floor(uv * 64.0 * asp); 30 | float r = floor(iuv.y / 9.0); 31 | iuv = mod(iuv, vec2(32.0, 9.0)); 32 | 33 | uint[9] rows = uint[]( 34 | (0x0d8u << 16) + 0x202u, 35 | (0x505u << 16) + 0x104u, 36 | (0x5fdu << 16) + 0x3feu, 37 | (0x7ffu << 16) + 0x7ffu, 38 | (0x376u << 16) + 0x777u, 39 | (0x1fcu << 16) + 0x5fdu, 40 | (0x088u << 16) + 0x489u, 41 | (0x104u << 16) + 0x104u, 42 | 0u 43 | ); 44 | 45 | float t1 = time * 100.0 / 60.0; 46 | float t2 = t1 * 0.5; 47 | float bt = floor(t2); 48 | float tt = tanh(fract(t2) * 5.0); 49 | 50 | suv *= rot(-PI * 0.5 - PI / 12.0 * (bt + tt)); 51 | float a = atan(suv.y, suv.x) / PI * 0.5 + 0.5; 52 | 53 | float c; 54 | if (int(iuv.y) < rows.length()) { 55 | uint b = rows[int(iuv.y)]; 56 | if (a < 1.0 - tt) b = ~b; 57 | if (0.0 < mod(bt, 2.0)) b = ~b; 58 | float shift; 59 | if (0.0 < mod(floor(t1), 2.0)) shift += 16.0; 60 | if (0.0 < mod(r, 2.0)) shift += 8.0; 61 | b = (b << uint(iuv.x + shift + t1)) >> 31; 62 | c = float(b); 63 | } 64 | 65 | vec3 col = vec3(0.34, 1.00, 0.11) * c; 66 | 67 | vec3 l = vec3(1.0, 1.0, 4.0); 68 | float diffuse = max(dot(normal, normalize(l - pos)), 0.2); 69 | diffuse = diffuse * 0.7 + pow(diffuse, 30.0) * 0.3; 70 | col *= diffuse; 71 | 72 | outColor = vec4(col, 1.0); 73 | } 74 | 75 | //---------------------------- 76 | // Reference 77 | //---------------------------- -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 | 11 |
12 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /src/20240207_2/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | precision highp int; 4 | 5 | uniform sampler2D backBuffer; 6 | uniform vec2 resolution; 7 | uniform vec2 mouse; 8 | uniform float time; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | #define sat(v) clamp(v, 0.0, 1.0) 14 | 15 | const float PI = acos(-1.0); 16 | 17 | vec3 hash(vec3 v) { 18 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 19 | x = (x >> 8 ^ x.zxy) * 0x456789ABu; 20 | x = (x >> 8 ^ x.zxy) * 0x6789AB45u; 21 | x = (x >> 8 ^ x.zxy) * 0x89AB4567u; 22 | return vec3(x) / vec3(-1u); 23 | } 24 | 25 | mat2 rot(float a) { 26 | float s = sin(a), c = cos(a); 27 | return mat2(c, s, -s, c); 28 | } 29 | 30 | void main() { 31 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y); 32 | float t = time * 60.0 / 60.0; 33 | float bt = floor(t); 34 | float tt = tanh(fract(t) * 5.0); 35 | 36 | uv = (uv - 0.5) * asp; 37 | uv = vec2(atan(uv.y, uv.x) / PI, 0.18 / length(uv)); 38 | vec2 iuv = floor(uv * 64.0); 39 | float x = mod(floor(iuv.y / 9.0), 2.0); 40 | iuv = mod(iuv, vec2(32.0, 9.0)); 41 | 42 | uint[8] rows = uint[]( 43 | (0x0d8u << 16) + 0x0d8u, 44 | (0x505u << 16) + 0x505u, 45 | (0x5fdu << 16) + 0x5fdu, 46 | (0x7ffu << 16) + 0x7ffu, 47 | (0x376u << 16) + 0x376u, 48 | (0x1fcu << 16) + 0x1fcu, 49 | (0x088u << 16) + 0x088u, 50 | (0x104u << 16) + 0x104u 51 | ); 52 | 53 | float c; 54 | if (int(iuv.y) < rows.length()) { 55 | float s = 0.0 < sign(x) ? iuv.x : 32.0 - iuv.x; 56 | uint b = rows[int(iuv.y)]; 57 | b = (b << uint(s + t * 2.0)) >> 31; 58 | c = float(b); 59 | } 60 | 61 | float center = smoothstep(0.2, 0.03, distance((vUv - 0.5) * asp + 0.5, vec2(0.5))); 62 | c = sat(1.0 - c + center); 63 | 64 | uv = (vUv - 0.5) * asp; 65 | uv *= rot(-PI * 0.5 - PI * (bt + tt) * 1.0 / 12.0); 66 | uv = vec2(atan(uv.y, uv.x) / PI, length(uv)); 67 | if (0.0 < mod(bt, 2.0)) c = mix(1.0 - c, c, step(uv.x * 0.5 + 0.5, fract(1.0 - tt))); 68 | else c = mix(c, 1.0 - c, step(uv.x * 0.5 + 0.5, fract(1.0 - tt))); 69 | 70 | outColor = vec4(vec3(c) * 0.9, 1.0); 71 | } 72 | 73 | //---------------------------- 74 | // Reference 75 | //---------------------------- 76 | // OpenGL Tunnel Effect Shader in GLSL 77 | // https://youtube.com/shorts/VF2R4tRdKMI?si=lvEY5fGEvz_d5TLy -------------------------------------------------------------------------------- /src/20240418/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | uniform sampler2D textureUnit; 11 | 12 | in vec2 vUv; 13 | out vec4 outColor; 14 | 15 | #define h21(v2, s) hash(vec3(v2, s)) 16 | const float PI = acos(-1.0); 17 | const float SEED = SEED_VALUE; 18 | 19 | vec3 hash(vec3 v) { 20 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 21 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 22 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 23 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 24 | return vec3(x) / vec3(-1u); 25 | } 26 | 27 | mat2 rot(float a) { 28 | float s = sin(a), c = cos(a); 29 | return mat2(c, s, -s, c); 30 | } 31 | 32 | float easeInOutCubic(float x) { 33 | return x < 0.5 ? 4.0 * x * x * x : 1.0 - pow(-2.0 * x + 2.0, 3.0) / 2.0; 34 | } 35 | 36 | void main() { 37 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 38 | ivec2 tSize = textureSize(textureUnit, 0); 39 | float tAspect = float(tSize.x) / float(tSize.y); 40 | vec4 b = texture(backBuffer, uv); 41 | 42 | float lt = time * 15.0 / 60.0; 43 | float bt = floor(lt); 44 | float tt = easeInOutCubic(tanh(fract(lt) * 3.0)); 45 | // float tt = tanh(fract(lt) * 5.0); 46 | lt = bt + tt; 47 | 48 | vec2 quv = suv, fuv, iuv; 49 | vec3 h; 50 | for (int i = 0; i < 4; i++) { 51 | fuv = fract(quv); 52 | iuv = floor(quv); 53 | if ((h = h21(iuv, float(i + 1) + bt + SEED)).x < 0.4) break; 54 | quv *= 2.0; 55 | } 56 | 57 | vec2 mapUv = fuv; 58 | mapUv += (h21(iuv, floor(time * 10.0)).xy * 2.0 - 1.0) * 0.02; 59 | mapUv = (mapUv - 0.5) * rot(floor(h21(iuv, bt + SEED).x * 4.0) / 4.0 * PI * 2.0) + 0.5; 60 | mapUv.x = floor(h.y * tAspect) / tAspect + mapUv.x / tAspect; 61 | vec4 text = texture(textureUnit, mapUv); 62 | vec3 txt = text.rgb * text.a; 63 | 64 | vec2 auv = abs(fuv * 2.0 - 1.0); 65 | txt *= step(auv.x, 0.9) * step(auv.y, 0.9); 66 | 67 | txt *= 1.0 - h21(uv, time).x * 0.3; 68 | txt *= 1.0 - step(h21(floor(uv * vec2(1000, 0)), time).x, 0.5) * 0.3; 69 | 70 | txt *= step(h.z, tt); 71 | 72 | outColor = vec4(mix(b.rgb, txt, 0.2), 1.0); 73 | } 74 | 75 | //---------------------------- 76 | // Reference 77 | //---------------------------- -------------------------------------------------------------------------------- /src/20240206_2/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | #define sat(v) clamp(v, 0.0, 1.0) 14 | 15 | const float PI = acos(-1.0); 16 | 17 | mat2 rot(float a) { 18 | float s = sin(a), c = cos(a); 19 | return mat2(c, s, -s, c); 20 | } 21 | 22 | float sdf(vec3 p) { 23 | float final = 1e9; 24 | 25 | vec3 bp = p; 26 | 27 | loop(5) { 28 | bp = abs(bp) - 0.5; 29 | bp.xy *= rot(1.0 * PI * 0.25); 30 | bp.xz *= rot(1.0 * PI * 0.25 - time * 0.5); 31 | } 32 | 33 | bp = abs(bp) - vec3(1.0, 0.3, 0.01); 34 | float b = max(bp.x, max(bp.y, bp.z)); 35 | float c = p.z - 0.5; 36 | return max(b, c); 37 | } 38 | 39 | float raymarch(vec3 rd, vec3 ro) { 40 | float t; 41 | loop(128) { 42 | vec3 p = rd * t + ro; 43 | float d = sdf(p); 44 | if (d < 1e-5 || 1e9 < t) break; 45 | t += d; 46 | } 47 | return t; 48 | } 49 | 50 | vec3 calcNormal(vec3 p) { 51 | float h = 1e-4; 52 | vec2 k = vec2(1, -1); 53 | return normalize(vec3( 54 | k.xyy * sdf(p + k.xyy * h) + 55 | k.yxy * sdf(p + k.yxy * h) + 56 | k.yyx * sdf(p + k.yyx * h) + 57 | k.xxx * sdf(p + k.xxx * h) 58 | )); 59 | } 60 | 61 | void main() { 62 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv - 0.5) * asp * 2.0; 63 | vec3 rd = normalize(vec3(suv, -5.0)), ro = vec3(0.0, 0.0, 15.0); 64 | 65 | float t = raymarch(rd, ro); 66 | 67 | vec3 col; 68 | if (t < 1e9) { 69 | vec3 p = rd * t + ro; 70 | vec3 normal = calcNormal(p); 71 | 72 | vec3 l = vec3(5.0, 5.0, 10.0); 73 | float d = clamp(dot(normal, normalize(l - p)), 0.2, 1.0); 74 | col = vec3(d) * 0.5; 75 | 76 | vec3 reflection = reflect(rd, normal); 77 | ro = p + normal * 1e-4 * 2.0; 78 | t = raymarch(reflection, ro); 79 | if (t < 1e9) { 80 | vec3 rp = reflection * t + ro; 81 | normal = calcNormal(rp); 82 | d = clamp(dot(normal, normalize(l - rp)), 0.2, 1.0); 83 | col += vec3(d) * 0.5; 84 | } 85 | } 86 | 87 | outColor = vec4(col, 1.0); 88 | } 89 | 90 | //---------------------------- 91 | // Reference 92 | //---------------------------- 93 | // Iterated Function System(IFS) 94 | // https://qiita.com/kaneta1992/items/21149c78159bd27e0860 -------------------------------------------------------------------------------- /src/scripts/core/FrameBuffer.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | import { params } from '../Params' 3 | 4 | export type Options = { 5 | dpr?: number 6 | matrixAutoUpdate?: boolean 7 | type?: THREE.TextureDataType 8 | } 9 | 10 | export abstract class FrameBuffer { 11 | protected readonly scene: THREE.Scene 12 | protected readonly camera: THREE.OrthographicCamera 13 | protected readonly renderTarget: THREE.WebGLRenderTarget 14 | private readonly screen: THREE.Mesh 15 | 16 | constructor( 17 | protected readonly renderer: THREE.WebGLRenderer, 18 | material: THREE.RawShaderMaterial, 19 | private options?: Options, 20 | ) { 21 | this.scene = new THREE.Scene() 22 | this.camera = new THREE.OrthographicCamera() 23 | this.renderTarget = this.createRenderTarget() 24 | this.screen = this.createScreen(material) 25 | 26 | this.setMatrixAutoUpdate(options?.matrixAutoUpdate ?? false) 27 | } 28 | 29 | private get devicePixelRatio() { 30 | return this.options?.dpr ?? params.dpr 31 | } 32 | 33 | private setMatrixAutoUpdate(v: boolean) { 34 | this.camera.matrixAutoUpdate = v 35 | this.scene.traverse((o) => (o.matrixAutoUpdate = v)) 36 | } 37 | 38 | protected get size() { 39 | return { width: this.renderer.domElement.width * this.devicePixelRatio, height: this.renderer.domElement.height * this.devicePixelRatio } 40 | } 41 | 42 | protected createRenderTarget() { 43 | const rt = new THREE.WebGLRenderTarget(this.size.width, this.size.height, { 44 | type: this.options?.type ?? THREE.UnsignedByteType, 45 | generateMipmaps: false, 46 | minFilter: params.filterType, 47 | magFilter: params.filterType, 48 | wrapS: THREE.RepeatWrapping, 49 | wrapT: THREE.RepeatWrapping, 50 | }) 51 | return rt 52 | } 53 | 54 | private createScreen(material: THREE.RawShaderMaterial) { 55 | const geometry = new THREE.PlaneGeometry(2, 2) 56 | const mesh = new THREE.Mesh(geometry, material) 57 | this.scene.add(mesh) 58 | return mesh 59 | } 60 | 61 | get uniforms() { 62 | return this.screen.material.uniforms 63 | } 64 | 65 | resize() { 66 | this.renderTarget.setSize(this.size.width, this.size.height) 67 | } 68 | 69 | get texture() { 70 | return this.renderTarget.texture 71 | } 72 | 73 | render(..._args: any[]) { 74 | this.renderer.setRenderTarget(this.renderTarget) 75 | this.renderer.render(this.scene, this.camera) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/20240401/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform float prevTime; 9 | uniform int frame; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | float rand(vec2 n) { 15 | return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); 16 | } 17 | 18 | float noise(vec2 p) { 19 | vec2 ip = floor(p); 20 | vec2 u = fract(p); 21 | u = u * u * (3.0 - 2.0 * u); 22 | float res = mix(mix(rand(ip), rand(ip + vec2(1.0, 0.0)), u.x), mix(rand(ip + vec2(0.0, 1.0)), rand(ip + vec2(1.0, 1.0)), u.x), u.y); 23 | return res * res; 24 | } 25 | 26 | float fbm(vec2 x, int octaves) { 27 | float v = 0.0; 28 | float a = 0.5; 29 | vec2 shift = vec2(100); 30 | // Rotate to reduce axial bias 31 | mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50)); 32 | for (int i = 0; i < octaves; ++i) { 33 | v += a * noise(x); 34 | x = rot * x * 2.0 + shift; 35 | a *= 0.5; 36 | } 37 | return v; 38 | } 39 | 40 | float blendDarken(float base, float blend) { 41 | return min(blend, base); 42 | } 43 | 44 | vec3 blendDarken(vec3 base, vec3 blend) { 45 | return vec3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b)); 46 | } 47 | 48 | vec3 blendDarken(vec3 base, vec3 blend, float opacity) { 49 | return (blendDarken(base, blend) * opacity + base * (1.0 - opacity)); 50 | } 51 | 52 | void main() { 53 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 54 | 55 | if (frame == 1) { 56 | vec2 auv = abs(suv); 57 | float c = step(length(suv), 0.1); 58 | vec3 col = mix(vec3(1), vec3(0), c); 59 | outColor = vec4(col, 1.0); 60 | return; 61 | } 62 | 63 | float disp = fbm(suv * 15.0, 4) * 0.005; 64 | 65 | vec3 t1 = texture(backBuffer, uv).rgb; 66 | vec3 t2 = texture(backBuffer, uv + vec2(disp, 0.0) / asp).rgb; 67 | vec3 t3 = texture(backBuffer, uv - vec2(disp, 0.0) / asp).rgb; 68 | vec3 t4 = texture(backBuffer, uv + vec2(0.0, disp) / asp).rgb; 69 | vec3 t5 = texture(backBuffer, uv - vec2(0.0, disp) / asp).rgb; 70 | 71 | vec3 col = t1; 72 | col = blendDarken(col, t2, 0.65); 73 | col = blendDarken(col, t3, 0.65); 74 | col = blendDarken(col, t4, 0.65); 75 | col = blendDarken(col, t5, 0.65); 76 | 77 | outColor = vec4(col, 1.0); 78 | } 79 | 80 | //---------------------------- 81 | // Reference 82 | //---------------------------- 83 | // https://www.youtube.com/live/ggruH0fHPOM?si=M8GiPSTCQOTP_JXs 84 | // https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 85 | // https://github.com/jamieowen/glsl-blend/blob/master/darken.glsl -------------------------------------------------------------------------------- /src/20240304/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | 10 | in vec2 vUv; 11 | out vec4 outColor; 12 | 13 | #define loop(n) for(int i;i> 8 ^ x.yzx) * 0x456789ABu; 21 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 22 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 23 | return vec3(x) / vec3(-1u); 24 | } 25 | 26 | // Classic Perlin 2D Noise 27 | // by Stefan Gustavson 28 | // 29 | vec2 fade(vec2 t) { 30 | return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); 31 | } 32 | vec4 permute(vec4 x) { 33 | return mod(((x * 34.0) + 1.0) * x, 289.0); 34 | } 35 | 36 | float cnoise(vec2 P) { 37 | vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); 38 | vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); 39 | Pi = mod(Pi, 289.0); // To avoid truncation effects in permutation 40 | vec4 ix = Pi.xzxz; 41 | vec4 iy = Pi.yyww; 42 | vec4 fx = Pf.xzxz; 43 | vec4 fy = Pf.yyww; 44 | vec4 i = permute(permute(ix) + iy); 45 | vec4 gx = 2.0 * fract(i * 0.0243902439) - 1.0; // 1/41 = 0.024... 46 | vec4 gy = abs(gx) - 0.5; 47 | vec4 tx = floor(gx + 0.5); 48 | gx = gx - tx; 49 | vec2 g00 = vec2(gx.x, gy.x); 50 | vec2 g10 = vec2(gx.y, gy.y); 51 | vec2 g01 = vec2(gx.z, gy.z); 52 | vec2 g11 = vec2(gx.w, gy.w); 53 | vec4 norm = 1.79284291400159 - 0.85373472095314 * vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)); 54 | g00 *= norm.x; 55 | g01 *= norm.y; 56 | g10 *= norm.z; 57 | g11 *= norm.w; 58 | float n00 = dot(g00, vec2(fx.x, fy.x)); 59 | float n10 = dot(g10, vec2(fx.y, fy.y)); 60 | float n01 = dot(g01, vec2(fx.z, fy.z)); 61 | float n11 = dot(g11, vec2(fx.w, fy.w)); 62 | vec2 fade_xy = fade(Pf.xy); 63 | vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); 64 | float n_xy = mix(n_x.x, n_x.y, fade_xy.y); 65 | return 2.3 * n_xy; 66 | } 67 | 68 | void main() { 69 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 70 | 71 | suv *= 1.3; 72 | 73 | float r = 0.15, sm = 0.005, w = 0.0015, c; 74 | vec2 n = vec2(cnoise(suv * 7.0 + SEED), cnoise(suv.yx * 10.0 + SEED)) * 0.015; 75 | 76 | float rn = 50.0; 77 | for (float i = 0.0; i <= rn; i++) { 78 | vec3 h = h21(vec2(i), SEED); 79 | float s = 1.0 + step(h.x, 0.2) * h.y * 1.5; 80 | if (i == rn) s = 20.0; 81 | else if (mod(i, 15.0) == 0.0) s = 2.5; 82 | c += smoothstep(r, r + sm, length(suv + n)) * smoothstep(r + w * s + sm, r + w * s, length(suv + n)); 83 | r += 0.012; 84 | } 85 | 86 | vec3 b = vec3(1.00, 0.98, 0.95); 87 | vec3 col = mix(b, b * 0.92, c); 88 | 89 | outColor = vec4(col, 1.0); 90 | } 91 | 92 | //---------------------------- 93 | // Reference 94 | //---------------------------- 95 | // https://gardeneight.medium.com/anai-764dd1fc1dd6 96 | // https://anaiwood.com/en/brands/fil - credits -------------------------------------------------------------------------------- /src/20240213_2/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | 9 | in vec2 vUv; 10 | out vec4 outColor; 11 | 12 | #define loop(n) for(int i; i < n; i++) 13 | #define sat(v) clamp(v, 0.0, 1.0) 14 | 15 | const float PI = acos(-1.0); 16 | 17 | float lt, bt, tt; 18 | vec3 h; 19 | 20 | mat2 rot(float a) { 21 | float s = sin(a), c = cos(a); 22 | return mat2(c, s, -s, c); 23 | } 24 | 25 | vec3 hash(vec3 v) { 26 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 27 | x = (x >> 8 ^ x.zxy) * 0x457890ABu; 28 | x = (x >> 8 ^ x.zxy) * 0x7890AB45u; 29 | x = (x >> 8 ^ x.zxy) * 0x90AB4578u; 30 | return vec3(x) / vec3(-1u); 31 | } 32 | 33 | vec2 pmod(vec2 p, float r) { 34 | float n = PI * 2.0 / r; 35 | float a = atan(p.x, p.y) + n * 0.5; 36 | a = floor(a / n) * n; 37 | return rot(a) * p; 38 | } 39 | 40 | float box(vec3 p, vec3 b) { 41 | p = abs(p) - b; 42 | return length(max(p, 0.0)) + min(max(p.x, max(p.y, p.z)), 0.0); 43 | } 44 | 45 | float sdCross(vec3 p) { 46 | float da = max(p.x, p.y); 47 | float db = max(p.y, p.z); 48 | float dc = max(p.z, p.x); 49 | return min(da, min(db, dc)) - 1.0; 50 | } 51 | 52 | float sdf(vec3 p) { 53 | p = mod(p, 2.0) - 1.0; 54 | 55 | float b = box(p, vec3(1.0)); 56 | float s = 1.0; 57 | loop(3) { 58 | vec3 a = mod(p * s, 2.0) - 1.0; 59 | s *= 4.0; 60 | vec3 r = abs(1.0 - 4.0 * abs(a)); 61 | float c = sdCross(r) / s; 62 | b = max(b, c); 63 | } 64 | 65 | return b; 66 | } 67 | 68 | void main() { 69 | lt = time * 120.0 / 60.0; 70 | bt = floor(lt); 71 | tt = tanh(fract(lt) * 4.0); 72 | lt = bt + tt; 73 | float ft = fract(time); 74 | 75 | h = hash(vec3(bt)); 76 | 77 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 78 | 79 | suv.x += sin(suv.y * 1000.0 + ft * 100.0 ) * 0.005; 80 | vec2 fuv = floor(suv * vec2(1, 1.5) * 2.0); 81 | vec3 fh = hash(vec3(fuv + bt, floor(ft * 40.0))); 82 | if (fh.x < 0.1 && h.x < 0.9) suv.x += sign(fh.y) * 0.05; 83 | if (0.0 < mod(floor(suv.y * 0.7 - time * 0.5), 2.0)) suv.x += sign(fh.z) * 0.05; 84 | 85 | vec3 rd = normalize(vec3(suv, -5.0 + length(suv) * 2.0)), ro = vec3(0.0, 0.0, 7.0); 86 | 87 | float t, acc; 88 | loop(64) { 89 | vec3 p = rd * t + ro; 90 | if (h.x < 0.9) { 91 | p.y -= 0.1; 92 | p.z -= lt * 0.6; 93 | } else { 94 | p.xy *= rot(t * 0.5); 95 | p.z -= ft * 6.0; 96 | } 97 | float d = sdf(p); 98 | if (d < 1e-4 || 1e4 < t) break; 99 | t += d; 100 | acc += exp(abs(d) * -300.0); 101 | } 102 | 103 | float c; 104 | if (h.y < 0.8) c = acc / 64.0 * 0.5; 105 | else c = fwidth(acc) * 0.02; 106 | 107 | float sc = step(fract(suv.y * 40.0 - fract(time) * 10.0), 0.8); 108 | c += sc * 0.07; 109 | 110 | vec4 b = texture(backBuffer, vUv); 111 | vec3 col = vec3(sat(c), b.rg); 112 | col = mix(col, b.rgb, 0.5) * 1.08; 113 | 114 | outColor = vec4(col, 1.0); 115 | } 116 | 117 | //---------------------------- 118 | // Reference 119 | //---------------------------- 120 | // https://iquilezles.org/articles/menger/ -------------------------------------------------------------------------------- /src/scripts/Canvas.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | import { Three } from './core/Three' 3 | import vertexShader from './shader/quad.vs' 4 | import fragmentShader from './shader/output.fs' 5 | import { RawShaderMaterial } from './core/ExtendedMaterials' 6 | import { MainScene } from './MainScene' 7 | import { params } from './Params' 8 | import { mouse2d } from './Mouse2D' 9 | 10 | export class Canvas extends Three { 11 | private mainScene: MainScene 12 | private output: THREE.Mesh 13 | 14 | constructor(canvas: HTMLCanvasElement, mainFs: string, outputFs?: string) { 15 | super(canvas) 16 | this.mainScene = new MainScene(this.renderer, mainFs) 17 | this.output = this.createOutput(outputFs ?? fragmentShader) 18 | 19 | this.disableMatrixAutoUpdate() 20 | 21 | this.bindAssets().then(() => { 22 | window.addEventListener('resize', this.resize.bind(this)) 23 | this.renderer.setAnimationLoop(this.anime.bind(this)) 24 | }) 25 | } 26 | 27 | private async bindAssets() { 28 | const texturePath = params.texturePath 29 | if (texturePath) { 30 | const loader = new THREE.TextureLoader() 31 | const texture = await loader.loadAsync(texturePath) 32 | texture.wrapS = THREE.RepeatWrapping 33 | texture.wrapT = THREE.RepeatWrapping 34 | texture.userData.aspect = texture.source.data.width / texture.source.data.height 35 | Object.assign(this.mainScene.uniforms, { textureUnit: { value: texture } }) 36 | } 37 | 38 | const cubeMapPath = params.cubeMapPath 39 | if (cubeMapPath) { 40 | const loader = new THREE.CubeTextureLoader() 41 | loader.setPath(cubeMapPath) 42 | const texture = await loader.loadAsync(['px', 'nx', 'py', 'ny', 'pz', 'nz'].map((f) => f + '.webp')) 43 | Object.assign(this.mainScene.uniforms, { cubeTextureUnit: { value: texture } }) 44 | } 45 | } 46 | 47 | private createOutput(fs: string) { 48 | const geometry = new THREE.PlaneGeometry(2, 2) 49 | const material = new RawShaderMaterial({ 50 | uniforms: { 51 | source: { value: null }, 52 | resolution: { value: [this.size.width, this.size.height] }, 53 | mouse: { value: mouse2d.position }, 54 | time: { value: 0 }, 55 | frame: { value: 0 }, 56 | }, 57 | vertexShader, 58 | fragmentShader: fs, 59 | glslVersion: '300 es', 60 | }) 61 | const mesh = new THREE.Mesh(geometry, material) 62 | this.scene.add(mesh) 63 | return mesh 64 | } 65 | 66 | private disableMatrixAutoUpdate() { 67 | this.camera.matrixAutoUpdate = false 68 | this.scene.traverse((o) => (o.matrixAutoUpdate = false)) 69 | } 70 | 71 | private get uniforms() { 72 | return this.output.material.uniforms 73 | } 74 | 75 | private resize() { 76 | this.uniforms.resolution.value = [this.size.width, this.size.height] 77 | this.uniforms.time.value = 0 78 | this.uniforms.frame.value = 0 79 | this.mainScene.resize() 80 | } 81 | 82 | private anime() { 83 | if (params.enableStats) this.stats.update() 84 | this.updateTime() 85 | 86 | this.mainScene.render(this.time.delta) 87 | 88 | this.uniforms.source.value = this.mainScene.texture 89 | this.uniforms.mouse.value = mouse2d.position 90 | this.uniforms.time.value += this.time.delta 91 | this.uniforms.frame.value += 1 92 | this.render() 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/20240225/sketch.fs: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | 4 | uniform sampler2D backBuffer; 5 | uniform vec2 resolution; 6 | uniform vec2 mouse; 7 | uniform float time; 8 | uniform int frame; 9 | uniform sampler2D textureUnit; 10 | 11 | in vec2 vUv; 12 | out vec4 outColor; 13 | 14 | #define loop(n) for(int i; i < n; i++) 15 | #define grad(p, h) sdf(p + h) - sdf(p - h) 16 | 17 | const float PI = acos(-1.0); 18 | float lt, bt, tt; 19 | 20 | mat2 rot(float a) { 21 | float s = sin(a), c = cos(a); 22 | return mat2(c, s, -s, c); 23 | } 24 | 25 | float box(vec3 p, vec3 b) { 26 | p = abs(p) - b; 27 | return max(p.x, max(p.y, p.z)); 28 | } 29 | 30 | float gyroid(vec3 p, float s, float t, float b) { 31 | p *= s; 32 | p.xy *= rot(lt * 0.2); 33 | p.yz *= rot(lt * 0.2); 34 | p.zx *= rot(lt * 0.2); 35 | return abs(dot(sin(p), cos(p.zxy)) - b) / s - t; 36 | } 37 | 38 | vec3 transform(vec3 p) { 39 | p.xy *= rot(time * 0.1); 40 | p.yz *= rot(time * 0.1); 41 | p.zx *= rot(time * 0.1); 42 | return p; 43 | } 44 | 45 | vec3 hash(vec3 v) { 46 | uvec3 x = floatBitsToUint(v + vec3(0.1, 0.2, 0.3)); 47 | x = (x >> 8 ^ x.yzx) * 0x456789ABu; 48 | x = (x >> 8 ^ x.yzx) * 0x6789AB45u; 49 | x = (x >> 8 ^ x.yzx) * 0x89AB4567u; 50 | return vec3(x) / vec3(-1u); 51 | } 52 | 53 | mat3 orthbas(vec3 z) { 54 | z = normalize(z); 55 | vec3 up = abs(z.y) < 0.999 ? vec3(0, 1, 0) : vec3(0, 0, 1); 56 | vec3 x = normalize(cross(up, z)); 57 | return mat3(x, cross(z, x), z); 58 | } 59 | 60 | vec3 cyc(vec3 p) { 61 | mat3 b = orthbas(vec3(-3.0, 2.0, -1.0)); 62 | vec4 n; 63 | loop(8) { 64 | p *= b; 65 | p += sin(p.yzx); 66 | n = 2.0 * n + vec4(cross(cos(p), sin(p.zxy)), 1.0); 67 | p *= 2.0; 68 | } 69 | return n.xyz / n.w; 70 | } 71 | 72 | float sdf(vec3 p) { 73 | float d = 1e9, g; 74 | d = min(d, box(p, vec3(0.7))); 75 | p += cyc(p * 0.2) * 0.5; 76 | g = gyroid(p, 8.0, 0.03, 1.3); 77 | d = max(d, g * 0.5); 78 | return d; 79 | } 80 | 81 | void main() { 82 | vec2 uv = vUv, asp = resolution / min(resolution.x, resolution.y), suv = (uv * 2.0 - 1.0) * asp; 83 | vec3 rd = normalize(vec3(suv, -5.0)), ro = vec3(0.0, 0.0, 6.0); 84 | 85 | lt = time * 100.0 / 60.0; 86 | bt = floor(lt); 87 | tt = tanh(fract(lt) * 5.0); 88 | lt = bt + tt; 89 | 90 | float t; 91 | loop(64) { 92 | vec3 p = rd * t + ro; 93 | p = transform(p); 94 | float d = sdf(p); 95 | if (d < 1e-4 || 1e5 < t) break; 96 | t += d; 97 | } 98 | 99 | vec3 col; 100 | if (t < 1e5) { 101 | vec3 p = rd * t + ro; 102 | p = transform(p); 103 | 104 | vec2 h = vec2(1e-4, 0.0); 105 | vec3 n = normalize(vec3(grad(p, h.xyy), grad(p, h.yxy), grad(p, h.yyx))); 106 | 107 | vec3 l = normalize(transform(vec3(1, 1, 2))); 108 | float diff = clamp(dot(n, l), 0.2, 1.0); 109 | col = vec3(diff); 110 | 111 | vec3 uv3 = p * 0.5 + 0.5; 112 | vec3 colXZ = texture(textureUnit, uv3.xz).rgb; 113 | vec3 colYZ = texture(textureUnit, uv3.yz).rgb; 114 | vec3 colXY = texture(textureUnit, uv3.xy).rgb; 115 | 116 | n = abs(n); 117 | col *= colYZ * n.x + colXZ * n.y + colXY * n.z; 118 | } 119 | 120 | outColor = vec4(col, 1.0); 121 | } 122 | 123 | //---------------------------- 124 | // Reference 125 | //---------------------------- 126 | // https://youtu.be/VaYyPTw0V84?si=eVov17jGvBxXqfgg 127 | // https://youtu.be/-adHIyjIYgk?si=nkXdxIpaVjTkXhPt --------------------------------------------------------------------------------