naive rasterizer

go back

example cow.obj or f-16.obj

result (small because its slow):
src
const input = document.getElementById('input')
const canvas = document.getElementById('canvas')

const ctx = canvas.getContext('2d', { willReadFrequently: true })
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)

const v1 = (event) =>
  withFile(event.target.files[0], (file) => {
    ctx.fillStyle = 'black'
    ctx.fillRect(0, 0, canvas.width, canvas.height)

    const obj = parseObj(file)
    const boundingBox = boundObj(obj)
    const adjustmentScalar = objAdjustmentScalar(
      canvas.width,
      canvas.height,
      boundingBox
    )

    const scaleAdjustedObj = scaledObj(obj, [
      adjustmentScalar,
      adjustmentScalar,
      adjustmentScalar,
    ])
    const scaledBoundingBox = boundObj(scaleAdjustedObj)
    const adjustmentTranslation = objAdjustmentTranslation(
      canvas.width,
      canvas.height,
      scaledBoundingBox
    )

    const centeredObj = translatedObj(scaleAdjustedObj, adjustmentTranslation)
    const translated = centeredObj.verts.flat(1)

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    const data = imageData.data

    for (let i = 0; i < translated.length; i += 9) {
      const vert1 = [
        translated[0 + i + 0],
        translated[0 + i + 1],
        translated[0 + i + 2],
      ]
      const vert2 = [
        translated[3 + i + 0],
        translated[3 + i + 1],
        translated[3 + i + 2],
      ]
      const vert3 = [
        translated[6 + i + 0],
        translated[6 + i + 1],
        translated[6 + i + 2],
      ]
      for (let y = 0; y < canvas.height; ++y) {
        for (let x = 0; x < canvas.width; ++x) {
          const barycentricCoordinate = barycentricCoordinates(
            [x, y],
            [vert1, vert2, vert3].flat()
          )

          if (
            barycentricCoordinate[0] >= 0.0 &&
            barycentricCoordinate[1] >= 0.0 &&
            barycentricCoordinate[2] >= 0.0
          ) {
            const _y = canvas.height - y - 1
            data[0 + (x + _y * canvas.width) * 4] = 255
            data[1 + (x + _y * canvas.width) * 4] = 255
            data[2 + (x + _y * canvas.width) * 4] = 255
            data[3 + (x + _y * canvas.width) * 4] = 255
          }
        }
      }
    }
    ctx.putImageData(imageData, 0, 0)
  })

input.addEventListener('change', v1)