index105
class Planet {
constructor(position) {
this.position = position
this.sphereGeometry = new THREE.SphereBufferGeometry(20, 100, 100)
this.sphereGeometry2 = new THREE.SphereBufferGeometry(40, 100, 100)
this.sphereGeometry3 = new THREE.SphereBufferGeometry(60, 100, 100)
let count = this.sphereGeometry.attributes.position.count
let shouldOffsetArr = new Float32Array(count)
let rangeArr = new Float32Array(count)
let timeArray = new Float32Array(count)
let sizesArray = new Float32Array(count)
let targetArr = new Float32Array(count * 3)
let whiteValues = new Float32Array(count)
let possibleRange = 50
for (let i = 0; i < count; i += 1) {
shouldOffsetArr[i] = Math.random()
rangeArr[i] = possibleRange / 2 + Math.random() * possibleRange
let randTime = Math.random() * 50
timeArray[i + 0] = randTime
timeArray[i + 1] = randTime
timeArray[i + 2] = randTime
sizesArray[i] = Math.random() * 2 + 1
whiteValues[i] = Math.random() * 0.7 + 0.3
}
for (let i = 0; i < count * 3; i += 3) {
let randX = 0
let randY = 0
let randZ = 0
if (i % 2 === 0) {
randX = this.sphereGeometry2.attributes.position.array[i + 0]
randY = this.sphereGeometry2.attributes.position.array[i + 1]
randZ = this.sphereGeometry2.attributes.position.array[i + 2]
} else {
randX = this.sphereGeometry3.attributes.position.array[i + 0]
randY = this.sphereGeometry3.attributes.position.array[i + 1]
randZ = this.sphereGeometry3.attributes.position.array[i + 2]
}
targetArr[i + 0] = randX
targetArr[i + 1] = randY
targetArr[i + 2] = randZ
}
this.sphereGeometry.addAttribute('shouldOffset', new THREE.BufferAttribute(shouldOffsetArr, 1))
this.sphereGeometry.addAttribute('range', new THREE.BufferAttribute(rangeArr, 1))
this.sphereGeometry.addAttribute('offsetPosition', new THREE.BufferAttribute(targetArr, 3))
this.sphereGeometry.addAttribute('randTime', new THREE.BufferAttribute(timeArray, 1))
this.sphereGeometry.addAttribute('size', new THREE.BufferAttribute(sizesArray, 1))
this.sphereGeometry.addAttribute('whiteValue', new THREE.BufferAttribute(whiteValues, 1))
this.attractor1 = new THREE.Vector3(0, 20, 0)
this.attractor2 = new THREE.Vector3(20, 0, 0)
this.attractor3 = new THREE.Vector3(0, -20, 0)
this.attractor4 = new THREE.Vector3(0, -20, 0)
this.attractor1.randomAngle = 5
this.attractor1.speed = Math.random() + 1
this.attractor2.randomAngle = 10
this.attractor2.speed = Math.random() + 1
this.attractor3.randomAngle = 15
this.attractor3.speed = Math.random() + 1
this.attractor4.randomAngle = 20
this.attractor4.speed = Math.random() + 1
this.sphereMaterial = new THREE.ShaderMaterial({
uniforms: {
time: {
value: 0
},
rotationMatrix: {
value: new THREE.Matrix4()
},
targetPosition1: {
value: this.attractor1
},
targetPosition2: {
value: this.attractor2
},
targetPosition3: {
value: this.attractor3
},
targetPosition4: {
value: this.attractor4
},
opacity: {
value: 0
}
},
vertexShader: planetVertexShader,
fragmentShader: planetFragmentShader,
transparent: true
})
}
init(parentNode) {
this.mesh = new THREE.Points(this.sphereGeometry, this.sphereMaterial)
this.mesh.position.copy(this.position)
this.mesh.rotation.x = 240 * Math.PI / 180
this.mesh.rotation.y = 240 * Math.PI / 180
parentNode.add(this.mesh)
return this
}
removeFromScene(parentNode) {
parentNode.remove(this.mesh)
return this
}
updateFrame(elapsedTime, delta) {
this.mesh.material.uniforms.time.value = elapsedTime
this.mesh.material.uniforms.rotationMatrix.value.makeRotationY(elapsedTime * 0.5)
let offset = 20
let sin = Math.sin(this.attractor1.randomAngle)
let cos = Math.cos(this.attractor1.randomAngle)
this.attractor1.x = sin * offset
this.attractor1.y = cos * offset
this.attractor1.randomAngle += delta * this.attractor1.speed
sin = Math.sin(this.attractor2.randomAngle * 0.75)
cos = Math.cos(this.attractor2.randomAngle * 0.75)
this.attractor2.x = sin * (offset + 20)
this.attractor2.z = cos * (offset + 20)
this.attractor2.randomAngle += delta * this.attractor2.speed
sin = Math.sin(this.attractor3.randomAngle * 0.5)
cos = Math.cos(this.attractor3.randomAngle * 0.5)
this.attractor3.x = sin * (offset)
this.attractor3.y = cos * (offset)
this.attractor3.randomAngle += delta * this.attractor3.speed
sin = Math.sin(this.attractor4.randomAngle * 0.25)
cos = Math.cos(this.attractor4.randomAngle * 0.25)
this.attractor4.x = sin * (offset + 20)
this.attractor4.y = cos * (offset + 20)
this.attractor4.randomAngle += delta * this.attractor4.speed
}
}
const width = window.innerWidth
const height = window.innerHeight
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000)
const renderer = new THREE.WebGLRenderer({
antialias: true
})
const clock = new THREE.Clock()
//const controls = new THREE.OrbitControls(camera, renderer.domElement)
const planetVertexShader = document.querySelector('#vertex-shader').text
const planetFragmentShader = document.querySelector('#fragment-shader').text
const planet = new Planet(new THREE.Vector3()).init(scene)
let elapsedTime = 0
setScene()
renderFrame()
function setScene() {
renderer.setSize(width, height)
renderer.setClearColor(0x111111)
renderer.setPixelRatio(window.devicePixelRatio || 1)
document.body.appendChild(renderer.domElement)
camera.position.set(0, 20, 200)
camera.lookAt(new THREE.Vector3())
// scene.add(new THREE.GridHelper(100, 3))
let delay = 0.75
TweenMax.to(planet.mesh.material.uniforms.opacity, 3, {
value: 1,
delay
})
TweenMax.to(planet.mesh.rotation, 2, {
x: 240 * Math.PI / 180,
y: 240 * Math.PI / 180,
delay
})
}
function renderFrame() {
window.requestAnimationFrame(renderFrame)
renderer.render(scene, camera)
let delta = clock.getDelta()
elapsedTime += delta
planet.updateFrame(elapsedTime, delta)
}