├── .gitattributes ├── public └── favicon.ico ├── src ├── shaders │ ├── vertex.glsl │ ├── ascii-vertex.glsl │ ├── fragment.glsl │ └── ascii-fragment.glsl ├── js │ └── main.js └── styles │ └── styles.css ├── vite.config.js ├── package.json ├── .gitignore ├── README.md ├── LICENSE └── index.html /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrico1234/codrops-ascii-ogl/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/shaders/vertex.glsl: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | in vec2 uv; 3 | in vec2 position; 4 | out vec2 vUv; 5 | void main() { 6 | vUv = uv; 7 | gl_Position = vec4(position, 0., 1.); 8 | } -------------------------------------------------------------------------------- /src/shaders/ascii-vertex.glsl: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | in vec2 uv; 3 | in vec2 position; 4 | out vec2 vUv; 5 | void main() { 6 | vUv = uv; 7 | gl_Position = vec4(position, 0., 1.); 8 | } 9 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | export default defineConfig({ 4 | root: '.', 5 | base: './', 6 | build: { 7 | outDir: 'dist', 8 | sourcemap: true 9 | }, 10 | server: { 11 | open: true, 12 | port: 3000 13 | }, 14 | resolve: { 15 | alias: { 16 | '@': '/src' 17 | } 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codrops-ascii-ogl", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "serve": "vite preview" 10 | }, 11 | "dependencies": { 12 | "ogl": "^0.0.29", 13 | "resolve-lygia": "^1.0.2", 14 | "tweakpane": "^2.1.0", 15 | "vite": "^4.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Node.js dependencies 2 | node_modules/ 3 | 4 | # Ignore build output 5 | dist/ 6 | 7 | # Ignore local environment settings 8 | .env 9 | .env.*.local 10 | 11 | # Ignore Vite cache 12 | .vite/ 13 | 14 | # Ignore log files 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Ignore MacOS system files 20 | .DS_Store 21 | 22 | # Ignore IDE/editor settings 23 | .idea/ 24 | .vscode/ 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | 30 | # Ignore any temporary files or scratch files 31 | *.tmp 32 | *.temp 33 | -------------------------------------------------------------------------------- /src/shaders/fragment.glsl: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision mediump float; 3 | uniform float uFrequency; 4 | uniform float uTime; 5 | uniform float uSpeed; 6 | uniform float uValue; 7 | in vec2 vUv; 8 | out vec4 fragColor; 9 | 10 | #include "lygia/generative/cnoise.glsl" 11 | 12 | vec3 hsv2rgb(vec3 c) { 13 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 14 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 15 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 16 | } 17 | 18 | void main() { 19 | float hue = abs(cnoise(vec3(vUv * uFrequency, uTime * uSpeed))); 20 | vec3 rainbowColor = hsv2rgb(vec3(hue, 1.0, uValue)); 21 | fragColor = vec4(rainbowColor, 1.0); 22 | } 23 | -------------------------------------------------------------------------------- /src/shaders/ascii-fragment.glsl: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | precision highp float; 3 | uniform vec2 uResolution; 4 | uniform sampler2D uTexture; 5 | out vec4 fragColor; 6 | 7 | float character(int n, vec2 p) { 8 | p = floor(p * vec2(-4.0, 4.0) + 2.5); 9 | if(clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) { 10 | int a = int(round(p.x) + 5.0 * round(p.y)); 11 | if(((n >> a) & 1) == 1) return 1.0; 12 | } 13 | return 0.0; 14 | } 15 | 16 | void main() { 17 | vec2 pix = gl_FragCoord.xy; 18 | vec3 col = texture(uTexture, floor(pix / 16.0) * 16.0 / uResolution.xy).rgb; 19 | float gray = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b; 20 | int n = 4096; 21 | if(gray > 0.2) n = 65600; 22 | if(gray > 0.3) n = 163153; 23 | if(gray > 0.4) n = 15255086; 24 | if(gray > 0.5) n = 13121101; 25 | if(gray > 0.6) n = 15252014; 26 | if(gray > 0.7) n = 13195790; 27 | if(gray > 0.8) n = 11512810; 28 | vec2 p = mod(pix / 8.0, 2.0) - vec2(1.0); 29 | col = col * character(n, p); 30 | fragColor = vec4(col, 1.0); 31 | } 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ASCII Shader with OGL 2 | 3 | Demo for the tutorial on how to create an ASCII art animation using OGL. 4 | 5 |  6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=82209) 8 | 9 | [Demo](https://tympanus.net/Tutorials/ascii-shader-ogl/) 10 | 11 | ## Installation 12 | 13 | ```sh 14 | npm install 15 | ``` 16 | 17 | ## Build and Run 18 | ```sh 19 | npm run dev 20 | ``` 21 | or 22 | ```sh 23 | npm run build 24 | ``` 25 | 26 | ## Misc 27 | 28 | Follow Andrico: [Twitter](https://x.com/AndricoKaroulla), [LinkedIn](https://www.linkedin.com/in/andrico-karoulla/), [GitHub](https://github.com/andrico1234) 29 | 30 | Follow Codrops: [Bluesky](https://bsky.app/profile/codrops.bsky.social), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/), [X](http://www.x.com/codrops) 31 | 32 | ## License 33 | [MIT](LICENSE) 34 | 35 | Made with :blue_heart: by [Andrico](https://x.com/AndricoKaroulla) and [Codrops](http://www.codrops.com) 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2009 - 2024 [Codrops](https://tympanus.net/codrops) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |