@@ -6,6 +6,11 @@ export class ThreeScene {
66 readonly renderer :THREE . WebGLRenderer ;
77 readonly objHolder :THREE . Object3D ;
88 private clock :THREE . Clock ;
9+ readonly ambientLight :THREE . AmbientLight ;
10+ private objs :THREE . Mesh [ ] = [ ]
11+ readonly pointLight :THREE . PointLight ;
12+ private mouse :THREE . Vector2 = new THREE . Vector2 ( ) ;
13+ rotationSpeed = 1 ;
914
1015 constructor ( ) {
1116 this . scene = new THREE . Scene ( ) ;
@@ -18,26 +23,70 @@ export class ThreeScene {
1823 this . objHolder = new THREE . Object3D ( ) ;
1924 this . clock = new THREE . Clock ( ) ;
2025
26+ this . ambientLight = new THREE . AmbientLight ( 0xffffff , 0.1 ) ;
27+ this . pointLight = new THREE . PointLight ( 0xffffff , 5 , 15 ) ;
28+
29+ window . addEventListener ( 'mousemove' , ( event ) => {
30+ // Normalize mouse coordinates to [-1, 1]
31+ this . mouse . x = ( event . clientX / window . innerWidth ) * 2 - 1 ;
32+ this . mouse . y = - ( event . clientY / window . innerHeight ) * 2 + 1 ;
33+ } ) ;
34+
2135 this . buildScene ( )
2236 }
2337
2438 protected buildScene ( ) {
2539 const geometry = new THREE . BoxGeometry ( 1 , 1 , 1 ) ;
26- const material = new THREE . MeshBasicMaterial ( { color : 0x000000 } ) ;
40+ const material = new THREE . MeshStandardMaterial ( { color : 0xcccccc } ) ;
2741 const cube = new THREE . Mesh ( geometry , material ) ;
2842
2943 this . objHolder . add ( cube ) ;
3044 this . scene . add ( this . objHolder )
3145
32- this . camera . position . z = 5 ;
46+ this . camera . position . z = 4 ;
3347 this . camera . position . x = - 4 ;
48+
49+ this . scene . add ( this . ambientLight ) ;
50+ this . objs . push ( cube ) ;
51+
52+ const dirLight = new THREE . DirectionalLight ( )
53+ this . scene . add ( dirLight ) ;
54+
55+ this . scene . add ( this . pointLight ) ;
56+
57+ this . pointLight . intensity = 3
58+ this . pointLight . position . z = 3
59+ }
60+
61+ private updateLightPosition ( ) {
62+ // Create a Vector3 with normalized mouse coordinates
63+ const vector = new THREE . Vector3 ( this . mouse . x , this . mouse . y , 0.5 ) ; // Z = 0.5 in NDC (midway in the frustum)
64+
65+ // Unproject the vector to world space using the camera
66+ vector . unproject ( this . camera ) ;
67+
68+ // Calculate the direction from the camera to the unprojected point
69+ const dir = vector . sub ( this . camera . position ) . normalize ( ) ;
70+
71+ // We want the light to be at a fixed Z in world space (e.g., Z = 2)
72+ const fixedZ = 2 ;
73+
74+ // Calculate the distance from the camera to the plane at fixedZ
75+ const distance = ( fixedZ - this . camera . position . z ) / dir . z ;
76+
77+ // Calculate the world position at the fixed Z plane
78+ const pos = this . camera . position . clone ( ) . add ( dir . multiplyScalar ( distance ) ) ;
79+
80+ // Update the light's position
81+ this . pointLight . position . set ( pos . x , pos . y , fixedZ ) ;
3482 }
3583
3684 render ( ) {
3785
3886 const delta = this . clock . getDelta ( )
39- this . objHolder . rotateY ( delta )
40- this . objHolder . rotateX ( delta )
87+ this . updateLightPosition ( ) ;
88+ this . objHolder . rotateY ( delta * this . rotationSpeed )
89+ this . objHolder . rotateX ( delta * this . rotationSpeed )
4190 this . renderer . render ( this . scene , this . camera ) ;
4291 }
4392}
0 commit comments