๐Ÿ”ฆ Ray casting

  • R(t) = O + t * D ์™€ ์‚ผ๊ฐํ˜• P(u, v) = V0 + u * (V1- V0) + v * (V2 - V0) ๊ฐ€ ์žˆ์„ ๋•Œ
  • R(t) = P(u, v) ๋ฅผ ๋งŒ์กฑํ•˜๋Š” u, v, t ๋ฅผ ๊ตฌํ•œ๋‹ค
  • u โ‰ฅ 0, v โ‰ฅ 0, u+v โ‰ค 1 ์ผ ๋•Œ, R(t) ๋Š” ์‚ผ๊ฐํ˜• ๋‚ด์˜ ์ ์ด๋ผ๊ณ  ํŒ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

1. ๊ด‘์„ 

  • ๊ด‘์„  ์œ„์˜ ํ•œ ์ ์— ๋Œ€ํ•œ ํ‘œํ˜„
\[r(t) = o + t d\]

(o๋Š” ์›์ , d๋Š” ๋ฐฉํ–ฅ๋ฒกํ„ฐ)

  • ๋ฐฉํ–ฅ๋ฒกํ„ฐ๊ฐ€ ํ•ญ์ƒ ๋‹จ์œ„ ๋ฒกํ„ฐ์ž„์ด ๋ณด์žฅ๋˜์ง€๋Š” ์•Š์ง€๋งŒ, ๊ด€๋ จ ์—ฐ์‚ฐ ๋Œ€๋ถ€๋ถ„์—์„œ ๋ฐฉํ–ฅ๋ฒกํ„ฐ๋ฅผ ์ •๊ทœํ™”ํ•˜์—ฌ ์‚ฌ์šฉํ•จ

2. ํ‘œ๋ฉด

  • Ray - Object ๊ต์ฐจ์˜ ๊ธฐ๋ณธ์ด ๋˜๋Š” ํ‘œ๋ฉด์€ ํฌ๊ฒŒ ์Œํ•จ์ˆ˜ ํ‘œ๋ฉด๊ณผ ๋ช…์‹œ์  ํ‘œ๋ฉด์œผ๋กœ ๊ตฌ๋ถ„๋จ

๋ช…์‹œ์  ํ‘œ๋ฉด

  • ํ•œ ๋ณ€์ˆ˜๋ฅผ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋“ค์˜ ํ•จ์ˆ˜๋กœ ์ง์ ‘ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ์‹
\[z = f(x, y)\]
  • ์˜ˆ์‹œ: ํฌ๋ฌผ์„ ์˜ ํ‘œ๋ฉด
\[z = x^2 + y^2\]
  • ๋ช…์‹œ์  ํ‘œ๋ฉด๊ณผ Ray ๊ฐ„ ๊ต์ฐจ๋ฅผ ๊ฒ€์‚ฌํ•  ๋•Œ, ํ•จ์ˆ˜์— x, y ๊ฐ’์„ ๋Œ€์ž…ํ•ด๋ณด๊ณ  ๊ทธ ๊ฐ’์„ z๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ํ‘œ๋ฉด์— ์žˆ๋Š” ์ ์ธ์ง€, ํ‘œ๋ฉด์„ ์ง€๋‚œ ์ ์ธ์ง€, ํ‘œ๋ฉด์— ๋‹ฟ์ง€ ๋ชปํ•œ ์ ์ธ์ง€ ๊ฒฐ์ •

  • ๊ตฌ์˜ ๊ฒฝ์šฐ ์ฒ˜๋Ÿผ x, y ๊ฐ’์„ ๋Œ€์ž…ํ•˜๋ฉด z๊ฐ€ ๋‘ ๊ฐœ์˜ ๊ฐ’์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๋Š” ๋ช…์‹œ์  ํ‘œํ˜„์œผ๋กœ ํ‘œํ˜„ํ•˜์ง€ ๋ชปํ•จ

\[x^2 + y^2 + z^2 = r^2\]
- ๊ธฐํ•˜ํ•™์ ์œผ๋กœ ์ดํ•ดํ•˜๋ฉด, ํŠน์ • `x`, `y`์— ๋Œ€ํ•ด ์œ„์ชฝ ๋ฐ˜๊ตฌ์˜ `z` ์ง€์ ๊ณผ ์•„๋ž˜์ชฝ ๋ฐ˜๊ตฌ์˜ `z` ์ง€์  ์ด ๋‘ ๊ฐœ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— ํ‘œํ˜„ ๋ถˆ๊ฐ€

์Œํ•จ์ˆ˜ ํ‘œ๋ฉด

  • ํ•จ์ˆ˜๊ฐ’์ด 0์ด๋˜๋Š” ์ ๋“ค์˜ ์ง‘ํ•ฉ์ด ํ‘œ๋ฉด
