JSFiddle - React, Tailwind, and code Playground
by Douglas Duhaime
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="x-shader/x-vertex" id="vertexshader">
attribute vec2 offset;
varying vec2 vOffset;
void main() {
vOffset = offset;
gl_PointSize = 25.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform sampler2D texture;
uniform vec2 repeat;
varying vec2 vOffset;
void main() {
vec2 uv = vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y );
vec4 tex = texture2D( texture, uv * repeat + vOffset );
if ( tex.a < 0.5 ) discard;
gl_FragColor = tex;
}
</script>
CSS
body {
background-color: #000;
margin: 0px;
overflow: hidden;
}
JavaScript
var renderer, scene, camera, controls;
var pointCloud, uniforms, attributes;
init();
animate();
function init() {
// info
info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '30px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.style.color = '#fff';
info.style.fontWeight = 'bold';
info.style.backgroundColor = 'transparent';
info.style.zIndex = '1';
info.style.fontFamily = 'Monospace';
info.innerHTML = 'Drag mouse to rotate camera; scroll to zoom';
document.body.appendChild( info );
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0x000000, 1 );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
//camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 400;
// controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
// vertices
var geometry = new THREE.SphereGeometry( 100, 16, 12 );
geometry.mergeVertices(); // to remove duplicate vertices at the poles
var vertices = geometry.vertices;
// geometry
geometry = new THREE.BufferGeometry();
// attributes
numVertices = vertices.length;
var positions = new Float32Array( numVertices * 3 ); // 3 coordinates per point
var offsets = new Float32Array( numVertices * 2 ); // 2 coordinates per point
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
geometry.addAttribute( 'offset', new THREE.BufferAttribute( offsets, 2 ) );
// populate positions
geometry.attributes.position.copyVector3sArray( vertices );
// populate offsets
var offset = new THREE.Vector2();
for ( var i = 0, index = 0, l = numVertices; i < l; i ++, index += 2 ) {
offset.set(...