Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ShaneBrumback/54c3b1a3d588050c9e37d0abb14125f3 to your computer and use it in GitHub Desktop.

Select an option

Save ShaneBrumback/54c3b1a3d588050c9e37d0abb14125f3 to your computer and use it in GitHub Desktop.
Threejs Examples Enhancing Your Website With Threejs Star Field Particle System
<!--////////////////////////////////////////////////////////////////////////////////////////
/// ///
/// Example Using Three.js Library, HTML, CSS & JavaScript ///
// 3D Interactive Web Apps & Games 2021-2024 ///
/// Contact Shane Brumback https://www.shanebrumback.com ///
/// Send a message if you have questions about this code ///
/// I am a freelance developer. I develop any and all web. ///
/// Apps Websites 3D 2D CMS Systems etc. Contact me anytime :) ///
/// ///
////////////////////////////////////////////////////////////////////////////////////////////-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Threejs Examples - Enhancing Your Website With Threejs Star Field Particle Systems</title>
<style>
body {
color: white;
text-align: center;
margin: 0;
background-color: black
}
a {
text-decoration: none;
color: white;
}
h1 {
padding: 10px;
}
</style>
</head>
<body>
<a href="http://www.shanebrumback.com/blog/enhancing-your-website-with-threejs-star-field-particle-systems.html">
<h1>Threejs Examples - Enhancing Your Website With Three.js Star Field Particle Systems</h1>
</a>
<!--Load the latest version of Three.js from CDN-->
<script src="https://cdn.jsdelivr.net/npm/three@latest/build/three.min.js"></script>
<script>
// Variables for Three.js components
let scene, camera, renderer;
let mouseX = 0, mouseY = 0;
let targetX = 0, targetY = 0;
let particleSystem;
let planes = []
// Function to set up the scene, camera, and renderer
function init() {
// Create the scene
scene = new THREE.Scene();
// Create the camera
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 100, 1000);
camera.position.z = 100;
// Create the renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.setClearColor(0x000000); // Set background color to black
renderer.domElement.style.position = 'fixed';
renderer.domElement.style.zIndex = '-3';
renderer.domElement.style.left = '0';
renderer.domElement.style.top = '0';
document.body.appendChild(renderer.domElement);;
// Call the function to load the star area
loadStars();
// Function to handle window resizing
window.addEventListener('resize', onWindowResize, false);
// Function to handle mouse movement
window.addEventListener('mousemove', onMouseMove, false);
// Load the smoke texture
const textureLoader = new THREE.TextureLoader();
const smokeTexture = textureLoader.load('images/smoke.png');
// Create 50 planes with smoke texture
const planes = [];
for (let i = 0; i < 50; i++) {
const planeGeometry = new THREE.PlaneGeometry(500, 500);
const planeMaterial = new THREE.MeshBasicMaterial({
map: smokeTexture,
transparent: true,
depthTest: false, // Disable depth testing for transparency
});
const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(planeMesh);
// Set random initial positions
planeMesh.position.set(
Math.random() * 1000 - 500,
Math.random() * 1000 - 500,
Math.random() * 1000 - 500,
);
// Face the camera
const lookAtVector = new THREE.Vector3();
lookAtVector.subVectors(camera.position, planeMesh.position);
planeMesh.quaternion.setFromUnitVectors(new THREE.Vector3(0, 0, 1), lookAtVector.normalize());
// Set random rotation speed
const speed = Math.random() * 0.005;
planeMesh.userData.speed = speed;
planes.push(planeMesh);
}
}
// Function to load the cube with particle system
function loadStars() {
const triangles = 10000;
const positions = new Float32Array(triangles * 9); // 3 vertices per triangle, 3 coordinates per vertex
const colors = new Float32Array(triangles * 12); // 4 color values per vertex
const n = 800, n2 = n / 2; // cube size
const d = 200, d2 = d / 2; // triangle size
for (let i = 0; i < triangles; i++) {
const vertexIndex = i * 9; // vertex index in the positions array
const colorIndex = i * 12; // color index in the colors array
// Generate random positions for the triangle vertices within the cube
const x = Math.random() * n - n2;
const y = Math.random() * n - n2;
const z = Math.random() * n - n2;
const ax = x + Math.random() * d - d2;
const ay = y + Math.random() * d - d2;
const az = z + Math.random() * d - d2;
const bx = x + Math.random() * d - d2;
const by = y + Math.random() * d - d2;
const bz = z + Math.random() * d - d2;
const cx = x + Math.random() * d - d2;
const cy = y + Math.random() * d - d2;
const cz = z + Math.random() * d - d2;
// Set positions for the triangle vertices
positions[vertexIndex] = ax;
positions[vertexIndex + 1] = ay;
positions[vertexIndex + 2] = az;
positions[vertexIndex + 3] = bx;
positions[vertexIndex + 4] = by;
positions[vertexIndex + 5] = bz;
positions[vertexIndex + 6] = cx;
positions[vertexIndex + 7] = cy;
positions[vertexIndex + 8] = cz;
// Generate random bright colors for each vertex
const r = Math.random();
const g = Math.random();
const b = Math.random();
// Set colors for the triangle vertices
colors[colorIndex] = r;
colors[colorIndex + 1] = g;
colors[colorIndex + 2] = b;
colors[colorIndex + 3] = 1.0;
colors[colorIndex + 4] = r;
colors[colorIndex + 5] = g;
colors[colorIndex + 6] = b;
colors[colorIndex + 7] = 1.0;
colors[colorIndex + 8] = r;
colors[colorIndex + 9] = g;
colors[colorIndex + 10] = b;
colors[colorIndex + 11] = 1.0;
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 4));
const material = new THREE.PointsMaterial({ size: 0.05, vertexColors: true });
particleSystem = new THREE.Points(geometry, material);
scene.add(particleSystem);
}
// Function to handle window resizing
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Function to handle mouse movement
function onMouseMove(event) {
mouseX = (event.clientX - window.innerWidth / 2) / 100;
mouseY = (event.clientY - window.innerHeight / 2) / 100;
}
// Function to update the scene's rotation based on mouse movement
function updateSceneRotation() {
targetX = mouseX * 0.01;
targetY = mouseY * 0.01;
particleSystem.rotation.y += .5 * (targetX - scene.rotation.y);
particleSystem.rotation.x += .5 * (targetY - scene.rotation.x);
}
// Function to render the scene
function animate() {
requestAnimationFrame(animate);
updateSceneRotation()
// Rotate the planes
for (const plane of planes) {
// Rotate the plane
plane.rotateOnAxis(new THREE.Vector3(0, 0, 1), plane.userData.speed);
}
renderer.render(scene, camera);
}
// Call the init function to set up the scene, camera, and renderer
init();
// Start the animation loop
animate();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment