19
\$\begingroup\$

I'm trying to create an Easter egg for a 3D game in Unity3D. I want to render my game momentarily in ASCII art.

My first idea is to create a shader to do that, but I'm not sure if it's the right way.

\$\endgroup\$
  • \$\begingroup\$ with libAA or libCACA ( link1 - link2 resp.) \$\endgroup\$ – v.oddou Aug 5 '15 at 8:11
20
\$\begingroup\$

I don't know of any plug and play solutions for it, but here is an algorithm that works in the pixel shader with just a texture as extra assets.

The asset required is a small texture with a single row of some number of tiles, where the left most is the darkest and the right most the lightest.

What happens then is (per frame):

  • Take the buffer you want to make an ASCII version of and downscale it by the tile size (so if you have 8x8 tiles the image will be scaled down by 8 in both dimensions).
  • Create a new render target of the original full sized buffer.
  • Use a pixel shader with the following:
    • A sampler input for the buffer (with sampling set to nearest neighbor), and a sampler input for the tiles.
    • Uniforms for the tile size, amount of tiles and final output resolution
  • The pixel shader should then:
    • Get the gray scale value from the downscaled buffer ( (col.r+col.g+col.b) / 3.0 is probably sufficient, even though that isn't quite how eyes work)
    • Use this information to get which tile you want to render from (floor(grayscale * TILE_COUNT))
    • Calculate the pixel X/Y coordinates of the output and take those module the tile size (tileX/tileY).
    • Return as color the value sampled from the tile buffer at vec2( whichTile * TILE_WIDTH + tileX, tileY ) / vec2( TILE_WIDTH * TILE_COUNT, TILE_HEIGHT )

The linked page has several images of examples, one thing I'd consider adding would be a slight bit of noise to the calculated grayscale value so it's not one big block of MMMMMMMMMMMMMMMMs

Updated: @Lokkij in the gamedev chatroom posted a more complete tutorial for Unity: http://pentahelix.github.io/ASCII-Tutorial-Revisited/

\$\endgroup\$
  • \$\begingroup\$ Simple solution that could work pretty well (+1). Now I'm thinking about implementing this effect myself. \$\endgroup\$ – Paul Manta Nov 28 '14 at 19:21
  • 2
    \$\begingroup\$ @Sata In reference to Kevin's comment that "[this] isn't quite how eyes work", here's a description of multiple ways to convert a colored image to greyscale: johndcook.com/blog/2009/08/24/… \$\endgroup\$ – Paul Manta Nov 28 '14 at 19:23
  • 1
    \$\begingroup\$ You can expand this to include additional parameters like edge detection, to select characters based on their shape in addition to density/brightness. \$\endgroup\$ – DMGregory Nov 28 '14 at 20:32
  • \$\begingroup\$ Additionally, there was an article about doing something similar in XNA. \$\endgroup\$ – XNargaHuntress Dec 1 '14 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.