codepens/troisjs-starfield/dist/script.js

121 lines
4.2 KiB
JavaScript

// Made with TroisJS : https://github.com/troisjs/trois
import { createApp } from 'https://unpkg.com/vue@3.0.11/dist/vue.esm-browser.prod.js'
import { lerp, BufferGeometry, Camera, EffectComposer, Points, Renderer, RenderPass, Scene, ShaderMaterial, Texture, UnrealBloomPass, ZoomBlurPass } from 'https://unpkg.com/troisjs@0.3.0-beta.4/build/trois.module.cdn.min.js'
import { Clock, Color, MathUtils, Vector3 } from 'https://unpkg.com/three@0.127.0/build/three.module.js'
const { randFloat: rnd, randInt, randFloatSpread: rndFS } = MathUtils
const vertexShader = `
uniform float uTime;
attribute vec3 color;
attribute float size;
attribute float velocity;
varying vec4 vColor;
void main(){
vColor = vec4(color, 1.0);
vec3 p = vec3(position);
p.z = -150. + mod(position.z + uTime, 300.);
vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
gl_PointSize = size * (-50.0 / mvPosition.z);
gl_Position = projectionMatrix * mvPosition;
}
`
const fragmentShader = `
uniform sampler2D uTexture;
varying vec4 vColor;
void main() {
gl_FragColor = vColor * texture2D(uTexture, gl_PointCoord);
}
`
createApp({
template: `
<Renderer ref="renderer" pointer resize="window">
<Camera :position="{ z: 0 }" :fov="50" />
<Scene>
<Points ref="points" :position="{ z: -150 }">
<BufferGeometry :attributes="attributes" />
<ShaderMaterial :blending="2" :depth-test="false" :uniforms="uniforms" :vertex-shader="vertexShader" :fragment-shader="fragmentShader">
<Texture src="https://assets.codepen.io/33787/sprite.png" uniform="uTexture" />
</ShaderMaterial>
</Points>
</Scene>
<EffectComposer>
<RenderPass />
<UnrealBloomPass :strength="2" :radius="0" :threshold="0" />
<ZoomBlurPass :strength="zoomStrength" />
</EffectComposer>
</Renderer>
<a href="#" @click="updateColors" @mouseenter="targetTimeCoef = 100" @mouseleave="targetTimeCoef = 1">Random Colors</a>
`,
components: { BufferGeometry, Camera, EffectComposer, Points, Renderer, RenderPass, Scene, ShaderMaterial, Texture, UnrealBloomPass, ZoomBlurPass },
setup() {
const POINTS_COUNT = 50000
const palette = niceColors[83]
const positions = new Float32Array(POINTS_COUNT * 3)
const colors = new Float32Array(POINTS_COUNT * 3)
const sizes = new Float32Array(POINTS_COUNT)
const v3 = new Vector3(), color = new Color()
for (let i = 0; i < POINTS_COUNT; i++) {
v3.set(rndFS(200), rndFS(200), rndFS(300))
v3.toArray(positions, i * 3)
color.set(palette[Math.floor(rnd(0, palette.length))])
color.toArray(colors, i * 3)
sizes[i] = rnd(5, 20)
}
const attributes = [
{ name: 'position', array: positions, itemSize: 3 },
{ name: 'color', array: colors, itemSize: 3 },
{ name: 'size', array: sizes, itemSize: 1 },
]
const uniforms = { uTime: { value: 0 } }
const clock = new Clock()
const timeCoef = 1, targetTimeCoef = 1
return {
POINTS_COUNT,
attributes, uniforms, vertexShader, fragmentShader,
clock, timeCoef, targetTimeCoef,
}
},
data() {
return {
zoomStrength: 0,
}
},
mounted() {
const renderer = this.$refs.renderer
const positionN = renderer.three.pointer.positionN
const points = this.$refs.points.points
renderer.onBeforeRender(() => {
this.timeCoef = lerp(this.timeCoef, this.targetTimeCoef, 0.02)
this.uniforms.uTime.value += this.clock.getDelta() * this.timeCoef * 4
this.zoomStrength = this.timeCoef * 0.004
const da = 0.05
const tiltX = lerp(points.rotation.x, positionN.y * da, 0.02)
const tiltY = lerp(points.rotation.y, -positionN.x * da, 0.02)
points.rotation.set(tiltX, tiltY, 0)
})
},
methods: {
updateColors() {
const colorAttribute = this.$refs.points.geometry.attributes.color
const ip = randInt(0, 99); const palette = niceColors[ip]; console.log(ip)
const color = new Color()
for (let i = 0; i < this.POINTS_COUNT; i++) {
color.set(palette[randInt(0, palette.length)])
color.toArray(colorAttribute.array, i * 3)
}
colorAttribute.needsUpdate = true
},
},
}).mount('#app')