Skip to content

Commit

Permalink
feat: 升级threejs至r117.1
Browse files Browse the repository at this point in the history
  • Loading branch information
inori-lover committed Jun 7, 2020
1 parent 5fa66d7 commit 1b1d319
Show file tree
Hide file tree
Showing 20 changed files with 502 additions and 936 deletions.
12 changes: 3 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"@babel/core": "^7.10.2",
"@babel/preset-env": "^7.10.2",
"@types/node": "^14.0.11",
"@types/three": "^0.92.18",
"babel-loader": "^8.1.0",
"declaration-bundler-webpack-plugin": "^1.0.3",
"file-loader": "^6.0.0",
Expand All @@ -39,7 +38,7 @@
},
"dependencies": {
"core-js": "^3.6.5",
"three": "^0.96.0",
"three": "^0.117.1",
"tslib": "^2.0.0"
},
"types": "./lib/azusa.d.ts",
Expand Down
208 changes: 100 additions & 108 deletions src/azusa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { Triangle } from './Triangle';
import { range } from './util/range';
import { node } from './node';
import { Audio, loadOption as musicOption } from './audio';
import THREE from './lib/ExtendThree';

import './lib/LuminosityHighPassShader.js';
import './lib/CopyShader.js';
import './lib/EffectComposer.js';
import './lib/RenderPass.js';
import './lib/ShaderPass.js';
import './lib/UnrealBloomPass';
import * as THREE from 'three';

import { CopyShader } from 'three/examples/jsm/shaders/CopyShader';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
import { UnrealBloomPass } from './lib/UnrealBloomPass';

