|
18 | 18 | import * as THREE from '../build/three.module.js'; |
19 | 19 |
|
20 | 20 | import Stats from './jsm/libs/stats.module.js'; |
21 | | - import { GUI } from './jsm/libs/dat.gui.module.js'; |
22 | 21 |
|
23 | 22 | import { OrbitControls } from './jsm/controls/OrbitControls.js'; |
24 | 23 | import { RectAreaLightHelper } from './jsm/helpers/RectAreaLightHelper.js'; |
25 | 24 | import { RectAreaLightUniformsLib } from './jsm/lights/RectAreaLightUniformsLib.js'; |
26 | 25 |
|
27 | 26 | let renderer, scene, camera; |
28 | | - |
29 | | - const origin = new THREE.Vector3(); |
30 | | - |
31 | | - let rectLight, rectLightHelper; |
32 | | - |
33 | | - let param = {}; |
34 | 27 | let stats; |
35 | 28 |
|
36 | 29 | init(); |
37 | | - animate(); |
38 | 30 |
|
39 | 31 | function init() { |
40 | 32 |
|
41 | 33 | renderer = new THREE.WebGLRenderer( { antialias: true } ); |
42 | 34 | renderer.setPixelRatio( window.devicePixelRatio ); |
43 | 35 | renderer.setSize( window.innerWidth, window.innerHeight ); |
44 | | - renderer.shadowMap.enabled = true; |
45 | | - renderer.shadowMap.type = THREE.PCFSoftShadowMap; |
| 36 | + renderer.setAnimationLoop( animation ); |
46 | 37 | renderer.outputEncoding = THREE.sRGBEncoding; |
47 | 38 | document.body.appendChild( renderer.domElement ); |
48 | 39 |
|
49 | 40 | 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 ); |
51 | 42 |
|
52 | 43 | scene = new THREE.Scene(); |
53 | 44 |
|
54 | | - const ambient = new THREE.AmbientLight( 0xffffff, 0.1 ); |
55 | | - scene.add( ambient ); |
56 | | - |
57 | 45 | RectAreaLightUniformsLib.init(); |
58 | 46 |
|
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 ); |
62 | 50 |
|
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 ) ); |
65 | 62 |
|
66 | 63 | 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 } ); |
68 | 65 | const mshStdFloor = new THREE.Mesh( geoFloor, matStdFloor ); |
69 | 66 | scene.add( mshStdFloor ); |
70 | 67 |
|
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 ); |
94 | 74 |
|
95 | 75 | const controls = new OrbitControls( camera, renderer.domElement ); |
96 | | - controls.target.copy( mshStdBox.position ); |
| 76 | + controls.target.copy( meshKnot.position ); |
97 | 77 | controls.update(); |
98 | 78 |
|
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 | | - |
187 | 79 | // |
188 | 80 |
|
189 | 81 | window.addEventListener( 'resize', onResize, false ); |
|
201 | 93 |
|
202 | 94 | } |
203 | 95 |
|
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 ) { |
226 | 97 |
|
227 | | - rectLightHelper.update(); |
| 98 | + const mesh = scene.getObjectByName( 'meshKnot' ); |
| 99 | + mesh.rotation.y = time / 1000; |
228 | 100 |
|
229 | 101 | renderer.render( scene, camera ); |
230 | 102 |
|
|
0 commit comments