<div class='canvas-container'></div>
<script src='https://unpkg.com/[email protected]/build/three.min.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/controls/OrbitControls.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/shaders/CopyShader.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/shaders/LuminosityHighPassShader.js'></script>
<script src='https://unpkg.com/[email protected]/examples/js/postprocessing/UnrealBloomPass.js'></script>
<script id='sphere-vertex-shader' type='x-shader/x-vertex'>
uniform float uTime;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vNormal = normal;
vec3 delta = 40.0 * normal * sin(
abs(normal.x) * 2.0 +
abs(normal.y) * 3.0 +
abs(normal.z) * 4.0 + uTime / 2.0);
delta.x += 20.0 * sin(uTime * normal.z);
delta.y += 20.0 * sin(uTime * normal.x);
delta.z += 20.0 * sin(uTime * normal.y);
vec3 newPosition = position + delta;
vPosition = newPosition;
gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
gl_PointSize = 1.0;
}
</script>
<script id='sphere-fragment-shader' type='x-shader/x-fragment'>
uniform float uTime;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
}
.canvas-container {
height: 100vh;
width: 100vw;
background: #6a558e;
}
View Compiled
let SCENE;
let CAMERA;
let RENDERER;
let CONTROLS;
let COMPOSER;
let TIME = 10; // Let it be non zero at start
main();
function main() {
init();
animate();
}
function init() {
initScene();
initCamera();
initRenderer();
initComposer();
initControls();
initEventListeners();
createObjects();
document.querySelector('.canvas-container').appendChild(RENDERER.domElement);
}
function initScene() {
SCENE = new THREE.Scene();
initLights();
}
function initLights() {
const point = new THREE.PointLight(0xffffff, 1, 0);
point.position.set(0, 100, 50);
SCENE.add(point);
}
function initCamera() {
CAMERA = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
CAMERA.position.z = 100;
}
function initRenderer() {
RENDERER = new THREE.WebGLRenderer({ alpha: true });
RENDERER.setPixelRatio(window.devicePixelRatio);
RENDERER.setSize(window.innerWidth, window.innerHeight);
RENDERER.shadowMap.enabled = true;
RENDERER.shadowMapSort = true;
RENDERER.setClearColor(0x6a558e, 0.3);
}
function initComposer() {
COMPOSER = new THREE.EffectComposer(RENDERER);
COMPOSER.setSize(window.innerWidth, window.innerHeight);
const renderPass = new THREE.RenderPass(SCENE, CAMERA);
COMPOSER.addPass(renderPass);
const bloomPass = new THREE.UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 1, 0.1);
bloomPass.renderToScreen = true;
COMPOSER.addPass(bloomPass);
}
function initControls() {
CONTROLS = new THREE.OrbitControls(CAMERA);
CONTROLS.enableZoom = false;
CONTROLS.minPolarAngle = Math.PI * 1 / 4;
CONTROLS.maxPolarAngle = Math.PI * 3 / 4;
CONTROLS.update();
}
function initEventListeners() {
window.addEventListener('resize', onWindowResize);
onWindowResize();
}
function onWindowResize() {
CAMERA.aspect = window.innerWidth / window.innerHeight;
CAMERA.updateProjectionMatrix();
RENDERER.setSize(window.innerWidth, window.innerHeight);
COMPOSER.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
CONTROLS.update();
TIME += 0.005;
updateUniforms();
render();
}
function updateUniforms() {
SCENE.traverse(function(child) {
if (child instanceof THREE.Points
&& child.material.type === 'ShaderMaterial') {
child.material.uniforms.uTime.value = TIME;
child.material.needsUpdate = true;
}
});
}
function render() {
CAMERA.lookAt(SCENE.position);
COMPOSER.render(SCENE, CAMERA);
}
function createObjects() {
const geometry = new THREE.TorusBufferGeometry(25, 1, 3000, 13);
const shaderMaterial = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: TIME }
},
transparent: true,
side: THREE.DoubleSide,
vertexShader: document.getElementById('sphere-vertex-shader').textContent,
fragmentShader: document.getElementById('sphere-fragment-shader').textContent
});
const torus = new THREE.Points(geometry, shaderMaterial);
SCENE.add(torus);
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.