이 페이지는 youtube에서 Devving It With Sohail 님의 영상을 보고 정리한 글입니다.


1. Ambient Light
Ambient Light는 모든 방향에서 빛을 비춘다 라고 생각하면 쉽다.
공식문서에 보면 이렇게 나와있다.

즉, 모든 방향에 빛이 있기 때문에 그림자가 없다
는 의미이다.
2. Directional Light
광원이 점이 아닌 경우, 태양이 물체를 비추는 상황이라고 생각하면 쉽다.
그림자가 생긴다. 자세한 것은 공식문서 참고

3. Hemisphere Light
공식 문서의 예제를 보면서 함께 이야기 해자. 우측 Control 부분에서 Directional Light를 제거해보자.
새의 그림자는 사라지고, 날개의 위쪽은 상대적으로 어둡고, 날개 아랫부분은 밝은 것을 확인할 수 있다. Hemisphere Light는 Sky color, ground color라는 두가지 색을 사용해서 scene 바로 위쪽에 위치한다.

예제에서 확인할 수 있는 것처럼 그림자를 만드는 것에는 이용할 수 없다. 공식문서에서는 이렇게 나와있다.

4. Point Light
Pont Light는 마치 작은 촛불이나 전구같은 작은 빛 역할을 한다. 그림자 생성한다.
공식문서 참고
5. Spot Light
마치 무대조명처럼 한 point에서 cone 모양(원뿔모양) 으로 빛을 비춘다. 그림자도 생성한다.
공식문서 참고
예제를 가지고 이리저리 만져보면 이해가 빠르다.
6. 물체에 그림자 보이게 하기

사진처럼 공의 그림자를 floor 위에 보기에 하고 싶다면
- Spotlight과 Ball에 “castShadow” 속성추가하기
- Floor에 “receiveShadow” 속성추가하기
- Canvas에 Shadows 속성추가하기
코드로 보자면 이렇다.
// Three.tsx
...
return (
<>
<PerspectiveCamera makeDefault position={[0, 1, 5]} />
<OrbitControls
ref={orbitControlRef}
maxPolarAngle={angleToRadians(80)}
minPolarAngle={angleToRadians(40)}
/>
{/* circle */}
<mesh castShadow position={[0, 0.5, 0]}>
<sphereGeometry args={[0.5, 32, 32]} />
<meshStandardMaterial color="#E0DA46" />
</mesh>
{/* floor */}
<mesh receiveShadow rotation={[-angleToRadians(90), 0, 0]}>
<planeGeometry args={[7, 7]} />
<meshStandardMaterial color="#60FC4E" />
</mesh>
{/* ambient Light */}
<ambientLight args={['#ffffff', 0.25]} />
{/* direnctional Light */}
<spotLight
castShadow
args={['#ffffff', 1, 7, angleToRadians(45), 0.3]}
position={[-3, 1, 0]}
/>
</>
)
}
export default Three
// index.tsx
import React, { Suspense } from 'react'
import { Html } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import Three from '@/components/Three'
function TutorialMainPage() {
return (
<div>
TutorialMainPage
<Canvas shadows className="h-[100vh]">
<Suspense fallback={null}>
<Three />
</Suspense>
</Canvas>
</div>
)
}
export default TutorialMainPage
7. Environment
Environment는 말그대로 물체를 둘러싸고 있는 환경을 조성한다고 생각하면 된다.
아래 코드는 엄청나게 큰 분홍색의 구 모양의 환경을 만들어서 마치 무드등을 켠 것처럼 object의 색상이 변한다.
// Three.tsx
...
<Environment>
<mesh>
<sphereGeometry args={[30, 100, 100]} />
<meshBasicMaterial color="#F24671" side={THREE.BackSide} />
</mesh>
</Environment>
8. MeshPhongMaterial vs MeshStandardMaterial
현재 코드를 보면 sphereGeometry
아래에 MeshStandardMaterial
이라는 component가 들어가있다.
이 부분을 MeshPhongMaterial로 바꾸면 빛의 영향을 받지 않는다.
MeshStandardMaterial에는 metalness, roughness같은 속성이 있어서 더 매끈한 구 모양을 만들 수 있다. 더 많은 속성은 공식문서를 참고하자
9. 최종코드
// Three.tsx
import React, { useEffect, useRef } from 'react'
import {
Environment,
OrbitControls,
PerspectiveCamera,
} from '@react-three/drei'
import { useFrame } from '@react-three/fiber'
import * as THREE from 'three'
import type { OrbitControls as OrbitControlsImpl } from 'three-stdlib'
import { angleToRadians } from '@/utills/angle'
function Three() {
const orbitControlRef = useRef<OrbitControlsImpl>(null)
useFrame((state) => {
if (orbitControlRef.current) {
const { x, y } = state.mouse
orbitControlRef.current.setAzimuthalAngle(-x * angleToRadians(45))
orbitControlRef.current.setPolarAngle(y + 0.5 + angleToRadians(90 - 60))
orbitControlRef.current.update()
}
})
useEffect(() => {
if (orbitControlRef.current) {
console.log(orbitControlRef.current)
}
}, [orbitControlRef.current])
return (
<>
<PerspectiveCamera makeDefault position={[0, 1, 5]} />
<OrbitControls
ref={orbitControlRef}
maxPolarAngle={angleToRadians(80)}
minPolarAngle={angleToRadians(40)}
/>
{/* circle */}
<mesh castShadow position={[0, 0.5, 0]}>
<sphereGeometry args={[0.5, 32, 32]} />
<meshStandardMaterial color="#FFFFFF" metalness={0.5} roughness={0.2} />
</mesh>
{/* floor */}
<mesh receiveShadow rotation={[-angleToRadians(90), 0, 0]}>
<planeGeometry args={[20, 20]} />
<meshStandardMaterial color="#60FC4E" />
</mesh>
{/* ambient Light */}
<ambientLight args={['#ffffff', 0.25]} />
{/* direnctional Light */}
<spotLight
castShadow
args={['#ffffff', 1, 7, angleToRadians(45), 0.3]}
position={[-3, 1, 0]}
/>
{/* environment */}
<Environment>
<mesh>
<sphereGeometry args={[30, 100, 100]} />
<meshBasicMaterial color="#F24671" side={THREE.BackSide} />
</mesh>
</Environment>
</>
)
}
export default Three

꽤나 매끈한 탁구공이 완성되었음을 확인할 수 있다.
Uploaded by N2T