interface AzusaOption {
view: HTMLCanvasElement;
Expand All @@ -26,30 +26,32 @@ export interface ExportedAzusaOption extends Partial<AzusaOption> {
music: musicOption;
}

class Line extends THREE.Line{
constructor (vertices: THREE.Vector2[], lineMaterial:THREE.LineBasicMaterial) {

const lineGeometry = new THREE.BufferGeometry()
lineGeometry.addAttribute('position', Line.creatBufferAttribute(vertices).setDynamic(true))
class Line extends THREE.Line {
constructor(vertices: THREE.Vector2[], lineMaterial: THREE.LineBasicMaterial) {
const lineGeometry = new THREE.BufferGeometry();
lineGeometry.setAttribute(
'position',
Line.creatBufferAttribute(vertices).setUsage(THREE.DynamicDrawUsage),
);

super(lineGeometry, lineMaterial)
super(lineGeometry, lineMaterial);
}

static creatBufferAttribute(vertices: THREE.Vector2[]) {
const res: number[] = [];
vertices = vertices.concat(vertices[0])
vertices = vertices.concat(vertices[0]);
vertices.forEach((value) => {
res.push(value.x, value.y, 0);
})
});
return new THREE.BufferAttribute(new Float32Array(res), 3);
}
}

export class Azusa {
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private composer: THREE.EffectComposer;
private bloomPass: THREE.UnrealBloomPass;
private composer: EffectComposer;
private bloomPass: UnrealBloomPass;
private clock: THREE.Clock = new THREE.Clock();
private lines: THREE.Line[];
private lineA: THREE.Line;
Expand All @@ -62,65 +64,61 @@ export class Azusa {
private audio: Audio;
private nodes: node[];
private Triangles: Triangle[] = [];
private option:AzusaOption;
private option: AzusaOption;

constructor(_option: ExportedAzusaOption) {

const option: AzusaOption = Object.assign({
width: window.innerWidth,
height: window.innerHeight,
subdivisionSize: 1024,
cutFront: 0,
cutEnd: 0
}, _option)

const {
view,
width = window.innerWidth,
height = window.innerHeight,
subdivisionSize = 1024,
cutFront = 0,
cutEnd = 0
} = option;
const option: AzusaOption = Object.assign(
{
width: window.innerWidth,
height: window.innerHeight,
subdivisionSize: 1024,
cutFront: 0,
cutEnd: 0,
},
_option,
);

const { view, width, height, subdivisionSize, cutFront, cutEnd } = option;

const renderer = new THREE.WebGLRenderer({
canvas: view,
alpha: true,
antialias: true
antialias: true,
});
renderer.setSize(width, height);
renderer.setClearColor(0x000000, 0);

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(45, width / height, 1, 500);
camera.position.set(0, 0, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));

const composer = new THREE.EffectComposer(renderer)
const composer = new EffectComposer(renderer);
composer.setSize(width, height);
const renderScene = new THREE.RenderPass(scene, camera)
const renderScene = new RenderPass(scene, camera);
composer.addPass(renderScene);
this.bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(width, height), 1.5, 0.2, 0);
this.bloomPass = new UnrealBloomPass(new THREE.Vector2(width, height), 1.5, 0.2, 0);
composer.addPass(this.bloomPass);
const copyShader = new THREE.ShaderPass(THREE.CopyShader);
const copyShader = new ShaderPass(CopyShader);
copyShader.renderToScreen = true;
composer.addPass(copyShader);

const audio = new Audio({ fftsize: subdivisionSize })
this.loadAudio(camera, audio)
const audio = new Audio({ fftsize: subdivisionSize });
this.loadAudio(camera, audio);

const frequencyBinCount = audio.frequencyBinCount;

const nodeCount = frequencyBinCount - cutEnd - cutFront
const nodes = range(0, nodeCount).map(item => {
return new node(20, (item / nodeCount * 360 + 45) % 360, new THREE.Vector2(0, 0));
})
const nodeCount = frequencyBinCount - cutEnd - cutFront;
const nodes = range(0, nodeCount).map((item) => {
return new node(20, ((item / nodeCount) * 360 + 45) % 360, new THREE.Vector2(0, 0));
});

const lineGroup = new THREE.Group();
const { lineA, lineB, lines } = this.loadLine(nodes);
lineGroup.add(lineA);
lineGroup.add(lineB);
lines.forEach(line => lineGroup.add(line));
lines.forEach((line) => lineGroup.add(line));
scene.add(lineGroup);

const { TriangleGroup } = this.loadTriangle();
Expand All @@ -140,61 +138,78 @@ export class Azusa {

this.option = option;

this.loadMusic()
this.loadMusic();
this.render();
this.resize(width, height);
}

private loadLine = (nodes: node[]) => {
const lineMaterial = this.lineMaterial
const lineA = new Line(nodes.map(node => node['positionA']), lineMaterial);
const lineB = new Line(nodes.map(node => node['positionB']), lineMaterial);
const lines: Line[] = range(0, nodes.length).map(item => {
const lineMaterial = this.lineMaterial;
const lineA = new Line(
nodes.map((node) => node['positionA']),
lineMaterial,
);
const lineB = new Line(
nodes.map((node) => node['positionB']),
lineMaterial,
);
const lines: Line[] = range(0, nodes.length).map((item) => {
return new Line([nodes[item].positionA, nodes[item].positionB], lineMaterial);
})
});

return { lineA, lineB, lines };
}
};

private loadAudio = (camera: THREE.PerspectiveCamera, audio: Audio) => {
camera.add(audio.listener);
}
};

private loadMusic = () => {
this.option.music && this.audio.load(this.option.music)
}
this.option.music && this.audio.load(this.option.music);
};

private loadTriangle = () => {
const TriangleGroup = new THREE.Group();
setInterval(() => requestAnimationFrame(this.addTriangle), 500);
return { TriangleGroup };
}
};

private addTriangle = () => {
const material = this.material
const lineMaterial = this.lineMaterial
const material = this.material;
const lineMaterial = this.lineMaterial;
const triangle = this.makeTriangle(material, lineMaterial, (t) => {
this.Triangles = this.Triangles.filter((triangle) => {
return triangle !== t;
})
});
this.TriangleGroup.remove(t.group);
});
this.TriangleGroup.add(triangle.group);
this.Triangles.push(triangle);
}
};

