Ascii3D is a text-based 3D rendering library for JavaScript and TypeScript.
Install via npm:
npm install ascii3d
A 3D meshes consists of vertices, paired in threes to form triangles.
const vertices = [
// X Y R G B CharCode
[-.5, -.5, 1.0, 1.0, 0.0, "#".charCodeAt(0)],
[-.5, 0.5, 0.0, 1.0, 1.0, "#".charCodeAt(0)],
[0.5, 0.5, 1.0, 0.0, 1.0, "#".charCodeAt(0)],
[0.5, -.5, 1.0, 1.0, 0.0, "#".charCodeAt(0)],
];
const indices = [
0, 1, 2, // triangle 1
0, 2, 3, // triangle 2
]
A vertex shader is responsible for interpreting vertices. Pixel data is interpolated for each point inside the triangle and sent to the pixel shader.
function vertexShader([x, y, r, g, b, charCode]) {
const clipspacePosition = [x, y, 0, 1];
const pixel = [r, g, b, charCode];
return new VertexData(clipspacePosition, pixel);
}
A pixel shader is responsible for interpreting pixels provided by the vertex shader.
function vertexShader([r, g, b, charCode]) {
return new PixelData(charCode, r, g, b, 1);
}
A render buffer is a 2D array of pixels with depth information. They contain the result of draw calls.
// create buffer
const width = 30, height = 30;
const renderBuffer = new RenderBuffer(width, height);
// draw a triangle
const doDepthTesting = true;
renderBuffer.drawTriangle(vertices, indices, vertexShader, pixelShader, doDepthTesting);
// sample as a texture
const u = .5, v = .5;
renderBuffer.sample2D(u,v);
One way to display a render buffer is through an HTML canvas element.
renderBuffer.renderToCanvas(
ctx, // CanvasRenderingContext2D
letterSpacing, // letter spacing
0, 0 // optional: start position (from bottom left)
);
Special thanks to:
- ASCIICKER for inspiring this project.
- Sessamekesh for the models adapted for the demos.
- This Stack Overflow thread for holding my hand through the maths.
Licensed under MIT.
All files can be used for commercial or non-commercial purposes. Do not resell. Attribution is appreciated but not due.