JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="x-shader/x-vertex" id="vert">
attribute vec3 offset;
attribute vec2 uvOffset;
attribute vec2 uvScale;
varying vec2 vUv;
void main() {

    vUv = uvOffset + uv * uvScale;
    
    vec2 scale = vec2( 20.0 ); // create a uniform for this
    
    vec2 alignedPosition = ( ( position.xy * scale ) + offset.xy );

    //vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
    vec4 mvPosition = vec4( modelViewMatrix[3][0], modelViewMatrix[3][1], modelViewMatrix[3][2], modelViewMatrix[3][3] );
    mvPosition.xy += alignedPosition;

    gl_Position = projectionMatrix * mvPosition;
    
}</script>

<script type="x-shader/x-fragment" id="frag">
  precision highp float;

  varying vec2 vUv;

  uniform sampler2D texture;
  uniform vec3 textColor;
  uniform vec3 outlineColor;
  uniform float outlineDistance;
  uniform float opacity;

  float aastep(float base, float value) {
    #ifdef GL_OES_standard_derivatives
    float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
    #else
    float afwidth = (1.0 / 32.0) * (1.4142135623730951 / (2.0 * gl_FragCoord.w));
    #endif
    return smoothstep(base - afwidth, base + afwidth, value);
  }

  void main() {
    float distance = texture2D(texture, vUv).a;
    float outlineFactor = aastep(0.5, distance);
    vec3 color = mix(outlineColor, textColor, outlineFactor);
    float alpha = aastep(outlineDistance, distance);
    gl_FragColor = vec4(color, opacity * alpha);
    if (gl_FragColor.a < 0.0001) discard;
  }
</script>

JavaScript

// a basic three.js scene

var container, renderer, scene, camera, controls;

init();
animate();

function init() {

    // renderer
    renderer = new THREE.WebGLRenderer({
        antialias: false
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0xccccff);
    container = document.createElement('div');
    document.body.appendChild(container);
    container.appendChild(renderer.domElement);

    // scene
    scene = new THREE.Scene();

    // camera
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.set(0, 200, 800);
    //camera.lookAt(scene.position);
    scene.add(new THREE.CameraHelper(camera));
    

    //instances geometry
    var geometry = new THREE.InstancedBufferGeometry();
    
    var vertices = new Float32Array( [
			- 0.5, - 0.5, 0,
			  0.5, - 0.5, 0,
			  0.5, 0.5, 0,
			- 0.5, 0.5, 0
		] );
    
    var uvs = new Float32Array( [
			 0, 0,
			 1, 0,
			 1, 1,
			 0, 1
		] );
    
    geometry.addAttribute("position", new THREE.Float32BufferAttribute( vertices, 3 ) );
    geometry.addAttribute("uv", new THREE.Float32BufferAttribute( uvs, 2 ) );
    geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] );
    
    

  var count = 3;
  var offsets = new Float32Array(count * 3);
  var uvOffset = new Float32Array(count * 2);
  var uvScales = new Float32Array(count * 2);

  //iterators
  var offsetIterator = 0;
  var uvOffsetIterator = 0;
  var uvScalesIterator = 0;
  
  var cX = 389;
  var cY = 109;
  var cWidth = 25;
  var cHeight = 28;
  var left = cX / 512;
  var top = (512 - (cY + cHeight)) / 512;

  for (let i = 0; i < count; i++) {
    offsets[offsetIterator++] = 100 + (19) * i;
    offsets[offsetIterator++] = 50;
    offsets[offsetIterator++] = 0.0;

    uvOffset[uvOffsetIterator++] = left;
    uvOffset[uvOffsetIterator++] = top;

    uvScales[uvScalesIterator++] = cWidth / 512;
    uvScales[uvScalesIterator++] = cHeight / 512;  
  }
  
  
  


 ...