|
|
@@ -33,12 +33,15 @@
|
|
|
import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js';
|
|
|
|
|
|
let renderer, scene, camera;
|
|
|
- let stats, meshKnot;
|
|
|
+ let rectLight1, rectLight2, rectLight3;
|
|
|
+ let timer, stats;
|
|
|
|
|
|
init();
|
|
|
|
|
|
function init() {
|
|
|
|
|
|
+ timer = new THREE.Timer();
|
|
|
+
|
|
|
renderer = new THREE.WebGLRenderer( { antialias: true } );
|
|
|
renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
@@ -52,16 +55,16 @@
|
|
|
|
|
|
RectAreaLightUniformsLib.init();
|
|
|
|
|
|
- const rectLight1 = new THREE.RectAreaLight( 0xff0000, 5, 4, 10 );
|
|
|
- rectLight1.position.set( - 5, 5, 5 );
|
|
|
+ rectLight1 = new THREE.RectAreaLight( 0xff0000, 5, 4, 10 );
|
|
|
+ rectLight1.position.set( - 5, 6, 5 );
|
|
|
scene.add( rectLight1 );
|
|
|
|
|
|
- const rectLight2 = new THREE.RectAreaLight( 0x00ff00, 5, 4, 10 );
|
|
|
- rectLight2.position.set( 0, 5, 5 );
|
|
|
+ rectLight2 = new THREE.RectAreaLight( 0x00ff00, 5, 4, 10 );
|
|
|
+ rectLight2.position.set( 0, 6, 5 );
|
|
|
scene.add( rectLight2 );
|
|
|
|
|
|
- const rectLight3 = new THREE.RectAreaLight( 0x0000ff, 5, 4, 10 );
|
|
|
- rectLight3.position.set( 5, 5, 5 );
|
|
|
+ rectLight3 = new THREE.RectAreaLight( 0x0000ff, 5, 4, 10 );
|
|
|
+ rectLight3.position.set( 5, 6, 5 );
|
|
|
scene.add( rectLight3 );
|
|
|
|
|
|
scene.add( new RectAreaLightHelper( rectLight1 ) );
|
|
|
@@ -69,14 +72,15 @@
|
|
|
scene.add( new RectAreaLightHelper( rectLight3 ) );
|
|
|
|
|
|
const geoFloor = new THREE.BoxGeometry( 2000, 0.1, 2000 );
|
|
|
- const matStdFloor = new THREE.MeshStandardMaterial( { color: 0xbcbcbc, roughness: 0.1, metalness: 0 } );
|
|
|
+ const matStdFloor = new THREE.MeshStandardMaterial( { color: 0x444444 } );
|
|
|
+ matStdFloor.roughnessMap = createCheckerTexture( 400 );
|
|
|
const mshStdFloor = new THREE.Mesh( geoFloor, matStdFloor );
|
|
|
scene.add( mshStdFloor );
|
|
|
|
|
|
const geoKnot = new THREE.TorusKnotGeometry( 1.5, 0.5, 200, 16 );
|
|
|
const matKnot = new THREE.MeshStandardMaterial( { color: 0xffffff, roughness: 0, metalness: 0 } );
|
|
|
- meshKnot = new THREE.Mesh( geoKnot, matKnot );
|
|
|
- meshKnot.position.set( 0, 5, 0 );
|
|
|
+ const meshKnot = new THREE.Mesh( geoKnot, matKnot );
|
|
|
+ meshKnot.position.set( 0, 5.5, 0 );
|
|
|
scene.add( meshKnot );
|
|
|
|
|
|
const controls = new OrbitControls( camera, renderer.domElement );
|
|
|
@@ -92,6 +96,29 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function createCheckerTexture( repeat = 1 ) {
|
|
|
+
|
|
|
+ const canvas = document.createElement( 'canvas' );
|
|
|
+ canvas.width = 2;
|
|
|
+ canvas.height = 2;
|
|
|
+
|
|
|
+ const ctx = canvas.getContext( '2d' );
|
|
|
+ ctx.fillStyle = '#000';
|
|
|
+ ctx.fillRect( 0, 0, 2, 2 );
|
|
|
+ ctx.fillStyle = '#fff';
|
|
|
+ ctx.fillRect( 0, 0, 1, 1 );
|
|
|
+ ctx.fillRect( 1, 1, 1, 1 );
|
|
|
+
|
|
|
+ const texture = new THREE.CanvasTexture( canvas );
|
|
|
+ texture.repeat.set( repeat, repeat );
|
|
|
+ texture.magFilter = THREE.NearestFilter;
|
|
|
+ texture.wrapS = THREE.RepeatWrapping;
|
|
|
+ texture.wrapT = THREE.RepeatWrapping;
|
|
|
+
|
|
|
+ return texture;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
function onWindowResize() {
|
|
|
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
@@ -100,9 +127,15 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
- function animation( time ) {
|
|
|
+ function animation() {
|
|
|
+
|
|
|
+ timer.update();
|
|
|
+
|
|
|
+ const delta = timer.getDelta();
|
|
|
|
|
|
- meshKnot.rotation.y = time / 1000;
|
|
|
+ rectLight1.rotation.y += - delta;
|
|
|
+ rectLight2.rotation.y += delta * .5;
|
|
|
+ rectLight3.rotation.y += delta;
|
|
|
|
|
|
renderer.render( scene, camera );
|
|
|
|