Instanced mesh, psuedo-decal paint-trail

Draw on a mesh similarly to decal geometry, but with instanced spheres.

by notchris

CSS

* {
    box-sizing: border-box;
    text-rendering: optimizeLegibility;
    font-kerning: auto;
    outline: none;
}

html {
    font-family: sans-serif;
}

body {
    margin: 0;
}

JavaScript

import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import {
  OrbitControls
} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";

import {
  RoundedBoxGeometry
} from 'https://cdn.skypack.dev/three@0.136.0/examples/jsm/geometries/RoundedBoxGeometry.js';


let renderer, scene, camera, controls, mesh, normal, line, decalMaterial, decalMesh
let angle = 0
let raycaster = new THREE.Raycaster()
let mouse = new THREE.Vector2()
let axis = new THREE.Vector3()

let vA = new THREE.Vector3();
let vB = new THREE.Vector3();
let vC = new THREE.Vector3();
let vnorm = new THREE.Vector3();
let count = 0;

let mouseHelper = new THREE.Mesh(new THREE.BoxBufferGeometry(1, 1, 10), new THREE.MeshNormalMaterial());
mouseHelper.visible = false;

const position = new THREE.Vector3();
const orientation = new THREE.Euler();
const size = new THREE.Vector3(4, 4, 4);
const decals = [];

const intersection = {
  intersects: false,
  point: new THREE.Vector3(),
  normal: new THREE.Vector3()
};
let intersects = [];
init()
animate()

function init() {

  // renderer
  renderer = new THREE.WebGLRenderer({
    antialias: true
  })
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  renderer.domElement.addEventListener("pointermove", onMouseMove)

  // scene
  scene = new THREE.Scene()

  // ambient light
  let ambient = new THREE.AmbientLight(0x404040)
  scene.add(ambient)

  // directional light
  let directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
  directionalLight.position.set(10, 10, 10)
  scene.add(directionalLight)

  // camera
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.z = 120;

  controls = new OrbitControls(camera, renderer.domElement)

  decalMaterial = new THREE.MeshBasicMaterial({
    color: 0xffffff
  })


  // material
  let material = new...