<meta name="viewport" content="width=device-width">
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
gl_Position = vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 u_pos[ NB_BALLS ];
uniform vec3 u_RED;
uniform vec3 u_BLUE;
void main(){
float sum = 0.0;
for( int i = 0; i < NB_BALLS; i++ ){
float d = distance( gl_FragCoord.xy, u_pos[ i ].xy );
sum += u_pos[ i ].z / d * 150.0;
}
sum /= 1200.;
sum -= .8;
sum = clamp( sum, 0.0, 1.0 );
sum = floor( sum * 11.0 ) / 10.0;
gl_FragColor = vec4( mix( u_BLUE, u_RED, sum ), 1.0);
}
</script>
<div id="container"></div>
<script src="https://unpkg.com/three@0.85.0/build/three.min.js"></script>
<script src="https://unpkg.com/three@0.85.0/examples/js/Detector.js"></script>
*{
margin: 0;
padding: 0;
}
body {
overflow: hidden;
background: rgb( 30, 38, 48 );
}
#container {
position: relative;
}
View Compiled
window.addEventListener( 'load', function(){
if (!Detector.webgl) Detector.addGetWebGLMessage();
var width = window.innerWidth,
height = window.innerHeight;
var params = {
nbBalls : 40,
color1 : [ 30, 38, 48 ],
color2 : [ 251, 53, 80 ]
};
var container, camera, scene, renderer,
uniforms = {
u_BLUE: {
type: "v3",
value: new THREE.Vector3( params.color1[ 0 ] / 255 , params.color1[ 1 ] / 255, params.color1[ 2 ] / 255 )
},
u_RED: {
type: "v3",
value: new THREE.Vector3( params.color2[ 0 ] / 255 , params.color2[ 1 ] / 255, params.color2[ 2 ] / 255 )
},
u_pos: {
type: "v3v",
value: [].map.call(
( new Array( params.nbBalls ).fill( 0 ) ),
d => new THREE.Vector3( Math.random() * width, Math.random() * height, 40 + Math.random() * 100 )
)
}
},
lissajous = [].map.call(
new Array( params.nbBalls ).fill( 0 ),
d => {
return {
a: .2 + Math.random() ,
b: 1. + Math.random() * 5,
n: ~~ ( Math.random() * 30 )
}
}
);
( function init() {
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: "#define NB_BALLS " + params.nbBalls + "\n" + document.getElementById( 'fragmentShader' ).textContent
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( 1 );
container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
} )();
function onWindowResize( event ) {
width = window.innerWidth;
height = window.innerHeight;
renderer.setSize( width, height );
}
( function animate( t ) {
requestAnimationFrame( animate );
uniforms.u_pos.value.forEach( ( d, i ) => {
var tmp = ( i + t / 500 * lissajous[ i ].n ) / 200;
var x = width/2 + Math.cos( tmp * lissajous[ i ].a ) * ( width / 2 - 20 );
var y = height/2 + Math.sin( tmp * lissajous[ i ].b ) * ( height / 2 - 20 );
d.setX( x );
d.setY( y );
} );
renderer.render( scene, camera );
} )( 0 );
} );
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.