private makeTriangle = (
material: THREE.MeshBasicMaterial = new THREE.MeshBasicMaterial({ color: 0x03a9f4 }),
lineMaterial: THREE.LineBasicMaterial = new THREE.LineBasicMaterial({ color: 0x03a9f4 }),
cb: (t: Triangle) => void) => {
const triangle = new Triangle(2, new THREE.Vector3(0, 0, 0), Math.random() * 360, randomRange(5, 1), randomRange(0.1, 0.02), material, lineMaterial, {
startShow: 15,
endShow: 30,
startHide: 60,
endHide: 70
}, cb)
cb: (t: Triangle) => void,
) => {
const triangle = new Triangle(
2,
new THREE.Vector3(0, 0, 0),
Math.random() * 360,
randomRange(5, 1),
randomRange(0.1, 0.02),
material,
lineMaterial,
{
startShow: 15,
endShow: 30,
startHide: 60,
endHide: 70,
},
cb,
);
return triangle;
}
};

private updateGeometries = (scale: number) => {
this.lineGroup.scale.set(scale, scale, scale);
Expand All @@ -209,58 +224,35 @@ export class Azusa {
positions.forEach((position, index) => {
AttributeA.set([position[0].x, position[0].y], index * 3);
AttributeB.set([position[1].x, position[1].y], index * 3);
const geometry = (this.lines[index].geometry as THREE.BufferGeometry);
const geometry = this.lines[index].geometry as THREE.BufferGeometry;
const Attribute = geometry.getAttribute('position') as THREE.BufferAttribute;
Attribute.set(
[position[0].x, position[0].y, 0,
position[1].x, position[1].y, 0], 0
)
Attribute.set([position[0].x, position[0].y, 0, position[1].x, position[1].y, 0], 0);
Attribute.needsUpdate = true;
})
});
AttributeA.set([AttributeA.array[0], AttributeA.array[1]], positions.length * 3);
AttributeB.set([AttributeB.array[0], AttributeB.array[1]], positions.length * 3);
AttributeA.needsUpdate = true;
AttributeB.needsUpdate = true;
}
};

private render = () => {
this.composer.render();
let audioDate = this.audio.getFrequencyData()
let audioDate = this.audio.getFrequencyData();
const Delta = this.clock.getDelta();
const cutAudioDate = audioDate.slice(this.option.cutFront, audioDate.length - this.option.cutEnd)
const cutAudioDate = audioDate.slice(
this.option.cutFront,
audioDate.length - this.option.cutEnd,
);
this.nodes.forEach((node, index, array) => {
node.strength = cutAudioDate[(index) % array.length] * 0.1;
node.strength = cutAudioDate[index % array.length] * 0.1;
node.transition(Delta);
})
});

this.updateGeometries(1 + audioDate[Math.ceil(audioDate.length * 0.05)] / 1000);
this.Triangles.forEach(triangle => triangle.transition(Delta));
this.Triangles.forEach((triangle) => triangle.transition(Delta));

requestAnimationFrame(this.render);
}

public loadGui = () => {
const params = {
projection: 'normal',
background: false,
exposure: 1.0,
bloomStrength: 1.5,
bloomThreshold: 0.2,
bloomRadius: 0
};
const gui = new (window as any).dat.GUI();
gui.add(params, 'exposure', 0.1, 2);
gui.add(params, 'bloomThreshold', 0.0, 1.0).onChange((value: any) => {
this.bloomPass['threshold'] = Number(value);
});
gui.add(params, 'bloomStrength', 0.0, 3.0).onChange((value: any) => {
this.bloomPass['strength'] = Number(value);
});
gui.add(params, 'bloomRadius', 0.0, 1.0).onChange((value: any) => {
this.bloomPass['radius'] = Number(value);
});
gui.open();
}
};

public resize = (width: number, height: number) => {
this.camera.aspect = width / height;
Expand All @@ -272,7 +264,7 @@ export class Azusa {
this.camera.updateProjectionMatrix();
this.renderer.setSize(width, height);
this.composer.setSize(width, height);
}
};
}

export default Azusa
export default Azusa;
2 changes: 1 addition & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</style>

<!-- <script src="https://cdn.jsdelivr.net/npm/three"></script> -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.js"></script> -->
<!-- <script async>
(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//rawgit.com/mrdoob/stats.js/master/build/stats.min.js';document.head.appendChild(script);})()
</script> -->
Expand Down
Loading

0 comments on commit 1b1d319

Please sign in to comment.