# SkyBox

{% embed url="<https://youtu.be/bGwOdn18gBU>" %}

## <mark style="background-color:yellow;">스카이박스의 기본 원리</mark>

```
// SkyBox.hlsl 중요 부분
float4 viewPos = mul(float4(input.position.xyz, 0), viewMatrix);
output.position.z = output.position.w * 0.999999f;
```

1. 큐브 메시 사용: 플레이어를 감싸는 큰 정육면체 메시를 생성
2. 큐브맵 텍스처: 6개 방향(+X, -X, +Y, -Y, +Z, -Z)의 이미지로 구성된 특수 텍스처 사용
3. 카메라 중심 배치: 스카이박스는 항상 카메라를 중심으로 이동
4. 깊이 값 최대화: 다른 모든 객체 뒤에 그려지도록 깊이 값을 최대치(0.999999)로 설정

## <mark style="background-color:yellow;">쉐이더 구현</mark>

```
// SkyBox.hlsl
VS_OUTPUT VS(VS_INPUT input)
{
    VS_OUTPUT output;

    // 위치를 뷰 행렬로 변환하되, w=0으로 설정하여 이동 성분 제거
    float4 viewPos = mul(float4(input.position.xyz, 0), viewMatrix);
    float4 clipSpacePos = mul(viewPos, projectionMatrix);
    output.position = clipSpacePos.xyzw;
    
    // 깊이 값을 최대치로 설정 (항상 가장 뒤에 그려지도록)
    output.position.z = output.position.w * 0.999999f;

    // 로컬 위치를 텍스처 좌표로 사용
    output.PosL = input.position.xyz;
    return output;
}

float4 PS(VS_OUTPUT input) : SV_Target
{
    // 입력된 방향으로 큐브맵 샘플링
    float4 textureColor = texture0.Sample(sampler0, input.PosL);
    return textureColor;
}
```

* 핵심 기술 설명:

  * #### 이동 성분 제거 (w=0 기법):
    * float4 viewPos = mul(float4(input.position.xyz, 0), viewMatrix);
      * 위치 벡터의 w 성분을 0으로 설정하면 변환 행렬의 translation 성분이 영향을 주지 않음
      * 결과적으로 카메라가 이동해도 스카이박스는 상대적 거리 변화 없이 항상 배경으로 남음
      * 회전 성분만 적용되어 카메라 방향에 따라 적절한 배경이 보임
  * 깊이 값 조정
    * output.position.z = output.position.w \* 0.999999f;
      * Z 값을 w와 거의 같게 설정하여 정규화된 깊이 값이 1에 매우 가까워짐
      * 이는 스카이박스가 항상 다른 객체보다 뒤에 그려지도록 함
      * 0.999999를 곱하는 이유는 정확히 1.0이 되면 일부 그래픽 하드웨어에서 깊이 버퍼 정밀도 문제가 발생할 수 있기 때문
  * 큐브맵 샘플링
    * float4 textureColor = texture0.Sample(sampler0, input.PosL);
      * 큐브 정점의 로컬 위치(input.PosL)를 직접 텍스처 좌표로 사용
      * 이 벡터는 중심에서 큐브의 각 정점으로 향하는 방향 벡터가 됨
      * 큐브맵 텍스처는 이 방향 벡터를 기반으로 적절한 텍셀 값을 반환


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jihoon-jungs-organization.gitbook.io/jihoon_engine/feature-and-description/skybox.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
