245 lines
6.6 KiB
JavaScript
245 lines
6.6 KiB
JavaScript
import './style.css'
|
|
import * as THREE from 'three'
|
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
|
|
//import * as dat from 'dat.gui'
|
|
import { AdditiveBlending, Float32BufferAttribute } from 'three'
|
|
|
|
/**
|
|
* Base
|
|
*/
|
|
// Debug
|
|
//const gui = new dat.GUI({
|
|
// width: 400,
|
|
// closed: true
|
|
//})
|
|
|
|
const textureLoader = new THREE.TextureLoader()
|
|
const shape = textureLoader.load('/pkg/galaxy/particleShape/1.png')
|
|
|
|
// Canvas
|
|
const canvas = document.querySelector('canvas.webgl')
|
|
|
|
// Scene
|
|
const scene = new THREE.Scene()
|
|
|
|
|
|
//Galaxy Generator
|
|
|
|
const parameters = {}
|
|
|
|
parameters.count = 70000
|
|
parameters.size = 0.01
|
|
parameters.radius = 5
|
|
parameters.branches = 8
|
|
parameters.spin = 1
|
|
parameters.randomness = 0.3
|
|
parameters.randomnessPower = 5
|
|
parameters.stars = 9000
|
|
parameters.starColor = '#fff700'
|
|
parameters.insideColor = '#fff700'
|
|
parameters.outsideColor = '#fff700'
|
|
|
|
//parameters.starColor = '#1b3984'
|
|
//parameters.insideColor = '#ff6030'
|
|
//parameters.outsideColor = '#1b3984'
|
|
|
|
//gui.add(parameters, 'count').min(100).max(100000).step(100).onChange(generateGalaxy).name('stars in galaxy')
|
|
//gui.add(parameters, 'stars').min(0).max(100000).step(100).onChange(generateBgStars).name('background stars')
|
|
//gui.addColor(parameters, 'starColor').onChange(generateBgStars).name('color of stars')
|
|
//gui.add(parameters, 'size').min(0.001).max(0.1).step(0.001).onChange(generateGalaxy).name('size of stars in galaxy')
|
|
//gui.add(parameters, 'radius').min(1).max(10).step(1).onChange(generateGalaxy).name('radius of galaxy')
|
|
//gui.add(parameters, 'branches').min(1).max(10).step(1).onChange(generateGalaxy).name('branches in galaxy')
|
|
//gui.add(parameters, 'spin').min(-5).max(5).step(0.001).onChange(generateGalaxy).name('spin of the galaxy')
|
|
//gui.add(parameters, 'randomness').min(0).max(2).step(0.01).onChange(generateGalaxy)
|
|
//gui.add(parameters, 'randomnessPower').min(1).max(10).step(1).onChange(generateGalaxy)
|
|
//gui.addColor(parameters, 'insideColor').onChange(generateGalaxy).name('color of core')
|
|
//gui.addColor(parameters, 'outsideColor').onChange(generateGalaxy).name('color of branches')
|
|
|
|
|
|
let bgStarsGeometry = null
|
|
let bgStarsMaterial = null
|
|
let bgStars = null
|
|
|
|
//Background stars
|
|
function generateBgStars(){
|
|
|
|
if(bgStars!==null){
|
|
bgStarsGeometry.dispose()
|
|
bgStarsMaterial.dispose()
|
|
scene.remove(bgStars)
|
|
}
|
|
|
|
bgStarsGeometry = new THREE.BufferGeometry()
|
|
const bgStarsPositions = new Float32Array(parameters.stars * 3)
|
|
|
|
for(let j = 0; j<parameters.stars; j++){
|
|
bgStarsPositions[j*3 + 0] = (Math.random() - 0.5) * 20
|
|
bgStarsPositions[j*3 + 1] = (Math.random() - 0.5) * 20
|
|
bgStarsPositions[j*3 + 2] = (Math.random() - 0.5) * 20
|
|
}
|
|
|
|
bgStarsGeometry.setAttribute('position', new THREE.BufferAttribute(bgStarsPositions, 3))
|
|
|
|
bgStarsMaterial = new THREE.PointsMaterial({
|
|
color: 'white',
|
|
size: parameters.size,
|
|
depthWrite: false,
|
|
sizeAttenuation: true,
|
|
blending: AdditiveBlending,
|
|
color: parameters.starColor,
|
|
transparent: true,
|
|
alphaMap: shape
|
|
})
|
|
|
|
bgStars = new THREE.Points(bgStarsGeometry, bgStarsMaterial)
|
|
|
|
scene.add(bgStars)
|
|
scene.background = new THREE.Color( 0x313131 );
|
|
}
|
|
|
|
generateBgStars()
|
|
|
|
|
|
|
|
|
|
//gALAXY GENerator
|
|
let geometry = null
|
|
let material = null
|
|
let points = null
|
|
|
|
|
|
function generateGalaxy(){
|
|
|
|
if(points !== null){
|
|
geometry.dispose()
|
|
material.dispose()
|
|
scene.remove(points)
|
|
}
|
|
|
|
geometry = new THREE.BufferGeometry()
|
|
|
|
const positions = new Float32Array(parameters.count *3)
|
|
const colors = new Float32Array(parameters.count *3)
|
|
|
|
const colorInside = new THREE.Color(parameters.insideColor)
|
|
const colorOutside = new THREE.Color(parameters.outsideColor)
|
|
|
|
for(let i=0; i<parameters.count; i++){
|
|
|
|
//Position
|
|
const x = Math.random() * parameters.radius
|
|
const branchAngle = (i % parameters.branches) / parameters.branches * 2 * Math.PI
|
|
const spinAngle = x * parameters.spin
|
|
|
|
const randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random()<0.5 ? 1: -1)
|
|
const randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random()<0.5 ? 1: -1)
|
|
const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random()<0.5 ? 1: -1)
|
|
|
|
positions[i*3] = Math.sin(branchAngle + spinAngle) * x + randomX
|
|
positions[i*3 + 1] = randomY
|
|
positions[i*3 + 2] = Math.cos(branchAngle + spinAngle) * x + randomZ
|
|
|
|
//Color
|
|
|
|
const mixedColor = colorInside.clone()
|
|
mixedColor.lerp(colorOutside, x / parameters.radius)
|
|
|
|
colors[i*3 + 0] = mixedColor.r
|
|
colors[i*3 + 1] = mixedColor.g
|
|
colors[i*3 + 2] = mixedColor.b
|
|
}
|
|
|
|
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
|
|
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))
|
|
|
|
material = new THREE.PointsMaterial({
|
|
color: 'white',
|
|
size: parameters.size,
|
|
depthWrite: false,
|
|
sizeAttenuation: true,
|
|
blending: AdditiveBlending,
|
|
vertexColors: true,
|
|
transparent: true,
|
|
alphaMap: shape
|
|
})
|
|
|
|
points = new THREE.Points(geometry, material)
|
|
scene.add(points)
|
|
|
|
|
|
}
|
|
|
|
generateGalaxy()
|
|
|
|
/**
|
|
* Sizes
|
|
*/
|
|
const sizes = {
|
|
width: window.innerWidth,
|
|
height: window.innerHeight
|
|
}
|
|
|
|
window.addEventListener('resize', () =>
|
|
{
|
|
// Update sizes
|
|
sizes.width = window.innerWidth
|
|
sizes.height = window.innerHeight
|
|
|
|
// Update camera
|
|
camera.aspect = sizes.width / sizes.height
|
|
camera.updateProjectionMatrix()
|
|
|
|
// Update renderer
|
|
renderer.setSize(sizes.width, sizes.height)
|
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
|
|
})
|
|
|
|
/**
|
|
* Camera
|
|
*/
|
|
// Base camera
|
|
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
|
|
camera.position.x = 4
|
|
camera.position.y = 0.4
|
|
camera.position.z = 4
|
|
scene.add(camera)
|
|
|
|
// Controls
|
|
const controls = new OrbitControls(camera, canvas)
|
|
controls.enableDamping = true
|
|
|
|
/**
|
|
* Renderer
|
|
*/
|
|
const renderer = new THREE.WebGLRenderer({
|
|
canvas: canvas
|
|
})
|
|
renderer.setSize(sizes.width, sizes.height)
|
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
|
|
|
|
/**
|
|
* Animate
|
|
*/
|
|
const clock = new THREE.Clock()
|
|
|
|
const tick = () =>
|
|
{
|
|
const elapsedTime = clock.getElapsedTime()
|
|
|
|
//Update the camera
|
|
points.rotation.y = elapsedTime*0.005
|
|
bgStars.rotation.y = - elapsedTime*0.05
|
|
|
|
// Update controls
|
|
controls.update()
|
|
|
|
// Render
|
|
renderer.render(scene, camera)
|
|
|
|
// Call tick again on the next frame
|
|
window.requestAnimationFrame(tick)
|
|
|
|
}
|
|
|
|
tick()
|