 Very simple shader utilising the same method that I used in the Lemminvade and Flappy Bird shader to draw the pixel images (WebGL, pure fragment shader, sourcecode on Shadertoy).

This shader is now part of pixi.js, a  2D webGL framework for JavaScript.

Related Topics:

## 5 thoughts on “Ascii Art Shader”

1. asciiRenderQ&A

Hi, I'm a student from south korea. I was searching for ascii rendering and I found your work. It is pretty awsome so I tried it out for myself. However, I'm kind of having some trouble of understanding your source code. I can understand the bitmap value from the previous comments, but the rest of the code is hard to understand. For example, I don't get of the equation of this:
```vec2 p = mod(uv/4.0, 2.0) - vec2(1.0); if (iMouse.z > 0.5) col = gray*vec3(character(n, p)); else col = col*character(n, p);```

or this:
```p = floor(p*vec2(4.0, -4.0) + 2.5); if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) { if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0; }```

Can you explain me what are these codes used for??
Thanks.

1. movAX13h

Post author

Hi!
I'm glad if I can help!

line 32:
`vec2 p = mod(uv/4.0, 2.0) - vec2(1.0);`
This splits the area into pieces of 8x8px and normalizes to values from -1 to +1.
If you change the second value of the mod call (from 2.0 to 4.0 for example), you will see what it does.

lines 8-12:
```p = floor(p*vec2(4.0, -4.0) + 2.5); if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) { if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0; }```

First p gets scaled to match our character width and height and shifted to a positive region. p.y is inverted (-4.0) because the characters are encoded in this order.
The if-clamp-line (9) is just a simple way of checking if p.x and p.y are in the range of 0.0 to 4.0.
The most complicated line 11 is calculating the binary AND this way because GLSL ES did not support the AND bit operation back then so I am using: `(n/2^k)%2`, assuming n and k integer which in GLSL is: `mod(n/(pow(2.0,k)),2.0)`

This could be simplified because the &-operator is supported now.

I hope that helped to understand the code. Feel free to ask if you have more questions.

2. itstilldoesntmatter

Hey, massive THANK YOU! For the code and for the really quick answer on Shadertoy. Still I couldn't find your e-mail, so I'm writing here hehe. To be honest, I'm a multimedia artist but I started to learn using software not so long ago, so I'm not sure if I will reach the point when I will be able to write a complete shader. Anyway, for now I hope you wont mind if I'll use your code as a part of the visualisation of my digital performance:)) And also I really liked that you gave me just a hint so I had to get to know this bitmap process a little closer.

1. movAX13h

Post author

Hi, you're welcome. I hope you have seen the link to the little tool that does the bitmapping for you. Just in case, here's the link again: http://www.thrill-project.com/archiv/coding/bitmap/

"Bitmap" is exactly what it is. Since the characters are monochrome, 1 bit is enough to describe 1 pixel. A number in a shader consists of 32bits but only about 25 can be safely used for the mapping process because of precision issues. This means that we can encode 5x5 pixels in these 25 bits (1 number). And this is what the shader does.

1. itstilldoesntmatter

Thank you for the explanation and the tool. I got to the answer pretty intuitively when I opened your bitmapping link, well maybe also after reading a little:)