JSFiddle - React, Tailwind, and code Playground
by tfoller
HTML
<canvas id="main_canvas" width="500" height="500"></canvas>
<script type="x-shader/x-vertex" id="vs_imesh">
#ifdef USE_INSTANCING_COLOR
attribute vec3 instanceRGID;
#endif
varying vec3 vrgID;
varying vec3 vColor;
void main() {
vec4 pos = vec4(position, 1.0);
#ifdef USE_INSTANCING
pos = instanceMatrix * pos;
#endif
gl_Position = projectionMatrix * modelViewMatrix * pos;
#ifdef USE_INSTANCING_COLOR
vColor = instanceColor;
vrgID = instanceRGID;
#else
vColor = vec3(1.0);
vrgID = vec3(1.0);
#endif
}
</script>
<script type="x-shader/x-fragment" id="fs_imesh">
varying vec3 vColor;
varying vec3 vrgID;
void main() {
gl_FragColor = vec4(vrgID + vColor, 1.0);
}
</script>
CSS
@import url("https://alikim.com/_v1_jsm/css/controls.css");
JavaScript
import * as THREE from 'https://unpkg.com/three/build/three.module.js'
import {
quaternFromETh
} from 'https://alikim.com/_v1_jsm/geometry.js'
import GMRNG from 'https://alikim.com/_v1_jsm/rng.js'
import * as CONTROLS from 'https://alikim.com/_v1_jsm/controls.js'
const get = id => document.getElementById(id);
const getShader = (uiObj, id) => {
let src = get(id).textContent;
src = src.replace(/#include '([^']+)'/g,
function() {
const $1 = arguments[1];
const elem = get($1);
if (!elem) console.error(`include shader '${$1}' not found`);
return elem.textContent;
});
return src;
};
const canvas = get('main_canvas');
const [w, h] = [canvas.width, canvas.height];
const renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: canvas,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(w, h);
const [near, far] = [1, 100];
const mid = -0.5 * (near + far);
const camera = new THREE.PerspectiveCamera(45, w / h, near, far);
camera.position.set(3, 4, 3);
camera.lookAt(0, 0, 0);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0.01, 0.01, 0.15);
const geo = new THREE.CylinderGeometry(0.5, 0.7, 1, 6);
const mat = new THREE.ShaderMaterial({
uniforms: {
},
vertexShader: getShader({}, 'vs_imesh'),
fragmentShader: getShader({}, 'fs_imesh')
});
const size = 3;
const imesh = new THREE.InstancedMesh(geo, mat, size);
const mtx = new THREE.Matrix4();
const e = [1, 0, 0];
for (let i = 0; i < size; i++) {
const q = quaternFromETh(e, Math.PI / 8 * i);
const sc = new THREE.Vector3(1, 1 - i * 0.2, 1);
mtx.compose(
new THREE.Vector3(0, 0, 0).add(new THREE.Vector3(0, 0, i)),
new THREE.Quaternion(q[1], q[2], q[3], q[0]),
sc);
imesh.setMatrixAt(i, mtx);
imesh.setColorAt(i, new THREE.Color(i / 4, 1 - i / 4, 1));
}
const rgID = [0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5];
imesh.geometry.setAttribute('instanceRGID',
new THREE.InstancedBufferAttribute(new Float32Array(rgID),...