\[F(x, y, z) = 0\]
  • ์˜ˆ์‹œ: ๊ตฌ์˜ ํ‘œ๋ฉด
\[F(x, y, z) = x^2 + y^2 + z^2 - r^2\]
  • ํ•จ์ˆ˜์— x, y, z ๊ฐ’์„ ๋Œ€์ž…ํ•ด๋ณด๊ณ  ๊ทธ ๊ฐ’์ด 0์ธ์ง€ ๊ฒ€์‚ฌํ•˜์—ฌ ํ‘œ๋ฉด์— ์žˆ๋Š” ์ ์ธ์ง€, ํ‘œ๋ฉด์„ ์ง€๋‚œ ์ ์ธ์ง€, ํ‘œ๋ฉด์— ๋‹ฟ์ง€ ๋ชปํ•œ ์ ์ธ์ง€ ๊ฒฐ์ •

  • ์Œํ•จ์ˆ˜ ํ‘œ๋ฉด์€ ์–ด๋–ค ํ˜•ํƒœ๋“  ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Œ

    • ๋ช…์‹œ์  ํ‘œ๋ฉด ๋˜ํ•œ ์Œํ•จ์ˆ˜ ํ‘œ๋ฉด์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋•Œ๋ฌธ์— ๋ช…์‹œ์  ํ‘œ๋ฉด์€ ์Œํ•จ์ˆ˜ ํ‘œํ˜„์˜ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Œ
\[F(x, y, z) = z - f(x, y)\]
- ๊ทธ๋ž˜ํ”ฝ์Šค์—์„œ๋Š” ์ฃผ๋กœ ์Œํ•จ์ˆ˜ ํ‘œ๋ฉด์„ ๊ต์ฐจ ๊ฒ€์‚ฌ์— ์‚ฌ์šฉ

3. ๋ฐ”์šด๋”ฉ ๋ณผ๋ฅจ

  • ์‚ผ๊ฐํ˜• ๊ต์ฐจ ๊ฒ€์‚ฌ๋‚˜ Mesh ๊ฐ„ ์ถฉ๋Œ ๊ฒ€์‚ฌ๋Š” ๊ฒŒ์ž„ ์—”์ง„์—์„œ ๊ฐ€์žฅ ๋น„์‹ผ ์—ฐ์‚ฐ ์ค‘ ํ•˜๋‚˜์ž„

  • ์ •๊ตํ•˜๊ฒŒ ์ถฉ๋Œ์„ ๊ฒ€์‚ฌํ•˜๊ธฐ ์ „์— Naiveํ•˜๊ฒŒ ์‹ผ ์—ฐ์‚ฐ์œผ๋กœ ๊ต์ฐจ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์—†๋Š” ๋ฌผ์ฒด๋“ค์„ ๋จผ์ € ๊ฑธ๋Ÿฌ๋‚ธ ๋’ค, ๊ต์ฐจ ํ›„๋ณด๊ฐ€ ๋˜๋Š” ๋ฌผ์ฒด๋“ค๋งŒ ์ •๊ตํ•˜๊ฒŒ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด Naiveํ•œ ๊ต์ฐจ ๊ฒ€์‚ฌ ๋Œ€์ƒ์œผ๋กœ ๋ฐ”์šด๋”ฉ ๋ณผ๋ฅจ์„ ์‚ฌ์šฉํ•จ

    • ์ผ๋ฐ˜์ ์œผ๋กœ Local BV์™€ World BV๋ฅผ ๋ชจ๋‘ ๊ด€๋ฆฌํ•˜๋ฉฐ, World BV๋กœ 1์ฐจ, Local BV๋กœ 2์ฐจ๋กœ ๊ฒ€์‚ฌํ•จ
  • ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌ๋‚˜ ๋ฐ•์Šค ํ˜•ํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, Unreal Engine์—์„œ๋Š” ๊ทธ ๋‘˜์„ ํ•ฉ์นœ BoxSphereBounds๋ผ๋Š” ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•จ

AABB(Axis-Alinged Bounding Box)

  • ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ๋Š” ์ถ• ์ •๋ ฌ ์ง์œก๋ฉด์ฒด ๊ฒฝ๊ณ„ ๋ฐ•์Šค

  • ๋ฐ•์Šค์˜ ๋ฉด์ด ์ขŒํ‘œ์ถ•๊ณผ ํ•ญ์ƒ ํ‰ํ–‰ํ•จ

  • ๊ณ„์‚ฐ์ด ๋‹จ์ˆœํ•˜๊ณ  ์ถ• ๋น„๊ต๋งŒ ํ•˜๋ฉด ๋˜์–ด์„œ ๊ฑฐ์˜ ๋ชจ๋“  ์—”์ง„์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉ๋จ

  • ๋‹จ, ๊ฐ์ฒด๊ฐ€ ํšŒ์ „ํ•˜์—ฌ๋„ AABB๋Š” ์ถ• ์ •๋ ฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•จ๊ป˜ ํšŒ์ „ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํšŒ์ „์ด ๋๋‚  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ๊ณ„์‚ฐํ•ด์•ผ ํ•จ

  • ์ผ๋ฐ˜์ ์ธ ๊ตฌ์„ฑ

    struct AABB
    {
        FVector Min;
        FVector Max;
    }
    
  • ๋ฐ•์Šค ๋‚ด๋ถ€ ํŒ์ •

    bool Inside =
        P.x >= Min.x && P.x <= Max.x &&
        P.y >= Min.y && P.y <= Max.y &&
        P.z >= Min.z && P.z <= Max.z;
    

