Instanced + properties

HTML

<canvas id="main_canvas" style="border: solid 1px red;" width=400 height=300></canvas>

CSS

body {
  background: #000;
}

JavaScript

import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.126/build/three.module.js'
import UTL from 'https://alikim.com/jsm/utils.module.js'

const genRNG = (n, beg = 0, end = 1) => {
    const mult = end - beg;
    const shft = beg;
    const rng = [];
    for (let i = 0; i < n; i++) rng[i] = shft + mult * UTL.rndF();
    return rng;
}

const renderer = new THREE.WebGLRenderer({
  antialias: false,
  alpha: true,
  canvas: document.querySelector('#main_canvas'),
});
renderer.setPixelRatio(window.devicePixelRatio);

const [cw, ch] = [400, 300];
const camera = new THREE.OrthographicCamera(-cw / 2, cw / 2, ch / 2, -ch / 2, 0, 100);

const str_num = 20;
const mat = new THREE.MeshBasicMaterial();
const geo = new THREE.SphereGeometry(1, 16, 16);
const stars = new THREE.InstancedMesh(geo, mat, str_num);

const [sz, h, s, v, op] = [[1.5, 3], [0, 1], [0.5, 1], [0.5, 1], [0.2, 1]];

const str_pos = { x: genRNG(str_num, -cw/2, cw/2), y: genRNG(str_num, -ch/2, ch/2) };
const str = {};
const prs = ['sz', 'h', 's', 'v', 'op'];
prs.forEach(p => { str[p] = genRNG(str_num, eval(p)[0], eval(p)[1]) });

const matrix = new THREE.Matrix4();
const color = new THREE.Color();
for (let j = 0; j < str_num; j++) {
	color.fromArray(UTL.HSVtoRGB(str.h[j], str.s[j], str.v[j]))
  const sc = str.sz[j];
  matrix.makeScale(sc, sc, sc).setPosition(str_pos.x[j], str_pos.y[j], -10);
  stars.setMatrixAt(j, matrix);
	stars.setColorAt(j, color);
}

const scene = new THREE.Scene().add(stars);

const lightD = new THREE.DirectionalLight(0xffffff, 1);
lightD.position.set(20, 30, 100);
scene.add(lightD);

renderer.render(scene, camera);