Permalink
Switch branches/tags
Nothing to show
Find file Copy path
d02fb73 Sep 17, 2018
1 contributor

Users who have contributed to this file

159 lines (130 sloc) 5.44 KB
import THREE from '../third_party/three.js';
import { renderer, getOrthoCamera } from '../modules/three.js';
import Maf from '../modules/maf.js';
import { palette2 as palette } from '../modules/floriandelooij.js';
import OrbitControls from '../third_party/THREE.OrbitControls.js';
import { InstancedGeometry, getInstancedMeshStandardMaterial, getInstancedDepthMaterial } from '../modules/instanced.js';
import { gradientLinear } from '../modules/gradient.js';
import RoundedExtrudedPolygonGeometry from '../modules/three-rounded-extruded-polygon.js';
import easings from '../modules/easings.js';
import Painted from '../modules/painted.js';
const painted = Painted(renderer, { minLevel: -.1 });
palette.range = ["#FE910F", "#A30F0B", "#D8180A", "#D2670D", "#FE910F"];
const canvas = renderer.domElement;
const camera = getOrthoCamera(1, 1);
const controls = new OrbitControls(camera, canvas);
const scene = new THREE.Scene();
const group = new THREE.Group();
const gradient = new gradientLinear(palette.range);
const geometry = new RoundedExtrudedPolygonGeometry(.5, .25, 6, 1, .05, .05, 4);
const mRot = new THREE.Matrix4().makeRotationX(Math.PI / 2);
geometry.applyMatrix(mRot);
const material = getInstancedMeshStandardMaterial({ color: 0xffffff, metalness: .1, roughness: .4 }, { colors: true });
const depthMaterial = getInstancedDepthMaterial();
const instancedGeometry = new InstancedGeometry(geometry, { colors: true });
const instancedMesh = new THREE.Mesh(instancedGeometry.geometry, material);
instancedMesh.frustumCulled = false;
instancedMesh.castShadow = true;
instancedMesh.receiveShadow = true;
instancedMesh.customDepthMaterial = depthMaterial;
group.add(instancedMesh);
const posValues = instancedGeometry.positions.values;
const quatValues = instancedGeometry.quaternions.values;
const scaleValues = instancedGeometry.scales.values;
const colorValues = instancedGeometry.colors.values;
const RINGS = 10;
let OBJECTS = 0;
let ptr = 0;
const data = [];
for (let j = 0; j < RINGS; j++) {
const parts = Math.max(1, 6 * j);
for (let p = 0; p < parts; p++) {
const a = p * Maf.TAU / parts;
const aa = Maf.mod(a, Maf.TAU / 6);
const r = (Math.sqrt(3) * j) / (Math.sqrt(3) * Math.cos(aa) + Math.sin(aa));
const x = r * Math.cos(a + Maf.TAU / 12);
const y = r * Math.sin(a + Maf.TAU / 12);
posValues[ptr * 3] = x;
posValues[ptr * 3 + 1] = 0;
posValues[ptr * 3 + 2] = y;
scaleValues[ptr * 3] = 1;
scaleValues[ptr * 3 + 1] = 1;
scaleValues[ptr * 3 + 2] = 1;
quatValues[ptr * 4] = 0;
quatValues[ptr * 4 + 1] = 0;
quatValues[ptr * 4 + 2] = 0;
quatValues[ptr * 4 + 3] = 1;
colorValues[ptr * 4] = .5;
colorValues[ptr * 4 + 1] = .5;
colorValues[ptr * 4 + 2] = .5;
colorValues[ptr * 4 + 3] = 1;
data.push({ r: j, a });
ptr++;
OBJECTS++;
}
}
instancedGeometry.update(OBJECTS);
group.scale.setScalar(.1);
scene.add(group);
const directionalLight = new THREE.DirectionalLight(0xffffff, .5);
directionalLight.position.set(-2, 2, 2);
directionalLight.castShadow = true;
directionalLight.shadow.camera.near = -1;
directionalLight.shadow.camera.far = 10;
scene.add(directionalLight);
const directionalLight2 = new THREE.DirectionalLight(0xffffff, .5);
directionalLight2.position.set(1, 2, 1);
directionalLight2.castShadow = true;
directionalLight2.shadow.camera.near = -4;
directionalLight2.shadow.camera.far = 10;
scene.add(directionalLight2);
const ambientLight = new THREE.AmbientLight(0x808080, .5);
scene.add(ambientLight);
const light = new THREE.HemisphereLight(palette.range[0], palette.range[1], .5);
scene.add(light);
camera.position.set(.1, 1, 0);
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer.setClearColor(palette.range[0], 1);
scene.fog = new THREE.FogExp2(palette.range[0], 0.065);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
const loopDuration = 2;
const q = new THREE.Quaternion();
const ARMS = 6;
function draw(startTime) {
const time = (.001 * (performance.now() - startTime)) % loopDuration;
const t = time / loopDuration;
for (let ptr = 0; ptr < OBJECTS; ptr++) {
const r = data[ptr].r;
const v = .5 + .5 * Math.sin(.5 * r + t * Maf.TAU);
const h = easings.InOutCubic(v);
const a = Maf.mod(data[ptr].a, Maf.TAU / ARMS);
const aa = (Maf.TAU / ARMS) * Math.floor(data[ptr].a / (Maf.TAU / ARMS)) - .5 * Maf.TAU / ARMS;
const dx = Math.cos(aa);
const dy = Math.sin(aa);
const axis = new THREE.Vector3(dx, 0, dy).normalize();
const ab = easings.InOutQuad(Maf.mod(.1 * r + t * Maf.TAU + a, Maf.TAU) / Maf.TAU) * Maf.TAU;
q.setFromAxisAngle(axis, r === 0 ? 0 : ab);
quatValues[ptr * 4 + 0] = q.x;
quatValues[ptr * 4 + 1] = q.y;
quatValues[ptr * 4 + 2] = q.z;
quatValues[ptr * 4 + 3] = q.w;
const s = r === 0 ? 1 : .5 + .5 * Maf.parabola(Maf.mod(.1 * r + t + a / Maf.TAU, 1), 1);
scaleValues[ptr * 3 + 0] = s;
scaleValues[ptr * 3 + 1] = s;
scaleValues[ptr * 3 + 2] = s;
const c = gradient.getAt(Maf.mod(.1 * r + t, 1));
const hsl = c.getHSL();
c.setHSL(hsl.h - .01, hsl.s - .2, hsl.l);
colorValues[ptr * 4 + 0] = c.r;
colorValues[ptr * 4 + 1] = c.g;
colorValues[ptr * 4 + 2] = c.b;
}
//instancedGeometry.positions.update(OBJECTS);
instancedGeometry.quaternions.update(OBJECTS);
instancedGeometry.scales.update(OBJECTS);
instancedGeometry.colors.update(OBJECTS);
//group.rotation.y = -t * Maf.TAU / ARMS;
painted.render(scene, camera);
}
export { draw, loopDuration, canvas };