AABB ์ƒ์„ฑ๊ณผ ๋ณ€ํ˜•

  • AABB ์ƒ์„ฑ ์ž์ฒด๋Š” ์ „์ฒด ์ •์  ์ง‘ํ•ฉ์„ ๋Œ์•„๋‹ค๋‹ˆ๋ฉฐ ๊ฐ ์ถ•์˜ ์ตœ์†Œ, ์ตœ๋Œ€ ์ง€์ ์„ ์ฐพ์œผ๋ฉด ๋˜์ง€๋งŒ, ์ด ์—ฐ์‚ฐ๋„ ๋ฌผ์ฒด์˜ ๋ณ€ํ˜•์ด ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์ˆ˜ํ–‰ํ•˜๋ฉด ์—ฐ์‚ฐ์ด ๋ถ€๋‹ด๋  ์ˆ˜ ์žˆ์Œ

  • Unreal Engine์—์„œ๋Š” ๋ฌผ์ฒด์˜ Local AABB๋ฅผ ๋ฌผ์ฒด ์ƒ์„ฑ ์‹œ ๋จผ์ € ๊ณ„์‚ฐํ•˜๊ณ , ๋ฌผ์ฒด๊ฐ€ ๋ณ€ํ˜•๋จ์— ๋”ฐ๋ผ์„œ ํ•จ๊ป˜ ๋ณ€ํ˜•ํ•จ

    • UStaticMeshComponent ๋“ฑ์—์„œ ์ƒ์„ฑ ์‹œ Local AABB๋ฅผ ์ €์žฅ

      • AABB๋ฅผ ์ƒ์„ฑํ•œ ํ›„ Origin ์ €์žฅ
\[c = \frac{min + max}{2}\]
- `USceneComponent`์—์„œ Transform ๋ณ€๊ฒฝ ๋ฐœ์ƒ ์‹œ BV ์—…๋ฐ์ดํŠธ
  • ๋ณ€ํ˜• ๋ฐฉ๋ฒ•

    • Unreal Engine์˜ TBoxSphereBounds๋Š” ์›์  ๋ฒกํ„ฐ Origin๊ณผ ๊ฐ ์ถ• ๋ฐฉํ–ฅ์œผ๋กœ์˜ BoxExtents(๋ฒกํ„ฐ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ

    • ๋ฌผ์ฒด์— ๊ฐ€ํ•ด์ง„ ๋ณ€ํ™˜ ํ–‰๋ ฌ์„ M์œผ๋กœ ๊ฐ€์ •

    • Origin์€ ๋‹จ์ˆœํžˆ M์˜ ์ด๋™ ์—ฐ์‚ฐ ๋ถ€๋ถ„๋งŒ ํ™œ์šฉํ•˜์—ฌ ๋ฌผ์ฒด์™€ ํ•จ๊ป˜ ์ด๋™๋งŒ ์‹œ์ผœ์ฃผ๋ฉด ๋จ

    • ๋ณ€ํ™˜ ํ–‰๋ ฌ์˜ ์„ ํ˜• ๋ณ€ํ™˜ ๋ถ€๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Œ

\[A = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix}\]

BoxExtents ๋ฒกํ„ฐ๋ฅผ e๋ผ ํ•˜๋ฉด, BoxExtents๋Š” e' = e |A|๋กœ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Œ

