Passthrough API - 2024-Adoor/practice GitHub Wiki

๊ด€๋ จ ๊ณต์‹ ๋ฌธ์„œ ๋งํฌ:

์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์œ ๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ์—์„œ ํ•  ์ผ

๐Ÿ”— ์ด ๋ถ€๋ถ„์€ Configure Unity Project์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

Tip

Building Blocks์˜ ํŒจ์Šค์Šค๋ฃจ ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๊ณผ์ •์„ ์ž๋™์œผ๋กœ ์ง„ํ–‰ํ•ด ์ค๋‹ˆ๋‹ค.

  1. OVRCameraRig์˜ ์ธ์ŠคํŽ™ํ„ฐ์—์„œ...

    1. OVRManager ์ปดํฌ๋„ŒํŠธ > Quest Features > General > Passthroguh Support์—์„œ Required ๋˜๋Š” Supported ์„ ํƒ
    2. Insight Passthrough์—์„œ Enable Passthrough ํ™œ์„ฑํ™”
      (๋‚˜์ค‘์— C# ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ํŒจ์Šค์Šค๋ฃจ๋ฅผ initializeํ•˜๋ ค๋ฉด OVRManager.isInsightPassthroughEnabled๋ฅผ ์ด์šฉ ๊ฐ€๋Šฅ)
    3. ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ > OVRPassthroughLayer ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€
    4. OVRPassthroughLayer์—์„œ Projection Surface ์„ค์ •์„ ์„ ํƒํ•˜์—ฌ ํŒจ์Šค์Šค๋ฃจ ๋ Œ๋”๋ง์ด ์ž๋™ ํ™˜๊ฒฝ Depth ์žฌ๊ตฌ์„ฑReconsturcted์„ ์‚ฌ์šฉํ• ์ง€, ์•„๋‹ˆ๋ฉด ์‚ฌ์šฉ์ž ์ •์˜ ํ‘œ๋ฉดUser Defiend์„ ์‚ฌ์šฉํ• ์ง€ ์ •ํ•ฉ๋‹ˆ๋‹ค. (๋ฌด์Šจ๋ง?)
  2. ๋‹ค์Œ์— ์ˆ˜ํ–‰ํ•  ์ž‘์—…์€ ์›ํ•˜๋Š” ํŒจ์Šค์Šค๋ฃจ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

    ๊ฐ€์ƒ ์ฝ˜ํ…์ธ  ์œ„์— ํŒจ์Šค์Šค๋ฃจ๋ฅผ ๊ทธ๋ฆฌ๋ ค๋ฉด Placement๋ฅผ Overlay๋กœ, ์•„๋ž˜์— ๊ทธ๋ฆฌ๋ ค๋ฉด Underlay๋กœ ์„ค์ •. (์ฆ‰ ๋ฐฐ๊ฒฝ์ด ํŒจ์Šค์Šค๋ฃจ์ธ๊ฑด ์–ธ๋”๋ ˆ์ด, VR์—์„œ ์ฐฝ๋ฌธ์œผ๋กœ ํ˜„์‹ค์ด ๋ณด์ด๋Š”๊ฑฐ ๊ฐ™์€ ๊ฒƒ์€ ์˜ค๋ฒ„๋ ˆ์ด) ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ Composition Depth ์„ค์ •์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์ด์–ด ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•œ๋‹ค. Composition Depth๊ฐ€ ์ž‘์€ ๋ ˆ์ด์–ด๋Š” ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋” ๋†’์œผ๋ฉฐ ๊ฐ’์ด ๋” ํฐ ๋ ˆ์ด์–ด๋ณด๋‹ค ์•ž์— ๋‚˜ํƒ€๋‚œ๋‹ค.

ํŒจ์Šค์Šค๋ฃจ๋ฅผ ๋” ๋งŽ์ด ์‹คํ—˜ํ•˜๋ ค๋ฉด ๋จผ์ € ๊ธฐ๋ณธ์ ์ธ Basic Passthrough Tutorial ๋˜๋Š” Basic Passthrough Tutorial with Building Blocks๋ฅผ ์ˆ˜ํ–‰ํ•˜์„ธ์š”. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด ๋ฌธ์„œ ๋‚ด์˜ ํŒจ์Šค์Šค๋ฃจ ์ƒ˜ํ”Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ ๊ธ‰ ์‡ผ์ผ€์ด์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณด๋ ค๋ฉด GitHub ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. Unity-Discover ๋ฐ Unity-TheWorldBeyord ํ”„๋กœ์ ํŠธ๋Š” ๋ชจ๋‘ Passthrough๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์„ ํƒ์ ์œผ๋กœ ํŒจ์Šค์Šค๋ฃจ ์‚ฌ์šฉํ•˜๊ธฐ

๋‹น์‹ ์€ ์‚ฌ์šฉ์ž์˜ ์„ ํƒ์— ๋”ฐ๋ผ VR ๋˜๋Š” ํŒจ์Šค์Šค๋ฃจ ๋ฐฐ๊ฒฝ์„ ํ‘œ์‹œํ•˜๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ์‹œ์Šคํ…œ์€ ์ด๋ฏธ ์ง‘ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด๋Ÿฌํ•œ ์„ ํƒ๊ถŒ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๊ท€ํ•˜์˜ ์•ฑ์€ ์‚ฌ์šฉ์ž์˜ ์ง‘ ํ™˜๊ฒฝ ์„ ํ˜ธ ์„ค์ •์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณด๋‹ค ์ผ๋ฐ˜์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์šฐ๋ฆฌ ์‹œ์Šคํ…œ์€ ์‚ฌ์šฉ์ž ์„ ํ˜ธ๋„์— ๋”ฐ๋ผ ์•ฑ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ MR ๋˜๋Š” VR์„ ์‚ฌ์šฉํ•˜๋„๋ก ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ถŒ์žฅ ์‚ฌํ•ญ์€ OVRManager.IsPassthroughRecommended()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์˜ˆ:

// ์•„๋ฌด MonoBehavior์— ์ด ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
void Start()
{
  if (OVRManager.IsPassthroughRecommended())
  {
     passthroughLayer.enabled = true;

     // ์นด๋ฉ”๋ผ์˜ ๋ฐฐ๊ฒฝ์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค
     OVRCameraRig ovrCameraRig = GameObject.Find("OVRCameraRig").GetComponent<OVRCameraRig>();
     var centerCamera = ovrCameraRig.centerEyeAnchor.GetComponent<Camera>();
     centerCamera.clearFlags = CameraClearFlags.SolidColor;
     centerCamera.backgroundColor = Color.clear;

     // VR ๋ฐฐ๊ฒฝ ์š”์†Œ๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”
  }
  else
  {
     passthroughLayer.enabled = false;

     // VR ๋ฐฐ๊ฒฝ ์š”์†Œ๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”
  }
}

์ดํ•ด

  • OVRManager.IsPassthroughRecommended() - ์‚ฌ์šฉ์ž๊ฐ€ ํŒจ์Šค์Šค๋ฃจ๋ฅผ ์„ ํ˜ธํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๋ณด์ธ๋‹ค.
    • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ํ•ญ์ƒ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.
  • passthroughLayer.enabled - ํŒจ์Šค์Šค๋ฃจ๋ฅผ (๋น„/)ํ™œ์„ฑํ™” ํ•˜๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ ์•„์ง ์ž์„ธํžŒ ๋ชจ๋ฅด๊ฒ ์Œ.
    • ์ƒ๊ฐํ•ด๋ณด๋‹ˆ passthroughLayer ๋Š” ๊ทธ๋ƒฅ ์ปดํฌ๋„ŒํŠธ OVRPassthroughLayer์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ช…์ด๊ณ  enabled๋Š” ์œ ๋‹ˆํ‹ฐ์—”์ง„ ์˜ค๋ธŒ์ ํŠธ์—์„œ ์ƒ์†๋œ๊ฑธ ํ…Œ๋‹ˆ ๋ญ”๊ฐ€ ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์€ ์•„๋‹˜. OVRPassthroughLayer ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•œ๋‹ค = ํŒจ์Šค์Šค๋ฃจ๋ฅผ ๋ˆ๋‹ค?
  • ์œ ๋‹ˆํ‹ฐ ์นด๋ฉ”๋ผ์˜ backgroundcolor๋ฅผ clear๋กœ ํ•˜๋ฉด ๋’ค์— ํŒจ์Šค์Šค๋ฃจ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.
    • ์–ด๋–ค ์˜์ƒ์—์„œ๋Š” VR ์œ„์— Passthrough Window์„ ๋งŒ๋“œ๋Š”๋ฐ ์ด๊ฑธ ์•ˆ ํ•˜๋Š”๊ฒƒ ๊ฐ™๋‹ค. ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ์ด๊ฒŒ ์กฐ๊ฑด์ด๋ฉด ๊ทธ๋ƒฅ ์œ ๋‹ˆํ‹ฐ ์„ธ๊ณ„๋ฅผ ๋ชป ๋ณด์—ฌ์ฃผ๋Š”๊ฑฐ๋ ค๋‚˜?
  • VR ๋ฐฐ๊ฒฝ ์š”์†Œ๋ž€ ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”๊ฐ€? ...centerCamera.backgroundColor์— ๋‹ค๋ฅธ ๊ฒŒ์ž„์ฒ˜๋Ÿผ ๋ญ๋ผ๋„ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉด ๊ทธ๋งŒ์ธ ๊ฑด๊ฐ€?

ํŒจ์Šค์Šค๋ฃจ ์Šคํƒ€์ผ๋ง

๐Ÿ”— ์ด ๋ถ€๋ถ„์€ Color Mapping Techniques์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

OVRPassgthroughLayer ์ปดํฌ๋„ŒํŠธ๋Š” ํŒจ์Šค์Šค๋ฃจ์˜ ์‹œ๊ฐ์  ์Šคํƒ€์ผ์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • Opacity: ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€์˜ ํˆฌ๋ช…์„ฑ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • Edge Rendering: ์—ฃ์ง€ ๋ Œ๋”๋ง ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Color Contro: ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€์˜ ์ƒ‰์ƒ ์žฌํ˜„์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ ์„น์…˜์—์„œ ์„ค๋ช…ํ•˜๋Š” ๋‹ค์–‘ํ•œ ์Šคํƒ€์ผ ์ง€์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ๋ง๊ณ  ์Šคํฌ๋ฆฝํŠธ๋กœ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • OVRPassthroughLayer.textureOpacity
  • OVRPassthroughLayer.edgeRenderingEnabled
  • OVRPassthroughLayer.edgeColor

์ƒ‰์ƒ ์ œ์–ด ๊ธฐ๋Šฅ์€ ๊ฐ ์ž…๋ ฅ ์ƒ‰์ƒ์„ ๋‹ค๋ฅธ ์ถœ๋ ฅ ์ƒ‰์ƒ์— ๋งคํ•‘ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • None: ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • Color Adjustment: ์ด๋ฏธ์ง€์˜ ๋ฐ๊ธฐ, ๋Œ€๋น„ ๋ฐ ์ฑ„๋„๋ฅผ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ฑ„๋„ ์กฐ์ •์€ ์ปฌ๋Ÿฌ ํŒจ์Šค์Šค๋ฃจ๋ฅผ ์ง€์›ํ•˜๋Š” ์žฅ์น˜์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
  • Grayscale: ๋ฐ๊ธฐ์™€ ๋Œ€๋น„๋ฅผ ์กฐ์ •ํ•˜๊ณ  ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ํ†ต๊ณผ ์ด๋ฏธ์ง€์— ํฌ์Šคํ„ฐํ™” ํšจ๊ณผ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์„ ์„ ํƒํ•˜๋ฉด ์ปฌ๋Ÿฌ ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€๊ฐ€ ๋จผ์ € ํšŒ์ƒ‰์กฐ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
  • Grayscale To Color: ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€์— ์ƒ‰์ƒ์„ ์ง€์ •ํ•˜๊ณ , ๋ฐ๊ธฐ์™€ ๋Œ€๋น„๋ฅผ ์กฐ์ •ํ•˜๊ณ , ํฌ์Šคํ„ฐํ™” ํšจ๊ณผ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์„ ์„ ํƒํ•˜๋ฉด ์ปฌ๋Ÿฌ ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€๊ฐ€ ๋จผ์ € ํšŒ์ƒ‰์กฐ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
  • Color LUT: ๊ฐ RGB ์ž…๋ ฅ ์ƒ‰์ƒ์„ ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€ ์ŠคํŠธ๋ฆผ์˜ ์ž„์˜ RGB(A)์— ๋งคํ•‘ํ•˜๋Š” look-up table(LUT)์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Blended Color LUTs: ๋‘ ์ปฌ๋Ÿฌ LUT ๊ฐ„์˜ ๋ธ”๋ Œ๋“œ๋ฅผ ํŒจ์Šค์Šค๋ฃจ ์ด๋ฏธ์ง€ ์ŠคํŠธ๋ฆผ์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‘ ์ƒ‰์ƒ LUT ๊ฐ„์„ ์›ํ™œํ•˜๊ฒŒ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ:

  • OVRPassthroughLayer.SetColorMap
  • OVRPassthroughLayer.SetColorMapMonochromatic
  • OVRPassthroughLayer.SetColorMapControls
  • OVRPassthroughLayer.SetBrightnessContrastSaturation
  • OVRPassthroughLayer.SetColorLut
  • OVRPassthroughLayer.DisableColorMap

์‹ค์ œ ์—ฐ์Šต

https://github.com/2024-Adoor/practice/blob/7b5ecf6a2f1b0806e405158d9815f3b558a1d065/Assets/Scripts/PTTransition.cs#L43-L48

NOTE

  • https://blog.csdn.net/qq_46044366/article/details/132430180
    ์ค‘๊ตญ ์‚ฌ๋žŒ์ด ์“ด ํŠœํ† ๋ฆฌ์–ผ์ธ๋ฐ ๋ฒˆ์—ญ๊ธฐ ๋Œ๋ ค์„œ ์ด์–ด์„œ ๋ณด๋ฉด ๋‚˜๋ฆ„ ๋ณผ๋งŒํ•ฉ๋‹ˆ๋‹ค.

eyeFovPremultipliedAlphaModeEnabled๋Š” ๋ฌด์—‡์ธ๊ฐ€

Passthrough Window Tutorial์—๋Š” ๊ณผ์ • ์ค‘์— ์ด๊ฒŒ ๋‚˜์˜ค๊ณ , ๋‹ค๋ฅธ ์˜ˆ์ œ์—์„œ๋„ Awake()์—์„œ ์ด๊ฑธ ์“ฐ๋Š” ๊ฒŒ ๋ณด์ด์ง€๋งŒ ๋ฌด์Šจ ์šฉ๋„์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค.

https://blog.csdn.net/qq_46044366/article/details/132430180 ์ด ์ค‘๊ตญ ํŠœํ† ๋ฆฌ์–ผ ๊ธ€์—์„œ๋Š” ์ด๊ฒŒ ์„ ๋ช…ํ•˜๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ์šฉ๋„๋ผ๊ณ  ํ•œ๋‹ค๋Š”๋ฐ...

EnableUnpremultipliedAlpha.cs์— ์žˆ๋Š” ์ฃผ์„

Since the alpha values for Selective Passthrough are written to the framebuffers after the color pass, we need to ensure that the color values get multiplied by the alpha value during compositing. By default, this is not the case, as framebuffers typically contain premultiplied color values. This step is only needed when Selective Passthrough is non-binary (i.e. alpha values are neither 0 nor 1), and it doesn't work if the framebuffer contains semi-transparent pixels even without Selective Passthrough, as those will have premultiplied colors.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