three.js dev template - module

by orion_prime

HTML

<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
    
<script type="importmap">
	{
		"imports": {
			"three": "https://unpkg.com/[email protected]/build/three.module.js",
      "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
		}
	}
</script>

CSS

body {
	background-color: #000;
	margin: 0px;
	overflow: hidden;
}

JavaScript

import * as THREE from 'three';
import {
  OrbitControls
} from 'three/addons/controls/OrbitControls.js';
import {
  GLTFLoader
} from 'three/addons/loaders/GLTFLoader.js';

/**
 * You can use this geometry to create a decal mesh, that serves different kinds of purposes.
 * e.g. adding unique details to models, performing dynamic visual environmental changes or covering seams.
 *
 * Constructor parameter:
 *
 * mesh — Any mesh object
 * position — Position of the decal projector
 * orientation — Orientation of the decal projector
 * size — Size of the decal projector
 *
 * reference: http://blog.wolfire.com/2009/06/how-to-project-decals/
 *
 */

class DecalGeometry extends THREE.BufferGeometry {

  constructor(camera, mesh, position, orientation, size) {

    super();

    // buffers

    var vertices = [];
    var normals = [];
    var uvs = [];

    // helpers

    var plane = new THREE.Vector3();

    // this matrix represents the transformation of the decal projector

    var projectorMatrix = new THREE.Matrix4();
    projectorMatrix.makeRotationFromEuler(orientation);
    projectorMatrix.setPosition(position);

    var projectorMatrixInverse = new THREE.Matrix4();
    projectorMatrixInverse.copy(projectorMatrix).invert();

    var viewDirection = new THREE.Vector3();

    // generate buffers

    generate();

    // build geometry

    this.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
    this.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
    this.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));

    function generate() {

      var i;
      var geometry = new THREE.BufferGeometry();
      var decalVertices = [];

      var vertex = new THREE.Vector3();
      var normal = new THREE.Vector3();

      // handle different geometry types

      if (mesh.geometry.isGeometry) {

        geometry.fromGeometry(mesh.geometry);

      } else {

        geometry.copy(mesh.geometry);

      }

     ...