\[e_x' = |a_{11}|e_x + |a_{21}|e_y + |a_{31}|e_z\] \[e_y' = |a_{12}|e_x + |a_{22}|e_y + |a_{32}|e_z\] \[e_z' = |a_{13}|e_x + |a_{23}|e_y + |a_{33}|e_z\]

Bounding Sphere ์ƒ์„ฑ๊ณผ ๋ณ€ํ˜•

  • Bounding Sphere๋Š” ์˜คํžˆ๋ ค AABB๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Œ

  • Unreal Engine์—์„œ Bounding Sphere๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š”, AABB์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ „์ฒด ์ •์  ์ง‘ํ•ฉ์—์„œ AABB๋กœ๋ถ€ํ„ฐ ๊ณ„์‚ฐ๋œ Origin์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ€์žฅ ๋ฉ€๋ฆฌ ๋–จ์–ด์ง„ ์ •์  ์ •๋ณด๋ฅผ ํ†ตํ•ด ๋ฐ˜์ง€๋ฆ„ ์ •๋ณด SphereRadius๋ฅผ ๊ณ„์‚ฐ

  • ๋ณ€ํ˜•ํ•  ๋•Œ๋Š” ์›์ ์€ ๊ทธ๋Œ€๋กœ ์ด๋™๋งŒ ์‹œํ‚ค๊ณ , ํšŒ์ „์—๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Œ

  • ๋ณ€ํ˜•์—์„œ ๊ณ ๋ คํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„์€ ์Šค์ผ€์ผ

    • ๊ท ์ผ ์Šค์ผ€์ผ์˜ ๊ฒฝ์šฐ์—๋Š” ๊ฐ„๋‹จํžˆ ๋ฐ˜์ง€๋ฆ„์— ์Šค์ผ€์ผ ๊ณ„์ˆ˜๋ฅผ ๊ณฑํ•˜์—ฌ ๋ณ€ํ˜•

    • ๋น„๊ท ์ผ ์Šค์ผ€์ผ์˜ ๊ฒฝ์šฐ์—๋Š” ๊ฐ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€์žฅ ํฐ ์Šค์ผ€์ผ ๊ฐ’์„ ๋ฐ˜์ง€๋ฆ„์— ๊ณฑํ•˜์—ฌ ๋ณ€ํ˜•

4. ๊ต์ฐจ

๊ด‘์„  - ๊ตฌ

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ตฌ์˜ ์Œํ•จ์ˆ˜ ํ‘œ๋ฉด ๊ฒ€์‚ฌ
\[f(p) = |p - c| - r = 0\]
  • ๊ด‘์„ ์„ ๋Œ€์ž…ํ•˜์—ฌ ์ •๋ฆฌ
\[f(r(t)) = |r(t) - c| - r = 0\] \[|o + t d - c| = r\] \[(o + t d - c) \cdot (o + t d - c) = r^2\] \[t^2(d \cdot d) + 2t(d \cdot (o - c)) + (o - c) \cdot (o - c) - r^2 = 0\]
  • ๋งŒ์•ฝ ๊ด‘์„ ์˜ d๊ฐ€ ๋‹จ์œ„ ๋ฒกํ„ฐ์ด๊ณ , b = d \cdot (o - c), c = (o - c) \cdot (o - c) - r^2๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋ฉด, t์— ๋Œ€ํ•ด ์•„๋ž˜ ์‹์œผ๋กœ ์ •๋ฆฌ๋จ
\[t = -b \pm \sqrt{b^2 - c}\]
  • ์ฆ‰, b^2 - c์— ๋”ฐ๋ผ ๊ด‘์„ ์ด ๊ตฌ์— ๋งž๋Š”์ง€ ๋งž์ง€ ์•Š๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Œ

๊ด‘์„  - ์ƒ์ž

  • OBB๊นŒ์ง€ ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๊ณ , AABB์— ํŠนํ™”๋œ ์กฐ๊ธˆ ๋” ๋น ๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜

    • โ€˜์Šฌ๋ž˜๋ธŒ ๋ฐฉ๋ฒ•โ€™์ด๋ผ๊ณ  ๋ถ€๋ฆ„
  • x, y, z์— ํ•ด๋‹นํ•˜๋Š” ์ถ•์„ ํฌ๊ฒŒ A๋ผ๊ณ  ํ‘œํ˜„

  • ๊ด‘์„ ์ด ์ถœ๋ฐœ์ ์—์„œ ๋์ (๊ด‘์„ ์€ ์›๋ž˜ ๋์ด ์—†์ง€๋งŒ ๋ฌผ๋ฆฌ ์—ฐ์‚ฐ ํ•œ๊ณ„์ƒ ์•ฝ ์‹œ์ž‘์  + 100,000 ์ •๋„๋ฅผ ๋์ ์„ ์žก์Œ)๊นŒ์ง€ ๋„์ฐฉํ•  ๋•Œ ์‹œ๊ฐ„์„ 1๋กœ ๋‘๊ณ , ๊ด‘์„ ์ด ์ถœ๋ฐœ์ ์—์„œ ์ฒ˜์Œ AABB์— ๋‹ฟ๋Š” ์‹œ๊ฐ„์„ t๋กœ ๋‘ 

  • t์˜ ๊ฐ ์ถ•์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜

\[t_A = \frac{Box.Min_A - Start_A}{End_A - Start_A}\]
- ๋‹จ, ๊ณ„์‚ฐ ์‹œ ๊ด‘์„ ์˜ ์‹œ์ž‘์ ๊ณผ ๋์ ์ด ๋ชจ๋‘ AABB๋ฅผ ์ง€๋‚˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์—ฐ์‚ฐ ์ž์ฒด๋ฅผ ํ•˜์ง€ ์•Š์Œ

- ์‹œ์ž‘์ ์ด ์• ์ดˆ์— AABB ์•ˆ์— ์žˆ์–ด๋„ ์—ฐ์‚ฐ์„ ๋”ฐ๋กœ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Œ
  • t์˜ ๊ฐ ์ถ• ๊ฐ’ ์ค‘ ๊ฐ€์žฅ ํฐ ๊ฐ’์ด ์‹ค์ œ๋กœ ๊ด‘์„ ์ด AABB์— ๋‹ฟ๋Š” ์‹œ์ 

  • Unreal Engine ์†Œ์Šค์ฝ”๋“œ์—์„œ๋Š” ๋งˆ์ง€๋ง‰์— ๋ถ€๋™ ์†Œ์ˆ˜์  ์˜ค์ฐจ๋ฅผ ๊ณ ๋ คํ•˜๋Š” ์ž„๊ณ„๊ฐ’์„ ์ถ”๊ฐ€ํ•จ

๊ด‘์„  - ์‚ผ๊ฐํ˜•

  • ์ƒ์šฉ ์—”์ง„์—์„œ๋Š” Ray Casting์„ ์—ฌ๋Ÿฌ phase๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๊ฐ€์žฅ ๋‚ฎ์€ narrow phase์—์„œ๋Š” ๊ฑฐ์˜ ๋ฐ˜๋“œ์‹œ ๊ด‘์„  - ์‚ผ๊ฐํ˜• ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋จ

    • ๊ด‘์„  - ํด๋ฆฌ๊ณค ๊ฒ€์‚ฌ ๋ฐฉ๋ฒ•์ด ์—ฐ๊ตฌ๋˜๊ธฐ๋„ ํ•˜์ง€๋งŒ, GPU๋Š” ๊ฒฐ๊ตญ Mesh๋ฅผ ์‚ผ๊ฐํ˜• ๊ธฐ๋ฐ˜์œผ๋กœ ๋ Œ๋”๋งํ•˜๊ณ , CPU์—์„œ ์ฒ˜๋ฆฌ ๋˜ํ•œ ์‚ผ๊ฐํ˜• ๋‹จ์œ„๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ด‘์„  - ์‚ผ๊ฐํ˜• ๊ต์ฐจ ๊ฒ€์‚ฌ๋Š” ๊ทธ๋ž˜ํ”ฝ์Šค์—์„œ ์ ˆ๋Œ€์ ์ธ ํ‘œ์ค€ ๊ฒ€์‚ฌ์ž„
  • ์•„๋ž˜์—์„œ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์€ ๊ด‘์„  - ์‚ผ๊ฐํ˜• ๊ต์ฐจ์˜ ๊ฐ€์žฅ ํ‘œ์ค€์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ Mรถllerโ€“Trumbore ๊ต์ฐจ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๊ณ  ๋ถ€๋ฆ„

  • โ€˜์‚ผ๊ฐํ˜•์ด ๋†“์ธ ํ‰๋ฉด๊ณผ ๊ด‘์„ ์˜ ๊ต์ฐจ์ ์„ ๊ณ„์‚ฐํ•ด์„œ, ํ•ด๋‹น ๊ต์ฐจ์ ์ด ์‚ผ๊ฐํ˜• ๋‚ด์— ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋ฉด ๋˜์ง€ ์•Š๋‚˜?โ€™ํ•˜๊ณ  ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋‘ ๋‹จ๊ณ„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ์ข… ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๋Š˜์–ด๋‚˜๊ณ  ์ˆ˜์น˜์ ์œผ๋กœ ๊ณ„์‚ฐ์ด ๋ฒˆ๊ฑฐ๋กœ์›Œ์ง€๋Š” ๋ถ€๋ถ„์ด ์ƒ๊น€

    • Mรถllerโ€“Trumbore ๊ต์ฐจ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ด๋Ÿฐ ์—ฐ์‚ฐ์„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•จ
  • ์‚ผ๊ฐํ˜• ๋‚ด๋ถ€์˜ ํ•œ ์ ์— ๋Œ€ํ•œ ํ‘œํ˜„(V_{0, 1, 2}๋Š” ์‚ผ๊ฐํ˜•์˜ ๊ฐ ์ •์ , u, v๋Š” ์‚ผ๊ฐํ˜• ๋ฌด๊ฒŒ์ค‘์‹ฌ ์ขŒํ‘œ๊ณ„ ๋‚ด ์ž„์˜์˜ ์Šค์นผ๋ผ)

\[P = V_0 + u E_1 + v E_2\] \[E_1 = V_1 - V_0\] \[E_2 = V_2 - V_0\]
  • ๊ด‘์„ ๊ณผ ์‚ผ๊ฐํ˜•์ด ๋งŒ๋‚  ๋•Œ์˜ ์‹
\[O + t D = V_0 + u E_1 + v E_2\]

์ •๋ฆฌํ•˜๋ฉด,

\[O - V_0 = u E_1 + v E_2 - t D\]
- ๊ฐ ๋ณ€์ˆ˜์˜ ์กฐ๊ฑด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Œ
\[u \ge 0,\quad v \ge 0,\quad u + v \le 1,\quad t > 0\]
  • ๊ด‘์„ ์˜ ๋ฐฉํ–ฅ ๋ฒกํ„ฐ D๋Š” ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ์ •๊ทœํ™”ํ•ด๋‘๋Š” ํŽธ์ด ์ข‹์Œ(์ˆซ์ž๊ฐ€ ๊น”๋”ํ•ด์ง)

  • ๊ณ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜

    1. ๋จผ์ € P ๋ฒกํ„ฐ์™€ Det๋ฅผ ๊ณ„์‚ฐ
\[P = D \times E_2\] \[Det = E_1 \cdot (D \times E_2)\]
    - `Det`๋Š” ์Šค์นผ๋ผ ์‚ผ์ค‘๊ณฑ์œผ๋กœ, `E_1`, `E_2`, `D`๊ฐ€ ๋งŒ๋“œ๋Š” ๋ถ€ํ”ผ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์œผ๋กœ๋„ ๋ณผ ์ˆ˜ ์žˆ์Œ

    - `Det`๊ฐ€ 0์— ๊ฐ€๊น๋‹ค๋Š” ๊ฒƒ์€ ๊ด‘์„ ์˜ ๋ฐฉํ–ฅ ๋ฒกํ„ฐ `D`๊ฐ€ ์‚ผ๊ฐํ˜• ํ‰๋ฉด๊ณผ ๊ฑฐ์˜ ํ‰ํ–‰ํ•˜๊ฑฐ๋‚˜, ์‚ผ๊ฐํ˜•์˜ ํ˜•ํƒœ๊ฐ€ ์˜๋ฏธ์—†์„ ์ •๋„๋กœ ์ฐŒ๊ทธ๋Ÿฌ์ ธ ์žˆ๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ ์•ˆ์ •์ ์œผ๋กœ ํ’€ ์ˆ˜ ์—†๋‹ค๋Š” ๋œป์ด๊ธฐ์— `EPSILON`(์ผ๋ฐ˜์ ์œผ๋กœ `1e-6f`)๋“ฑ๊ณผ ๋น„๊ตํ•˜์—ฌ ์—ฐ์‚ฐ์„ ๋ฉˆ์ถค

      ```C++
      if (fabs(Det) < EPSILON) { return false; }
      ```

        - Back-face culling ์‹œ, ์‚ผ๊ฐํ˜•์˜ ๋’ท๋ฉด์€ ํด๋ฆญํ•ด๋„ ์„ ํƒ๋˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด `fabs(Det)`๋Œ€์‹  ๊ทธ๋ƒฅ `Det` ์‚ฌ์šฉ
    
2. `u` ๊ณ„์‚ฐ
\[T = O - V_0\] \[u = \frac{T \cdot P}{Det}\]
    - `T`๋Š” ์‚ผ๊ฐํ˜•์˜ ๊ธฐ์ค€์  `V_0`์—์„œ ๊ด‘์„ ์˜ ์›์  `O`๊นŒ์ง€ ๊ฐ€๋Š” ๋ฒกํ„ฐ

    - ๋Œ€๋ถ€๋ถ„์˜ ๊ฒŒ์ž„ ์—”์ง„์—์„œ๋Š” `u`๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์—ฐ์‚ฐ์„ ๋ฉˆ์ถค

      ```C++
      if (u < 0.0f || u > 1.0f) { return false; }
      ```

3. `v` ๊ณ„์‚ฐ
\[Q = T \times E_1\] \[v = \frac{D \cdot Q}{Det}\]
    - `v`์˜ ๋ฒ”์œ„๋‚˜ `u + v`์˜ ๋ฒ”์œ„๊ฐ€ ๋ฒ—์–ด๋‚˜๋ฉด ์—ฐ์‚ฐ์„ ๋ฉˆ์ถค

      ```C++
      if (v < 0.0f || u + v > 1.0f) { return false; }
      ```

4. ๋งˆ์ง€๋ง‰์œผ๋กœ `t` ๊ณ„์‚ฐ
\[t = \frac{E_2 \cdot Q}{Det}\]
    - ๋งŒ์•ฝ `t < 0`์ด๋ผ๋ฉด ๊ด‘์„ ์ด ์‚ผ๊ฐํ˜•์˜ ์ง€๋‚˜์นœ ๊ณณ์—์„œ ๋ฐœ์‚ฌ๋˜์—ˆ๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ ๊ต์ฐจ ๋ถ€์ •

      ```C++
      if (t < 0.0f) { return false; }
      ```
      
5. ์—ฌ๊ธฐ๊นŒ์ง€ ๋ชจ๋“  ์กฐ๊ฑด ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผํ•˜๋ฉด ์‚ผ๊ฐํ˜•๊ณผ ๊ด‘์„ ์ด ๊ต์ฐจํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ๊ทธ ๊ต์ฐจ์ ์€ `O + t D`์ž„

5. Ray Casting์„ ์œ„ํ•œ Inverse Projection / View

  • Ray casting์€ ๊ฒฐ๊ตญ World ๊ณต๊ฐ„์—์„œ ์ผ์–ด๋‚˜์ง€๋งŒ, ๋งˆ์šฐ์Šค ์„ ํƒ ์ž์ฒด๋Š” Screen ๊ณต๊ฐ„์—์„œ ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ณต๊ฐ„ ์ขŒํ‘œ๊ณ„ ๋ณ€ํ™˜ ๊ณผ์ •์„ ์—ญ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ

  • ํ™”๋ฉด์˜ ๋งˆ์šฐ์Šค ์ขŒํ‘œ (s_x, s_y)์— ๋Œ€ํ•œ ๊ณต๊ฐ„ ์ขŒํ‘œ๊ณ„ ์—ญ๋ณ€ํ™˜

    1. Screen ๊ณต๊ฐ„ -> NDC ๊ณต๊ฐ„: ํ™”๋ฉด ์œ„์˜ ๋งˆ์šฐ์Šค ์œ„์น˜๋ฅผ ์ •๊ทœํ™”๋œ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜
\[x_{\mathrm{NDC}} = \frac{2 s_x}{width} - 1\] \[y_{\mathrm{NDC}} = 1 - \frac{2 s_y}{height}\]
2. Near / Far ์  ๋งŒ๋“ค๊ธฐ: ๊ฐ™์€ `(x, y)`์— `z`๋งŒ ๋‹ค๋ฅด๊ฒŒ ํ•˜์—ฌ ๋‘ ์ ์„ ์ƒ์„ฑ

    - Graphics ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ API ๊ทœ์•ฝ์— ๋”ฐ๋ผ `z` ๋ฒ”์œ„๊ฐ€ ๋‹ค๋ฆ„

        - OpenGL: `[-1, 1]`, DirectX: `[0, 1]`

    - `z` ๋ฟ ์•„๋‹ˆ๋ผ, 4์ฐจ์› ๋™์ฐจ ์ขŒํ‘œ(homogeneous coordinate)๋กœ ๋งˆ์ง€๋ง‰ ์›์†Œ 1๋„ ์ถ”๊ฐ€ํ•ด์คŒ

3. Inverse Projection: NDC ๊ณต๊ฐ„ -> View ๊ณต๊ฐ„
\[P_{\mathrm{view}} = P_{\mathrm{clip}} \cdot M_{\mathrm{projection}}^{-1}\]
    - ์—ญ๋ณ€ํ™˜์˜ ๊ฒฐ๊ณผ๋Š” ๋ณดํ†ต `(x, y, z, w)`์˜ ํ˜•ํƒœ๋กœ ๋‚˜์˜ค๋Š”๋ฐ, ์ด๋ฅผ ์‹ค์ œ 3D ์ ์ฒ˜๋Ÿผ ์“ฐ๊ธฐ์œ„ํ•ด `w`๋กœ ๋‚˜๋ˆ„์–ด์ฃผ๋Š” homogeneous divide๋ฅผ ์ˆ˜ํ–‰ํ•จ
\[(x' = \frac{x}{w},\quad y' = \frac{y}{w},\quad z' = \frac{z}{w},\quad 1)\]
4. Inverse View: View ๊ณต๊ฐ„ -> World ๊ณต๊ฐ„
\[P_{\mathrm{world}} = P_{\mathrm{view}} \cdot M_{\mathrm{view}}^{-1}\]
    - ์‚ฌ์‹ค View ๊ณต๊ฐ„์—์„œ๋„ ์ด๋ฏธ ๊ด‘์„ ์€ View ๊ณต๊ฐ„์˜ ์›์ ์—์„œ ์ถœ๋ฐœํ•˜๋Š” ๊ด‘์„ ์œผ๋กœ์จ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— View ๊ณต๊ฐ„์—์„œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•ด๋„ ๋˜์ง€๋งŒ, ๋ณดํ†ต ์ตœ์ข…์ ์œผ๋กœ Inverse View๊นŒ์ง€ ์ˆ˜ํ–‰ํ•จ

5. World Ray ์ƒ์„ฑ: `P_near^world`, `P_far^world` ๋‘ ์ ์„ ์ด์šฉํ•˜์—ฌ World ๊ณต๊ฐ„ ๋‚ด ๊ด‘์„  ์ƒ์„ฑ
\[O = P_{\mathrm{near}}^{\mathrm{world}}\] \[D = \mathrm{normalize}(P_{\mathrm{far}}^{\mathrm{world}} - O)\]

6. ์ƒ์šฉ ์—”์ง„์—์„œ Ray Casting์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

  • ์—”์ง„ ๊ฐœ๋ฐœ์ž์˜ ์ž…์žฅ์—์„œ๋Š” Ray Casting์œผ๋กœ ์ œ์ผ ๋จผ์ € ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ํŽธ์ง‘๊ธฐ ํ™”๋ฉด ๋‚ด์—์„œ์˜ ๊ฐ์ฒด ์„ ํƒ์ž„

  • ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ƒ์šฉ ์—”์ง„์—์„œ๋Š” ํŽธ์ง‘๊ธฐ ๋‚ด ๊ฐ์ฒด ์„ ํƒ์— ์ฃผ๋กœ ์ƒ‰ ๊ธฐ๋ฐ˜ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•จ(Unreal Engine์˜ Hit Proxy ๋“ฑ)

  • ๊ฒŒ์ž„ ๋‚ด ๋ฌผ๋ฆฌ ์ถฉ๋Œ ๊ฒ€์‚ฌ ๋“ฑ์—์„œ Ray Casting์„ ์ฃผ๋กœ ํ™œ์šฉํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ •ํ™•ํ•œ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด์„œ๋Š” ๊ฒŒ์ž„ ๋‚ด ๋ชจ๋“  ๊ฐ์ฒด์˜ ์ •์ ๋“ค์„ ์ด์šฉํ•˜์—ฌ ์ผ์ผํžˆ ๊ด‘์„ -์‚ผ๊ฐํ˜• ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ด๋Š” ๋งค์šฐ ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ์†์‹ค์„ ๊ฐ€์ ธ์˜ด

    • ๊ฐ์ฒด์˜ ํ˜•ํƒœ๊ฐ€ ์กฐ๊ธˆ๋งŒ ๋ณต์žกํ•ด์ ธ๋„ ๊ฐ์ฒด ํ•˜๋‚˜์— ์ˆ˜๋งŽ์€ ์ •์ ๊ณผ ์‚ผ๊ฐํ˜• ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋“ค์ด ์กด์žฌํ•˜๊ฒŒ ๋จ
  • ์ด ์„ฑ๋Šฅ ์†์‹ค์„ ๊ฐ์‡ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์šฉ ์—”์ง„์—์„œ๋Š” Ray Casting ๊ฒ€์‚ฌ๋ฅผ ์—ฌ๋Ÿฌ ํŽ˜์ด์ฆˆ๋กœ ๋‚˜๋ˆ„์–ด์„œ ๊ณ„์‚ฐํ•จ

  • ์ผ๋ฐ˜์ ์ธ phase ๊ตฌ์„ฑ

    1. Broad Phase: BV๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ด‘์„ ๊ณผ ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๊ฐ์ฒด๋“ค๋งŒ ์ถ”๋ฆฌ๊ธฐ

    2. Mid Phase: ๊ฐ์ฒด์™€ ๊ด€๋ จ๋œ ๊ฐ์ข… ํ•„ํ„ฐ(Visibility, ์ถฉ๋Œ ๋ฌด์‹œ ํ”Œ๋ž˜๊ทธ ๋“ฑ)๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ถ”๋ฆฌ๊ธฐ

    3. Narrow Phase: ํ›„๋ณด ๊ฐ์ฒด๋“ค ์ค‘์—์„œ ๊ด‘์„ ์ด ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ๋งž์ถ”์—ˆ๋Š”์ง€ ์ •ํ™•ํžˆ ๊ณ„์‚ฐ

      • ์—ฌ๊ธฐ์„œ๋„ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ์˜ ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ทผ์‚ฌ์  ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Œ(์ •ํ™•๋„ ๊ฐ์†Œ, ์†๋„ ์ฆ๊ฐ€)

        • Unreal Engine์—์„œ๋Š” trace_complex ์˜ต์…˜์ด true๊ฐ€ ์•„๋‹ˆ๋ฉด ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ์˜ ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ๋กœ ๋น ๋ฅด๊ฒŒ ๊ฒ€์‚ฌํ•จ

Picking

  • Sphere โ†’ AABB โ†’ Ray-Triangle test ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ˆ˜ํ–‰ (์—ฐ์‚ฐ ๋น„์šฉ ์ˆœ)