@@ -51,6 +51,8 @@ const FLOW_ACCEL_PER_SECOND = 0.018;
5151const FLOW_SPEED_MAX = 15.5 ;
5252const FLOW_DEPTH_SPAN = 320 ;
5353const FLOW_NEAR_LIMIT = 48 ;
54+ const CENTER_DEPTH = - 92 ;
55+ const CIRCUIT_COUNT = 68 ;
5456const PULSE_SPEED_BASE = 0.032 ;
5557const PULSE_SPEED_FLOW_GAIN = 0.0022 ;
5658
@@ -77,60 +79,62 @@ function pushPoint(points: THREE.Vector3[], point: THREE.Vector3) {
7779 }
7880}
7981
80- function randomShellPosition(radius : number ) {
81- const point = new THREE .Vector3 (
82- rand (- radius , radius ),
83- rand (- radius , radius ),
84- rand (- radius , radius ),
85- );
86- const dominantAxis = Math .floor (Math .random () * 3 );
87- const direction = Math .random () > 0.5 ? 1 : - 1 ;
88- if (dominantAxis === 0 ) point .x = direction * radius ;
89- if (dominantAxis === 1 ) point .y = direction * radius ;
90- if (dominantAxis === 2 ) point .z = direction * radius ;
91- return point ;
92- }
93-
9482function createOrthogonalPath() {
9583 const points: THREE .Vector3 [] = [];
96- const current = randomShellPosition ( rand ( 55 , 90 ) );
84+ const current = new THREE . Vector3 ( 0 , 0 , 0 );
9785 pushPoint (points , current .clone ());
9886
9987 let previousAxis = - 1 ;
100- const segmentCount = Math .floor (rand (8 , 15 ));
88+ const segmentCount = Math .floor (rand (10 , 18 ));
10189
10290 for (let i = 0 ; i < segmentCount ; i += 1 ) {
10391 const axis = pickAxis (previousAxis );
10492 previousAxis = axis ;
10593
10694 const next = current .clone ();
107- const axisValue = axis === 0 ? current .x : axis === 1 ? current .y : current .z ;
108- const towardCenter = Math .sign (- axisValue ) || (Math .random () > 0.5 ? 1 : - 1 );
109- const maxStep = Math .max (6 , Math .abs (axisValue ) * 0.85 );
110- const step = Math .min (rand (6 , 15 ), maxStep );
95+ const direction = Math .random () > 0.5 ? 1 : - 1 ;
96+ const step = rand (3.5 , 7.5 ) + i * 0.95 ;
11197
112- if (axis === 0 ) next .x += towardCenter * step ;
113- if (axis === 1 ) next .y += towardCenter * step ;
114- if (axis === 2 ) next .z += towardCenter * step ;
98+ if (axis === 0 ) next .x += direction * step ;
99+ if (axis === 1 ) next .y += direction * step ;
100+ if (axis === 2 ) next .z += direction * step ;
115101
116- next .x = THREE .MathUtils .clamp (next .x , - 95 , 95 );
117- next .y = THREE .MathUtils .clamp (next .y , - 95 , 95 );
118- next .z = THREE .MathUtils .clamp (next .z , - 95 , 95 );
102+ next .x = THREE .MathUtils .clamp (next .x , - 125 , 125 );
103+ next .y = THREE .MathUtils .clamp (next .y , - 125 , 125 );
104+ next .z = THREE .MathUtils .clamp (next .z , - 125 , 125 );
119105
120106 current .copy (next );
121107 pushPoint (points , current .clone ());
122108 }
123109
124- const axes = ([' x' , ' y' , ' z' ] as Array <' x' | ' y' | ' z' >).sort (() => Math .random () - 0.5 );
125- for (const axis of axes ) {
126- if (Math .abs (current [axis ]) <= 1 ) continue ;
110+ if (current .length () < 65 ) {
111+ const axes = ([' x' , ' y' , ' z' ] as Array <' x' | ' y' | ' z' >).sort (() => Math .random () - 0.5 );
112+ const boost = 65 - current .length () + rand (10 , 28 );
113+ for (const axis of axes ) {
114+ const next = current .clone ();
115+ const direction = Math .sign (current [axis ]) || (Math .random () > 0.5 ? 1 : - 1 );
116+ next [axis ] += direction * (boost / 3 );
117+ next .x = THREE .MathUtils .clamp (next .x , - 130 , 130 );
118+ next .y = THREE .MathUtils .clamp (next .y , - 130 , 130 );
119+ next .z = THREE .MathUtils .clamp (next .z , - 130 , 130 );
120+ current .copy (next );
121+ pushPoint (points , current .clone ());
122+ }
123+ }
124+
125+ const finalSpreadAxes = ([' x' , ' y' , ' z' ] as Array <' x' | ' y' | ' z' >).sort (() => Math .random () - 0.5 );
126+ for (const axis of finalSpreadAxes ) {
127+ if (Math .abs (current [axis ]) >= 118 ) continue ;
127128 const next = current .clone ();
128- next [axis ] = 0 ;
129+ const direction = Math .sign (current [axis ]) || (Math .random () > 0.5 ? 1 : - 1 );
130+ next [axis ] += direction * rand (8 , 20 );
131+ next .x = THREE .MathUtils .clamp (next .x , - 130 , 130 );
132+ next .y = THREE .MathUtils .clamp (next .y , - 130 , 130 );
133+ next .z = THREE .MathUtils .clamp (next .z , - 130 , 130 );
129134 current .copy (next );
130135 pushPoint (points , current .clone ());
131136 }
132137
133- pushPoint (points , new THREE .Vector3 (0 , 0 , 0 ));
134138 return points ;
135139}
136140
@@ -175,29 +179,28 @@ function addCenterHole() {
175179 if (! scene ) return ;
176180
177181 centerHole = new THREE .Mesh (
178- new THREE .SphereGeometry (8 , 48 , 48 ),
182+ new THREE .SphereGeometry (1.65 , 28 , 28 ),
179183 new THREE .MeshBasicMaterial ({ color: 0x020206 }),
180184 );
181185 scene .add (centerHole );
182186
183187 centerRing = new THREE .Mesh (
184- new THREE .RingGeometry (9.2 , 12.4 , 80 ),
188+ new THREE .RingGeometry (2.1 , 3.2 , 64 ),
185189 new THREE .MeshBasicMaterial ({
186190 color: 0x0f2a35 ,
187191 transparent: true ,
188- opacity: 0.45 ,
192+ opacity: 0.32 ,
189193 side: THREE .DoubleSide ,
190194 }),
191195 );
192- centerRing .rotation .x = Math .PI / 2 ;
193196 scene .add (centerRing );
194197
195198 centerHalo = new THREE .Mesh (
196- new THREE .SphereGeometry (13.5 , 36 , 36 ),
199+ new THREE .SphereGeometry (4.8 , 24 , 24 ),
197200 new THREE .MeshBasicMaterial ({
198201 color: 0x0a2734 ,
199202 transparent: true ,
200- opacity: 0.14 ,
203+ opacity: 0.09 ,
201204 depthWrite: false ,
202205 blending: THREE .AdditiveBlending ,
203206 }),
@@ -208,7 +211,7 @@ function addCenterHole() {
208211function createCircuitFlow() {
209212 if (! scene ) return ;
210213
211- for (let i = 0 ; i < 42 ; i += 1 ) {
214+ for (let i = 0 ; i < CIRCUIT_COUNT ; i += 1 ) {
212215 const pathPoints = createOrthogonalPath ();
213216 const sampler = createSampler (pathPoints );
214217 const group = new THREE .Group ();
@@ -387,19 +390,19 @@ function animate() {
387390 }
388391
389392 if (centerRing ) {
390- centerRing .position .copy (focalPoint );
393+ centerRing .position .set (focalPoint . x , focalPoint . y , CENTER_DEPTH );
391394 centerRing .rotation .z += delta * 0.06 ;
392395 const ringMaterial = centerRing .material as THREE .MeshBasicMaterial ;
393- ringMaterial .opacity = 0.3 + Math .sin (elapsed * 1.4 ) * 0.08 ;
396+ ringMaterial .opacity = 0.24 + Math .sin (elapsed * 1.4 ) * 0.05 ;
394397 }
395398 if (centerHalo ) {
396- centerHalo .position .copy (focalPoint );
399+ centerHalo .position .set (focalPoint . x , focalPoint . y , CENTER_DEPTH );
397400 const haloMaterial = centerHalo .material as THREE .MeshBasicMaterial ;
398- haloMaterial .opacity = 0.1 + Math .sin (elapsed * 1.1 ) * 0.04 ;
399- centerHalo .scale .setScalar (0.98 + Math .sin (elapsed * 0.9 ) * 0.03 );
401+ haloMaterial .opacity = 0.075 + Math .sin (elapsed * 1.1 ) * 0.028 ;
402+ centerHalo .scale .setScalar (0.96 + Math .sin (elapsed * 0.9 ) * 0.025 );
400403 }
401404 if (centerHole ) {
402- centerHole .position .copy (focalPoint );
405+ centerHole .position .set (focalPoint . x , focalPoint . y , CENTER_DEPTH );
403406 }
404407 } else if (legacyStars ) {
405408 legacyStars .rotation .y += delta * 0.03 ;
0 commit comments