쉐이더 뜯어보기

[URP Shader Training]1. 4_픽셀 셰이더 출력 값 확인(NDC는 언제?)

대게 2025. 5. 20. 19:22

강의 보다 궁금한 부분 생겨서 잠깐 실험... 인데 모르겠다


Pixel shader 출력시 색 확인

왜 이런 결과가 나오는가?

=> screen 공간상의 좌표라서


의문 1. NDC 변환은 언제 수행되는가?/output의 결과는 clip인가 NDC인가.

=> vertex의 아웃풋이 pixel로 들어가기 전 수행/output의 결과는 clip

 

추론1: 버텍스셰이더에서 픽셀셰이더로 변환되는 과정에 자동으로 변환이 이루어진다.

 

추론2: SV_POSITION?

 


의문2: 그렇다면, 아예 SV_POSITION에 이상한 값을 전달하면?


결론


 

 

 

Pixel shader 출력시 색 확인

 

좌측의 결과가 왜 우측인지 강의중에 나온 부분에 대해 확인하는 글입니다.

 

픽셀셰이더에서 받은 VertexOutput i는 클립공간까지 변환된 값이다. 

그래서 클립공간의 정의가 어떻게 되는지 찾아봤다.

 

커스텀 셰이더

 

spaceTransforms.hlsl

 

 

spaceTransforms.hlsl
spaceTransforms.hlsl
UniversalRP > ShaderLibrary > input.hlsl

 

unityinput.hlsl
unityinput.hlsl

즉 지금 버텍스셰이더에서 일어나고 있는 계산은 

mul( (현재보기*투영행렬), 현재 모델 매트릭스, 버텍스포지션 )

근데 이러면 뷰포트변환은 일어나지 않은, 투영변환까지 적용된 상태인데. 이 상태가 clip상태라면 정규화되지 않았을 것이고 NDC라면 정규화 되었을 것이다. 

 

그런데 클립공간은 분명 원점이 중앙인, -1~1 사이의 범위로 정규화된 공간이다.

그럼 모든부분이 1(파랑)으로만 나오는 것이 이상하다.


왜 이런 결과가 나오는가?

아마 이는 모든 범위가 1을 넘었기 때문에 단색으로 나올 것이다.

이런 결과가 나오려면 픽셀셰이더는 클립공간의 결과가 아닌 뷰포트변환까지 수행된 결과를 받아야 한다.

이를 확인하기 위해 아래와 같이 코드를 수정했다.

예상대로 좌측하단이 0인 그라데이션을 이룬다, screen space의 값으로 보인다.


 2. NDC 변환은 언제 수행되는가?/  output의 결과는 clip인가 NDC인가.

여기서 추가적인 의문이 생긴다. 버텍스셰이더에서 픽셀셰이더로 가면서 output이 스크린공간으로 바뀐것은 위에서 확인했다.

 


 

추론1: 버텍스셰이더에서 픽셀셰이더로 변환되는 과정에 자동으로 변환이 이루어진다.

 

우선 버텍스->픽셀중 SV_POSITION의 값이 screen 공간으로 변환되는걸 확인하기 위해 버텍스셰이더에서 x,y 아웃값을 그대로 픽셀셰이더로 전달했다.

 

 

여기선 예상대로 중앙이 원점인 결과가 나왔다.

 

추가로 이건 정규화된 좌표가 아님을 함께 알 수 있다.

= 즉, 버텍스 셰이더에서의 아웃풋 값은 clip공간에서의 값이다.

 

 

 

왜.. 확대축소시 그라데이션 되는 영역이 함께 확대축소되는지... 모르겠다... 교수님저는말하는감자에요..................

 

 

아마 픽셀셰이더로 가기 전, 레스터라이저나.. 다른 단계에서 자동으로 변환 된다는 듯 하다


추론2: SV_POSITION?

시멘틱에서, SV_POSITION은 더 명확하게 역할을 지정해주는 차이가 있었다.

그렇다면 여기서 SV_POSITION일 때 자동으로 변환되는 것일까?

 

 

버텍스셰이더의 output으로 그냥 POSITION은 사용 불가능하다.

다른 변수를 사용한 결과는 클립공간의 값으로 보인다

=>SV_POSITION일 때 자동으로 변환

 

 

 

 


의문2: 그렇다면, 아예 SV_POSITION에 이상한 값을 전달하면?

1. vertex position 그대로 전달

=> 오브젝트의 로컬공간에서의 값을 최종 색상으로 인식했다.

로컬 공간에서의 값을 강제로 SV_POSITION에 전달하면서 화면의 중앙을 원점으로 정규화된 좌표로 변환했다. 

참고로 화면에서 오브젝트가 나가면 사라진다. 컬링되는 것 같다.

 

2. World position 그대로 전달

재밌는 결과가 나왔다

=> 오브젝트의 월드공간에서의 값을 각 픽셀의 최종 색상으로 인식.

월드에서의 값에 따라 움직인다. y축은 원점의 기준이 바뀌면서 반대로 움직이는 것을 볼 수 있다. z축은 아예 클리핑된다.

 

 

즉 버텍스 셰이더에서 픽셀셰이더로 SV_POSITION으로 내보낸 값은 자동으로 screen space로 변환되어 인식된다. 

 

 


결론

 SV_POSITION으로 내보낸 포지션값은 픽셀셰이더에서 스크린스페이스상의 값으로 받아들인다. 

정확히 어느 단계에서 변환되는가?

그럼 geometry shader에서는?

추가적인 의문이 계속 생기지만.. 딴길로 너무 왔다.

다시 원래 쓰던 글로 돌아갈 시간... 이후 geometry shader 정리하면서 추가적으로 보고 수정하겠다.