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>
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...