JSFiddle - React, Tailwind, and code Playground
by Paul West
HTML
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.165.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.165.0/examples/jsm/"
}
}
</script>
CSS
body{
overflow: hidden;
margin: 0;
}
JavaScript
import * as THREE from "three";
import {
OrbitControls
} from "three/addons/controls/OrbitControls.js";
class Atlas extends THREE.CanvasTexture{
constructor(){
let c = document.createElement("canvas");
c.height = 128;
c.width = 128 * 6;
let u = (val) => val * c.height * 0.01;
let ctx = c.getContext("2d");
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, c.width, c.height);
let letters = [..."АБВГДЕ"];
ctx.fillStyle = "#000";
ctx.font = `bold ${u(80)}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
letters.forEach((l, lIdx) => {
ctx.fillText(l, (0.5 + lIdx) * 128, 64);
})
super(c);
this.colorSpace = "srgb";
this.anisotropy = renderer.capabilities.getMaxAnisotropy();
}
}
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0, 10);
let renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
let g = new THREE.PlaneGeometry();
let m = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: new Atlas(),
onBeforeCompile: shader => {
shader.uniforms.atlasSize = {value: new THREE.Vector2(6, 1)}
shader.vertexShader = `
uniform vec2 atlasSize;
attribute vec2 uvOffset;
${shader.vertexShader}
`.replace(
`#include <uv_vertex>`,
`#include <uv_vertex>
vMapUv = ( mapTransform * vec3( (MAP_UV + uvOffset) / atlasSize, 1 ) ).xy;
`
);
console.log(shader.vertexShader);
}
})
let amount = 100;
let io = new THREE.InstancedMesh(g, m, amount);
let uvOffset = [];
let dummy = new...