@lark-apaas/coding-steering 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,668 @@
1
+ # React Three Fiber Lighting
2
+
3
+ ## Quick Start
4
+
5
+ ```tsx
6
+ import { Canvas } from '@react-three/fiber'
7
+
8
+ function Scene() {
9
+ return (
10
+ <Canvas shadows>
11
+ {/* Ambient fill */}
12
+ <ambientLight intensity={0.5} />
13
+
14
+ {/* Main light with shadows */}
15
+ <directionalLight
16
+ position={[5, 5, 5]}
17
+ intensity={1}
18
+ castShadow
19
+ shadow-mapSize={[2048, 2048]}
20
+ />
21
+
22
+ {/* Objects */}
23
+ <mesh castShadow receiveShadow>
24
+ <boxGeometry />
25
+ <meshStandardMaterial color="orange" />
26
+ </mesh>
27
+
28
+ {/* Ground */}
29
+ <mesh receiveShadow rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
30
+ <planeGeometry args={[10, 10]} />
31
+ <meshStandardMaterial color="#888" />
32
+ </mesh>
33
+ </Canvas>
34
+ )
35
+ }
36
+ ```
37
+
38
+ ## Light Types Overview
39
+
40
+ | Light | Description | Shadow Support | Cost |
41
+ |-------|-------------|----------------|------|
42
+ | ambientLight | Uniform everywhere | No | Very Low |
43
+ | hemisphereLight | Sky/ground gradient | No | Very Low |
44
+ | directionalLight | Parallel rays (sun) | Yes | Low |
45
+ | pointLight | Omnidirectional (bulb) | Yes | Medium |
46
+ | spotLight | Cone-shaped | Yes | Medium |
47
+ | rectAreaLight | Area light (window) | No* | High |
48
+
49
+ ## ambientLight
50
+
51
+ Illuminates all objects equally. No direction, no shadows.
52
+
53
+ ```tsx
54
+ <ambientLight
55
+ color="#ffffff" // or color={new THREE.Color('#ffffff')}
56
+ intensity={0.5}
57
+ />
58
+ ```
59
+
60
+ ## hemisphereLight
61
+
62
+ Gradient from sky to ground. Good for outdoor scenes.
63
+
64
+ ```tsx
65
+ <hemisphereLight
66
+ color="#87ceeb" // Sky color
67
+ groundColor="#8b4513" // Ground color
68
+ intensity={0.6}
69
+ position={[0, 50, 0]}
70
+ />
71
+ ```
72
+
73
+ ## directionalLight
74
+
75
+ Parallel light rays. Simulates distant light (sun).
76
+
77
+ ```tsx
78
+ <directionalLight
79
+ color="#ffffff"
80
+ intensity={1}
81
+ position={[5, 10, 5]}
82
+
83
+ // Shadow configuration
84
+ castShadow
85
+ shadow-mapSize={[2048, 2048]}
86
+ shadow-camera-near={0.5}
87
+ shadow-camera-far={50}
88
+ shadow-camera-left={-10}
89
+ shadow-camera-right={10}
90
+ shadow-camera-top={10}
91
+ shadow-camera-bottom={-10}
92
+ shadow-bias={-0.0001}
93
+ shadow-normalBias={0.02}
94
+ />
95
+
96
+ // With target (light points at target)
97
+ function DirectionalWithTarget() {
98
+ const lightRef = useRef()
99
+
100
+ return (
101
+ <>
102
+ <directionalLight
103
+ ref={lightRef}
104
+ position={[5, 10, 5]}
105
+ target-position={[0, 0, 0]}
106
+ />
107
+ </>
108
+ )
109
+ }
110
+ ```
111
+
112
+ ## pointLight
113
+
114
+ Emits light in all directions. Like a light bulb.
115
+
116
+ ```tsx
117
+ <pointLight
118
+ color="#ffffff"
119
+ intensity={1}
120
+ position={[0, 5, 0]}
121
+ distance={100} // Maximum range (0 = infinite)
122
+ decay={2} // Light falloff (physically correct = 2)
123
+
124
+ // Shadows
125
+ castShadow
126
+ shadow-mapSize={[1024, 1024]}
127
+ shadow-camera-near={0.5}
128
+ shadow-camera-far={50}
129
+ shadow-bias={-0.005}
130
+ />
131
+ ```
132
+
133
+ ## spotLight
134
+
135
+ Cone-shaped light. Like a flashlight.
136
+
137
+ ```tsx
138
+ <spotLight
139
+ color="#ffffff"
140
+ intensity={1}
141
+ position={[0, 10, 0]}
142
+ angle={Math.PI / 6} // Cone angle (max Math.PI/2)
143
+ penumbra={0.5} // Soft edge (0-1)
144
+ distance={100} // Range
145
+ decay={2} // Falloff
146
+
147
+ // Target
148
+ target-position={[0, 0, 0]}
149
+
150
+ // Shadows
151
+ castShadow
152
+ shadow-mapSize={[1024, 1024]}
153
+ shadow-camera-near={0.5}
154
+ shadow-camera-far={50}
155
+ shadow-camera-fov={30}
156
+ shadow-bias={-0.0001}
157
+ />
158
+
159
+ // SpotLight helper
160
+ import { useHelper } from '@react-three/drei'
161
+ import { SpotLightHelper } from 'three'
162
+
163
+ function SpotLightWithHelper() {
164
+ const lightRef = useRef()
165
+ useHelper(lightRef, SpotLightHelper, 'cyan')
166
+
167
+ return <spotLight ref={lightRef} position={[0, 5, 0]} />
168
+ }
169
+ ```
170
+
171
+ ## rectAreaLight
172
+
173
+ Rectangular area light. Great for soft, realistic lighting.
174
+
175
+ ```tsx
176
+ import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper'
177
+
178
+ function AreaLight() {
179
+ const lightRef = useRef()
180
+
181
+ return (
182
+ <>
183
+ <rectAreaLight
184
+ ref={lightRef}
185
+ color="#ffffff"
186
+ intensity={5}
187
+ width={4}
188
+ height={2}
189
+ position={[0, 5, 0]}
190
+ rotation={[-Math.PI / 2, 0, 0]} // Point downward
191
+ />
192
+ </>
193
+ )
194
+ }
195
+
196
+ // Note: RectAreaLight only works with MeshStandardMaterial and MeshPhysicalMaterial
197
+ // Does not cast shadows natively
198
+ ```
199
+
200
+ ## Shadow Setup
201
+
202
+ ### Enable Shadows on Canvas
203
+
204
+ ```tsx
205
+ <Canvas
206
+ shadows // or shadows="soft" | "basic" | "percentage" | "variance"
207
+ >
208
+ ```
209
+
210
+ ### Shadow Types
211
+
212
+ ```tsx
213
+ // Basic shadows (fastest, hard edges)
214
+ <Canvas shadows="basic">
215
+
216
+ // PCF shadows (default, filtered)
217
+ <Canvas shadows>
218
+
219
+ // Soft shadows (PCFSoft, softer edges)
220
+ <Canvas shadows="soft">
221
+
222
+ // VSM shadows (variance shadow map)
223
+ <Canvas shadows="variance">
224
+ ```
225
+
226
+ ### Configure Shadow-Casting Objects
227
+
228
+ ```tsx
229
+ // Light must cast shadows
230
+ <directionalLight castShadow />
231
+
232
+ // Objects must cast and/or receive shadows
233
+ <mesh castShadow receiveShadow>
234
+ <boxGeometry />
235
+ <meshStandardMaterial />
236
+ </mesh>
237
+
238
+ // Ground typically only receives
239
+ <mesh receiveShadow>
240
+ <planeGeometry args={[100, 100]} />
241
+ <meshStandardMaterial />
242
+ </mesh>
243
+ ```
244
+
245
+ ### Shadow Camera Helper
246
+
247
+ ```tsx
248
+ import { useHelper } from '@react-three/drei'
249
+ import { CameraHelper } from 'three'
250
+
251
+ function LightWithShadowHelper() {
252
+ const lightRef = useRef()
253
+
254
+ // Visualize shadow camera frustum
255
+ useHelper(lightRef.current?.shadow.camera, CameraHelper)
256
+
257
+ return (
258
+ <directionalLight
259
+ ref={lightRef}
260
+ castShadow
261
+ shadow-camera-left={-10}
262
+ shadow-camera-right={10}
263
+ shadow-camera-top={10}
264
+ shadow-camera-bottom={-10}
265
+ />
266
+ )
267
+ }
268
+ ```
269
+
270
+ ## Drei Lighting Helpers
271
+
272
+ ### Environment
273
+
274
+ HDR environment lighting with presets or custom files.
275
+
276
+ ```tsx
277
+ import { Environment } from '@react-three/drei'
278
+
279
+ // Preset environments
280
+ <Environment
281
+ preset="sunset" // apartment, city, dawn, forest, lobby, night, park, studio, sunset, warehouse
282
+ background // Also use as background
283
+ backgroundBlurriness={0} // Background blur
284
+ backgroundIntensity={1} // Background brightness
285
+ environmentIntensity={1} // Lighting intensity
286
+ />
287
+
288
+ // Custom HDR file
289
+ <Environment files="/hdri/studio.hdr" />
290
+
291
+ // Cube map (6 images)
292
+ <Environment
293
+ files={['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']}
294
+ path="/textures/cube/"
295
+ />
296
+
297
+ // Ground projection
298
+ <Environment
299
+ preset="city"
300
+ ground={{
301
+ height: 15,
302
+ radius: 100,
303
+ scale: 100,
304
+ }}
305
+ />
306
+ ```
307
+
308
+ ### Lightformer
309
+
310
+ Create custom light shapes inside Environment.
311
+
312
+ ```tsx
313
+ import { Environment, Lightformer } from '@react-three/drei'
314
+
315
+ <Environment>
316
+ <Lightformer
317
+ form="ring" // circle, ring, rect
318
+ intensity={2}
319
+ color="white"
320
+ scale={10}
321
+ position={[0, 5, -5]}
322
+ target={[0, 0, 0]} // Point at target
323
+ />
324
+
325
+ <Lightformer
326
+ form="rect"
327
+ intensity={1}
328
+ color="red"
329
+ scale={[5, 2]}
330
+ position={[-5, 5, 0]}
331
+ />
332
+ </Environment>
333
+ ```
334
+
335
+ ### Sky
336
+
337
+ Procedural sky with sun.
338
+
339
+ ```tsx
340
+ import { Sky } from '@react-three/drei'
341
+
342
+ <Sky
343
+ distance={450000}
344
+ sunPosition={[0, 1, 0]} // Or calculate from inclination/azimuth
345
+ inclination={0.6} // Sun elevation (0 = horizon, 0.5 = zenith)
346
+ azimuth={0.25} // Sun rotation around horizon
347
+ turbidity={10} // Haziness
348
+ rayleigh={2} // Light scattering
349
+ mieCoefficient={0.005}
350
+ mieDirectionalG={0.8}
351
+ />
352
+ ```
353
+
354
+ ### Stars
355
+
356
+ Starfield background.
357
+
358
+ ```tsx
359
+ import { Stars } from '@react-three/drei'
360
+
361
+ <Stars
362
+ radius={100} // Sphere radius
363
+ depth={50} // Depth of star distribution
364
+ count={5000} // Number of stars
365
+ factor={4} // Size factor
366
+ saturation={0} // Color saturation
367
+ fade // Fade at edges
368
+ speed={1} // Twinkle speed
369
+ />
370
+ ```
371
+
372
+ ### Stage
373
+
374
+ Quick lighting setup for product showcase.
375
+
376
+ ```tsx
377
+ import { Stage } from '@react-three/drei'
378
+
379
+ <Stage
380
+ preset="rembrandt" // rembrandt, portrait, upfront, soft
381
+ intensity={1}
382
+ shadows="contact" // false, 'contact', 'accumulative', true
383
+ environment="city"
384
+ adjustCamera={1.2} // Adjust camera to fit content
385
+ >
386
+ <Model />
387
+ </Stage>
388
+ ```
389
+
390
+ ### ContactShadows
391
+
392
+ Fast fake shadows without shadow mapping.
393
+
394
+ ```tsx
395
+ import { ContactShadows } from '@react-three/drei'
396
+
397
+ <ContactShadows
398
+ position={[0, -0.5, 0]}
399
+ opacity={0.5}
400
+ scale={10}
401
+ blur={1}
402
+ far={10}
403
+ resolution={256}
404
+ color="#000000"
405
+ frames={1} // Render once (for static scenes)
406
+ />
407
+
408
+ // For animated scenes
409
+ <ContactShadows frames={Infinity} />
410
+ ```
411
+
412
+ ### AccumulativeShadows
413
+
414
+ Soft, accumulated shadows.
415
+
416
+ ```tsx
417
+ import { AccumulativeShadows, RandomizedLight } from '@react-three/drei'
418
+
419
+ <AccumulativeShadows
420
+ position={[0, -0.5, 0]}
421
+ scale={10}
422
+ color="#316d39"
423
+ opacity={0.8}
424
+ frames={100}
425
+ temporal // Smooth accumulation over time
426
+ >
427
+ <RandomizedLight
428
+ amount={8}
429
+ radius={4}
430
+ ambient={0.5}
431
+ intensity={1}
432
+ position={[5, 5, -10]}
433
+ bias={0.001}
434
+ />
435
+ </AccumulativeShadows>
436
+ ```
437
+
438
+ ### SoftShadows
439
+
440
+ Enable PCF soft shadows globally.
441
+
442
+ ```tsx
443
+ import { SoftShadows } from '@react-three/drei'
444
+
445
+ <Canvas shadows>
446
+ <SoftShadows
447
+ size={25}
448
+ samples={10}
449
+ focus={0}
450
+ />
451
+ </Canvas>
452
+ ```
453
+
454
+ ### BakeShadows
455
+
456
+ Bake shadows for static scenes.
457
+
458
+ ```tsx
459
+ import { BakeShadows } from '@react-three/drei'
460
+
461
+ <Canvas shadows>
462
+ <BakeShadows /> {/* Bakes shadows once on mount */}
463
+ </Canvas>
464
+ ```
465
+
466
+ ## Common Lighting Setups
467
+
468
+ ### Three-Point Lighting
469
+
470
+ ```tsx
471
+ function ThreePointLighting() {
472
+ return (
473
+ <>
474
+ {/* Key light (main) */}
475
+ <directionalLight
476
+ position={[5, 5, 5]}
477
+ intensity={1}
478
+ castShadow
479
+ />
480
+
481
+ {/* Fill light (softer, opposite side) */}
482
+ <directionalLight
483
+ position={[-5, 3, 5]}
484
+ intensity={0.5}
485
+ />
486
+
487
+ {/* Back light (rim lighting) */}
488
+ <directionalLight
489
+ position={[0, 5, -5]}
490
+ intensity={0.3}
491
+ />
492
+
493
+ {/* Ambient fill */}
494
+ <ambientLight intensity={0.2} />
495
+ </>
496
+ )
497
+ }
498
+ ```
499
+
500
+ ### Outdoor Daylight
501
+
502
+ ```tsx
503
+ import { Sky, Environment } from '@react-three/drei'
504
+
505
+ function OutdoorLighting() {
506
+ return (
507
+ <>
508
+ <Sky sunPosition={[100, 100, 100]} />
509
+ <Environment preset="dawn" />
510
+
511
+ <directionalLight
512
+ position={[50, 100, 50]}
513
+ intensity={1.5}
514
+ castShadow
515
+ shadow-mapSize={[2048, 2048]}
516
+ shadow-camera-far={200}
517
+ shadow-camera-left={-50}
518
+ shadow-camera-right={50}
519
+ shadow-camera-top={50}
520
+ shadow-camera-bottom={-50}
521
+ />
522
+
523
+ <hemisphereLight
524
+ color="#87ceeb"
525
+ groundColor="#8b4513"
526
+ intensity={0.5}
527
+ />
528
+ </>
529
+ )
530
+ }
531
+ ```
532
+
533
+ ### Studio Lighting
534
+
535
+ ```tsx
536
+ import { Environment, Lightformer, ContactShadows } from '@react-three/drei'
537
+
538
+ function StudioLighting() {
539
+ return (
540
+ <>
541
+ <Environment resolution={256}>
542
+ {/* Key light */}
543
+ <Lightformer
544
+ form="rect"
545
+ intensity={4}
546
+ position={[5, 5, -5]}
547
+ scale={[10, 5]}
548
+ target={[0, 0, 0]}
549
+ />
550
+
551
+ {/* Fill light */}
552
+ <Lightformer
553
+ form="rect"
554
+ intensity={2}
555
+ position={[-5, 5, 5]}
556
+ scale={[10, 5]}
557
+ />
558
+
559
+ {/* Rim light */}
560
+ <Lightformer
561
+ form="ring"
562
+ intensity={1}
563
+ position={[0, 5, -10]}
564
+ scale={5}
565
+ />
566
+ </Environment>
567
+
568
+ <ContactShadows
569
+ position={[0, -0.5, 0]}
570
+ opacity={0.5}
571
+ blur={2}
572
+ />
573
+ </>
574
+ )
575
+ }
576
+ ```
577
+
578
+ ## Animated Lighting
579
+
580
+ ```tsx
581
+ import { useFrame } from '@react-three/fiber'
582
+ import { useRef } from 'react'
583
+
584
+ function AnimatedLight() {
585
+ const lightRef = useRef()
586
+
587
+ useFrame(({ clock }) => {
588
+ const t = clock.elapsedTime
589
+
590
+ // Orbit around scene
591
+ lightRef.current.position.x = Math.cos(t) * 5
592
+ lightRef.current.position.z = Math.sin(t) * 5
593
+
594
+ // Pulsing intensity
595
+ lightRef.current.intensity = 1 + Math.sin(t * 2) * 0.5
596
+
597
+ // Color cycling
598
+ lightRef.current.color.setHSL((t * 0.1) % 1, 1, 0.5)
599
+ })
600
+
601
+ return (
602
+ <pointLight ref={lightRef} position={[5, 3, 0]} castShadow />
603
+ )
604
+ }
605
+ ```
606
+
607
+ ## Light Helpers
608
+
609
+ ```tsx
610
+ import { useHelper } from '@react-three/drei'
611
+ import {
612
+ DirectionalLightHelper,
613
+ PointLightHelper,
614
+ SpotLightHelper,
615
+ HemisphereLightHelper,
616
+ } from 'three'
617
+
618
+ function LightWithHelpers() {
619
+ const dirLightRef = useRef()
620
+ const pointLightRef = useRef()
621
+ const spotLightRef = useRef()
622
+ const hemiLightRef = useRef()
623
+
624
+ useHelper(dirLightRef, DirectionalLightHelper, 5, 'red')
625
+ useHelper(pointLightRef, PointLightHelper, 1, 'green')
626
+ useHelper(spotLightRef, SpotLightHelper, 'blue')
627
+ useHelper(hemiLightRef, HemisphereLightHelper, 5, 'yellow', 'brown')
628
+
629
+ return (
630
+ <>
631
+ <directionalLight ref={dirLightRef} position={[5, 5, 5]} />
632
+ <pointLight ref={pointLightRef} position={[-5, 5, 0]} />
633
+ <spotLight ref={spotLightRef} position={[0, 5, 5]} />
634
+ <hemisphereLight ref={hemiLightRef} />
635
+ </>
636
+ )
637
+ }
638
+ ```
639
+
640
+ ## Performance Tips
641
+
642
+ 1. **Limit light count**: Each light adds shader complexity
643
+ 2. **Use baked lighting**: For static scenes
644
+ 3. **Smaller shadow maps**: 512-1024 often sufficient
645
+ 4. **Tight shadow frustums**: Only cover needed area
646
+ 5. **Disable unused shadows**: Not all lights need shadows
647
+ 6. **Use Environment**: More efficient than many lights
648
+
649
+ ```tsx
650
+ // Selective shadows
651
+ <mesh castShadow={isHero}>
652
+ <boxGeometry />
653
+ </mesh>
654
+
655
+ // Only update shadows when needed
656
+ <ContactShadows frames={isAnimating ? Infinity : 1} />
657
+
658
+ // Use layers to exclude objects from lights
659
+ <directionalLight layers={1} />
660
+ <mesh layers={1}> {/* Affected by light */}
661
+ <mesh layers={2}> {/* Not affected */}
662
+ ```
663
+
664
+ ## See Also
665
+
666
+ - `r3f-materials` - Material light response
667
+ - `r3f-textures` - Environment maps
668
+ - `r3f-postprocessing` - Bloom and light effects