JSFiddle - React, Tailwind, and code Playground

by Kearnan Kelly

HTML

<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
    
<script type="importmap">
	{
		"imports": {
			"three": "https://unpkg.com/three/build/three.module.js",
      "cs": "https://unpkg.com/three/examples/jsm/controls/OrbitControls.js",
      "sky": "https://unpkg.com/three/examples/jsm/objects/Sky.js"
		}
	}
</script>

CSS

body {
	  margin: 0;
}

JavaScript

import * as THREE from 'three';
import {
  OrbitControls
} from 'cs';
import {
  Sky
} from 'sky';


// init

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animation);
document.body.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.04, 2000);
camera.position.set(0, 3, 10);
camera.lookAt(0, 0, 0);

new OrbitControls(camera, renderer.domElement);

const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry(3, 3, 3);
const material = new THREE.MeshStandardMaterial();

const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

const plane = new THREE.Mesh(new THREE.PlaneGeometry(1024, 1024), makeWaterMaterial(renderer));
plane.geometry.rotateX(-Math.PI / 2);
scene.add(plane);

const sky = new Sky();
sky.scale.setScalar(1000);
scene.add(sky);

const sun = new THREE.Vector3();
const phi = THREE.MathUtils.degToRad(85);
const theta = THREE.MathUtils.degToRad(180);
const uniforms = sky.material.uniforms;
uniforms.turbidity.value = 10;
uniforms.rayleigh.value = 3;
uniforms.mieCoefficient.value = 0.005;
uniforms.mieDirectionalG.value = 0.2;

sun.setFromSphericalCoords(1, phi, theta);
uniforms.sunPosition.value.copy(sun);

const light = new THREE.DirectionalLight();
light.position.copy(sun)
scene.add(light)

// animation

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}
window.addEventListener('resize', onWindowResize, false)

function animation(time) {

  mesh.rotation.x = time / 8000;
  mesh.rotation.y = time / 4000;
  mesh.position.y = Math.sin(time / 1000) / 2
  renderer.render(scene, camera);

}

// water shader

function makeWaterMaterial(renderer) {

  // make this work with WebGL1Renderer
  const...