<!-- from https://discourse.threejs.org/t/4071/2 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/95/three.min.js"></script>
<script src="https://unpkg.com/three@0.95.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
body {
    margin: 0;
    padding: 0;
    overflow: hidden;
}
var camera, scene, renderer, controls, stats;

init();
animate();

function init() {
    renderer = new THREE.WebGLRenderer({
        antialias: true
    });
    renderer.setClearColor(0x000000);
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    scene = new THREE.Scene();
    scene.background = new THREE.Color(0x333399);

    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);

    var ambientLight = new THREE.AmbientLight(0x999999, 0.4);
    scene.add(ambientLight);

    var light0 = new THREE.PointLight(0x999999, 1, 0);
    light0.position.set(-100, -200, -100);
    scene.add(light0);

    controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.minDistance = 0.0;
    controls.maxDistance = 1000.0;
    controls.panSpeed = 0.1;
    controls.enableDamping = true;
    controls.dampingFactor = 0.1;
    controls.rotateSpeed = 0.1;

    window.addEventListener('resize', onWindowResize, false);

    stats = new Stats();
    document.body.appendChild(stats.dom);

    buildScene();
}

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
    requestAnimationFrame(animate);
    controls.update();

    stats.begin();
    renderer.render(scene, camera);
    stats.end();
}

function buildScene() {
    var pts = [];
    const divisions = 1024;
    const radius = 10.0;

    for (var d = 0; d < divisions; ++d) {

        var angle1 = (d / divisions) * Math.PI * 2;
        var angle2 = (d / divisions * 15.0) * Math.PI * 2;
        var x = Math.cos(angle1) * radius + Math.cos(angle2);
        var z = Math.sin(angle1) * radius + Math.sin(angle2);
        x = Math.cos(angle1) * radius;
        z = Math.sin(angle1) * radius;

        pts.push(new THREE.Vector2(x, z));
    }

    var shape = new THREE.Shape(pts);

    var extrudeSettings = {
        depth: 2.0,
        steps: 1,
        bevelEnabled: false,
        bevelThickness: 0.5,
        bevelSize: 0.21,
        bevelSegments: 1
    };
    var geometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings);

    const position = geometry.attributes.position;
    const colors = [];

    var color = new THREE.Color();

    for (var i = 0; i < position.count; i += 3) {

        var hue = Math.abs((i / position.count) - 0.5) * 2.0
        color.setHSL(hue, 1.0, 0.5)

        colors.push(color.r, color.g, color.b);
        colors.push(color.r, color.g, color.b);
        colors.push(color.r, color.g, color.b);
    }

    geometry.addAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

    geometry.computeBoundingSphere();
    fitCameraToObject(geometry);

    var material = new THREE.MeshPhongMaterial({
        vertexColors: THREE.VertexColors
    });

    var mesh = new THREE.Mesh(geometry, material);
    mesh.rotation.y = -Math.PI / 7.0;
    mesh.rotation.x = -Math.PI / 3.0;

    scene.add(mesh);
}

function fitCameraToObject(geometry) {
    var fudge_factor = 1.05;
    var bounding_sphere_radius = geometry.boundingSphere.radius;
    var container_aspect_ratio = window.innerHeight / window.innerWidth;

    if (container_aspect_ratio > 1) {
        bounding_sphere_radius = bounding_sphere_radius * container_aspect_ratio;
    }

    var dist = bounding_sphere_radius / Math.sin((camera.fov * (Math.PI / 180.0)) / 2);
    dist *= fudge_factor;

    camera.position.set(-dist, 0.0, 0.0);
}
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.