Skip to content

Commit 54191ed

Browse files
authored
Merge pull request #21016 from mrdoob/rectarealight
Simplified and improved RectAreaLight example
2 parents 4a8b1fa + 3d9eb83 commit 54191ed

File tree

3 files changed

+31
-158
lines changed

3 files changed

+31
-158
lines changed

examples/jsm/helpers/RectAreaLightHelper.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,12 @@ function RectAreaLightHelper( light, color ) {
4040

4141
this.add( new Mesh( geometry2, new MeshBasicMaterial( { side: BackSide, fog: false } ) ) );
4242

43-
this.update();
44-
4543
}
4644

4745
RectAreaLightHelper.prototype = Object.create( Line.prototype );
4846
RectAreaLightHelper.prototype.constructor = RectAreaLightHelper;
4947

50-
RectAreaLightHelper.prototype.update = function () {
48+
RectAreaLightHelper.prototype.updateMatrixWorld = function () {
5149

5250
this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
5351

@@ -69,6 +67,9 @@ RectAreaLightHelper.prototype.update = function () {
6967

7068
}
7169

70+
this.matrixWorld.copy( this.light.matrixWorld ).scale( this.scale );
71+
this.children[ 0 ].matrixWorld.copy( this.matrixWorld );
72+
7273
};
7374

7475
RectAreaLightHelper.prototype.dispose = function () {
11.4 KB
Loading

examples/webgl_lights_rectarealight.html

Lines changed: 27 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -18,172 +18,64 @@
1818
import * as THREE from '../build/three.module.js';
1919

2020
import Stats from './jsm/libs/stats.module.js';
21-
import { GUI } from './jsm/libs/dat.gui.module.js';
2221

2322
import { OrbitControls } from './jsm/controls/OrbitControls.js';
2423
import { RectAreaLightHelper } from './jsm/helpers/RectAreaLightHelper.js';
2524
import { RectAreaLightUniformsLib } from './jsm/lights/RectAreaLightUniformsLib.js';
2625

2726
let renderer, scene, camera;
28-
29-
const origin = new THREE.Vector3();
30-
31-
let rectLight, rectLightHelper;
32-
33-
let param = {};
3427
let stats;
3528

3629
init();
37-
animate();
3830

3931
function init() {
4032

4133
renderer = new THREE.WebGLRenderer( { antialias: true } );
4234
renderer.setPixelRatio( window.devicePixelRatio );
4335
renderer.setSize( window.innerWidth, window.innerHeight );
44-
renderer.shadowMap.enabled = true;
45-
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
36+
renderer.setAnimationLoop( animation );
4637
renderer.outputEncoding = THREE.sRGBEncoding;
4738
document.body.appendChild( renderer.domElement );
4839

4940
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
50-
camera.position.set( 0, 20, 35 );
41+
camera.position.set( 0, 5, - 15 );
5142

5243
scene = new THREE.Scene();
5344

54-
const ambient = new THREE.AmbientLight( 0xffffff, 0.1 );
55-
scene.add( ambient );
56-
5745
RectAreaLightUniformsLib.init();
5846

59-
rectLight = new THREE.RectAreaLight( 0xffffff, 1, 10, 10 );
60-
rectLight.position.set( 5, 5, 0 );
61-
scene.add( rectLight );
47+
const rectLight1 = new THREE.RectAreaLight( 0xff0000, 5, 4, 10 );
48+
rectLight1.position.set( - 5, 5, 5 );
49+
scene.add( rectLight1 );
6250

63-
rectLightHelper = new RectAreaLightHelper( rectLight );
64-
rectLight.add( rectLightHelper );
51+
const rectLight2 = new THREE.RectAreaLight( 0x00ff00, 5, 4, 10 );
52+
rectLight2.position.set( 0, 5, 5 );
53+
scene.add( rectLight2 );
54+
55+
const rectLight3 = new THREE.RectAreaLight( 0x0000ff, 5, 4, 10 );
56+
rectLight3.position.set( 5, 5, 5 );
57+
scene.add( rectLight3 );
58+
59+
scene.add( new RectAreaLightHelper( rectLight1 ) );
60+
scene.add( new RectAreaLightHelper( rectLight2 ) );
61+
scene.add( new RectAreaLightHelper( rectLight3 ) );
6562

6663
const geoFloor = new THREE.BoxBufferGeometry( 2000, 0.1, 2000 );
67-
const matStdFloor = new THREE.MeshStandardMaterial( { color: 0x808080, roughness: 0, metalness: 0 } );
64+
const matStdFloor = new THREE.MeshStandardMaterial( { color: 0x808080, roughness: 0.1, metalness: 0 } );
6865
const mshStdFloor = new THREE.Mesh( geoFloor, matStdFloor );
6966
scene.add( mshStdFloor );
7067

71-
const matStdObjects = new THREE.MeshStandardMaterial( { color: 0xA00000, roughness: 0, metalness: 0 } );
72-
73-
const geoBox = new THREE.BoxBufferGeometry( Math.PI, Math.sqrt( 2 ), Math.E );
74-
const mshStdBox = new THREE.Mesh( geoBox, matStdObjects );
75-
mshStdBox.position.set( 0, 5, 0 );
76-
mshStdBox.rotation.set( 0, Math.PI / 2.0, 0 );
77-
mshStdBox.castShadow = true;
78-
mshStdBox.receiveShadow = true;
79-
scene.add( mshStdBox );
80-
81-
const geoSphere = new THREE.SphereBufferGeometry( 1.5, 32, 32 );
82-
const mshStdSphere = new THREE.Mesh( geoSphere, matStdObjects );
83-
mshStdSphere.position.set( - 5, 5, 0 );
84-
mshStdSphere.castShadow = true;
85-
mshStdSphere.receiveShadow = true;
86-
scene.add( mshStdSphere );
87-
88-
const geoKnot = new THREE.TorusKnotBufferGeometry( 1.5, 0.5, 100, 16 );
89-
const mshStdKnot = new THREE.Mesh( geoKnot, matStdObjects );
90-
mshStdKnot.position.set( 5, 5, 0 );
91-
mshStdKnot.castShadow = true;
92-
mshStdKnot.receiveShadow = true;
93-
scene.add( mshStdKnot );
68+
const geoKnot = new THREE.TorusKnotBufferGeometry( 1.5, 0.5, 200, 16 );
69+
const matKnot = new THREE.MeshStandardMaterial( { color: 0xffffff, roughness: 0, metalness: 0 } );
70+
const meshKnot = new THREE.Mesh( geoKnot, matKnot );
71+
meshKnot.name = 'meshKnot';
72+
meshKnot.position.set( 0, 5, 0 );
73+
scene.add( meshKnot );
9474

9575
const controls = new OrbitControls( camera, renderer.domElement );
96-
controls.target.copy( mshStdBox.position );
76+
controls.target.copy( meshKnot.position );
9777
controls.update();
9878

99-
// GUI
100-
101-
const gui = new GUI( { width: 300 } );
102-
gui.open();
103-
104-
param = {
105-
motion: true,
106-
width: rectLight.width,
107-
height: rectLight.height,
108-
color: rectLight.color.getHex(),
109-
intensity: rectLight.intensity,
110-
'ambient': ambient.intensity,
111-
'floor color': matStdFloor.color.getHex(),
112-
'object color': matStdObjects.color.getHex(),
113-
'roughness': matStdFloor.roughness,
114-
'metalness': matStdFloor.metalness
115-
};
116-
117-
gui.add( param, 'motion' );
118-
119-
const lightFolder = gui.addFolder( 'Light' );
120-
121-
lightFolder.add( param, 'width', 1, 20 ).step( 0.1 ).onChange( function ( val ) {
122-
123-
rectLight.width = val;
124-
125-
} );
126-
127-
lightFolder.add( param, 'height', 1, 20 ).step( 0.1 ).onChange( function ( val ) {
128-
129-
rectLight.height = val;
130-
131-
} );
132-
133-
lightFolder.addColor( param, 'color' ).onChange( function ( val ) {
134-
135-
rectLight.color.setHex( val );
136-
137-
} );
138-
139-
lightFolder.add( param, 'intensity', 0.0, 4.0 ).step( 0.01 ).onChange( function ( val ) {
140-
141-
rectLight.intensity = val;
142-
143-
} );
144-
145-
lightFolder.add( param, 'ambient', 0.0, 0.2 ).step( 0.01 ).onChange( function ( val ) {
146-
147-
ambient.intensity = val;
148-
149-
} );
150-
151-
lightFolder.open();
152-
153-
const standardFolder = gui.addFolder( 'Standard Material' );
154-
155-
standardFolder.addColor( param, 'floor color' ).onChange( function ( val ) {
156-
157-
matStdFloor.color.setHex( val );
158-
159-
} );
160-
161-
standardFolder.addColor( param, 'object color' ).onChange( function ( val ) {
162-
163-
matStdObjects.color.setHex( val );
164-
165-
} );
166-
167-
standardFolder.add( param, 'roughness', 0.0, 1.0 ).step( 0.01 ).onChange( function ( val ) {
168-
169-
matStdObjects.roughness = val;
170-
matStdFloor.roughness = val;
171-
172-
} );
173-
174-
// TODO (abelnation): use env map to reflect metal property
175-
standardFolder.add( param, 'metalness', 0.0, 1.0 ).step( 0.01 ).onChange( function ( val ) {
176-
177-
matStdObjects.metalness = val;
178-
matStdFloor.metalness = val;
179-
180-
} );
181-
182-
standardFolder.open();
183-
184-
// TODO: rect area light distance
185-
// TODO: rect area light decay
186-
18779
//
18880

18981
window.addEventListener( 'resize', onResize, false );
@@ -201,30 +93,10 @@
20193

20294
}
20395

204-
function animate() {
205-
206-
requestAnimationFrame( animate );
207-
208-
if ( param.motion ) {
209-
210-
const t = ( Date.now() / 2000 );
211-
212-
// move light in circle around center
213-
// change light height with sine curve
214-
215-
const r = 15.0;
216-
217-
const lx = r * Math.cos( t );
218-
const lz = r * Math.sin( t );
219-
220-
const ly = 5.0 + 5.0 * Math.sin( t / 3.0 );
221-
222-
rectLight.position.set( lx, ly, lz );
223-
rectLight.lookAt( origin );
224-
225-
}
96+
function animation( time ) {
22697

227-
rectLightHelper.update();
98+
const mesh = scene.getObjectByName( 'meshKnot' );
99+
mesh.rotation.y = time / 1000;
228100

229101
renderer.render( scene, camera );
230102

0 commit comments

Comments
 (0)