기본 콘텐츠로 건너뛰기

Direct3D11 - Intrinsic Functions 내장 함수


Intrinsic Functions 내장 함수

다음은 HLSL이 기본 제공하는 함수들과 관련 설명들입니다. 우선 HLSL 5.0(D3D11)에서 추가된 함수들입니다.
이 함수들에 대한 자료는 아직 매우 빈약한 편이어서 차츰 업데이트하는 방식을 택하겠습니다. 또, 새로 도입이 되긴 했지만 Vetex/Pixel/Geometry shader 어디에서도 아직 사용할 수 없는 함수들도 있습니다. 이런 함수들 역시 사용가능하게 되고 참고할 수 있을 때 업데이트하는 방식을 취할까 합니다.

1. AllMemoryBarrier()    모든 메모리 Access가 끝날 때까지그룹 내의 모든 쓰레드들의 실행을 막는다.
2. AllMemoryBarrierWithGroupSync()    모든 메모리 Access가 끝나고 모든 쓰레드들이 이 함수 지점까지 도달할
   때까지그룹 내의 모든 쓰레드들의 실행을 막는다.
3. DeviceMemoryBarrier()   모든 디바이스 메모리 Access가 끝날 때까지그룹 내의 모든 쓰레드들의 실행을 막는다.
4. DeviceMemoryBarrierWithGroupSync() 
  모든 디바이스 메모리 Access가 끝나고 모든 쓰레드들이 이 함수 지점까지 도달할
   때까지그룹 내의 모든 쓰레드들의 실행을 막는다.
5. GroupMemoryBarrier   그룹 메모리 Access가 끝날 때까지그룹 내의 모든 쓰레드들의 실행을 막는다.
6. GroupMemoryBarrierWithGroupSync
    모든 그룹 메모리 Access가 끝나고 모든 쓰레드들이 이 함수 지점까지 도달할
   때까지그룹 내의 모든 쓰레드들의 실행을 막는다.
7. dst:
  두 벡터 간의 거리(distance)를 구한다.
   fVector dst(
     __in  fVector src0,
     __in  fVector src1
   );

8. EvaluateAttributeAtCentroid
   5.0이전에는 Interpolator가 특정 픽셀의 보간된 속성값을 제공했다. 5.0에서는 Shader가 바로 이 값을 요청할 수 있게 됐으며,
  이 중에서 EvaluateAttributeAtCentroid는 픽셀 중앙 위치의 보간된 속성값을 요청한다.
9. EvaluateAttributeAtSample
  특정 픽셀에서의 보간된 속성값을 요청한다.
10. InterlockedAdd
   Multi Threading 환경에서 Atomic Add를 가능하게 한다. atomic add와 같은 연산을 atomic operation이라고
    하는데, 이는 멀티 쓰레딩 환경에서 다른 쓰레드의 간섭을 받지 않는 안전한 연산을 의미한다. 무슨 이야기냐면
    다들 알듯이 멀티 쓰레딩 환경에서는 race condition(시간차나 순서에 따라 특정 메모리에 접근하는 순서가
    정해지는 게 경주하는 것 같다고 해서 붙은 이름)이 일어나게 되고 이런 경우 메모리에는 전혀 예상하지 못한
    결과값이 들어가게 된다. 이를 방지하고 있는 안전한 연산이 바로 atomic operation인 것이다.
    이 이름은 atomic이라는 말이 원래 더 이상 쪼갤 수 없다는 의미이니, 다른 쓰레드와 쪼개서 공유할 수 없다,는 의미로
    붙여진 이름같다.
     어쨌든 Atomic Add는 Shared Memory에만 수행할 수 있는데, 아마도 Global Memory에 이 연산을 수행하면
     Performance가 안 좋아지기 때문인 것 같다.
               void InterlockedAdd(
                       __in   R dest,
                       __in   T value,
                       __out  T original_value
                 );
     이와 같은 형태로 쓰이며 입력값 T와 dest R에 있는 값을 더하여 다시 dest R에 저장한다. 세번 째 인자에 원래값이 들어
     간다.
11. InterlockedAnd: Atomic And를 수행한다.

  void InterlockedAnd(
     __in   R dest,
     __in   T value,
     __out  T original_value
  );
                value와 dest 값을 and 연산한 후 dest에 결과를 저장한다.
             
12. InterlockedCompareExchange:
  void InterlockedCompareExchange(
     __in   R dest,
     __in   T compare_value,
     __in   T Exchange_Value,
     __out  T original_value
  );
   dest의 값과 compare_value 값을 비교하여 만약 같으면 Exchange_Value를 dest에 저장한다. original_value에
   원래값이 들어간다.
        
13. InterlockedCompareStore:
  void InterlockedCompareStore(
    __in  R dest,
     __in  T compare_value,
     __in  T value
  );
  dest의 값과 compare_value를 비교하여 같으면 value를 dest에 저장한다.

14. InterlockedExchange:
  void InterlockedExchange(
     __in   R dest,
     __in   T value,
     __out  T original_value
  );
   value를 dest에 저장하고 원래값을 original_value에 반환한다.
15. InterlockedMax:
  void InterlockedMax(
     __in   R dest,
     __in   T value,
     __out  T original_value
  );
    shared Memory dest에 있는 값과 value의 최대값을 구하여 결과를 dest에 저장한다.
16. InterlockedMin:
  void InterlockedMax(
     __in   R dest,
     __in   T value,
     __out  T original_value
  );
  dest에 있는 값과 value의 최소값을 구하여 결과를 dest에 저장한다.
17. InterlockedOr:
  void InterlockedOr(
     __in   R dest,
     __in   T value,
     __out  T original_value
  );
  dest에 있는 값과 value를 or연산하여 그 결과를 dest에 저장한다.
18. InterlockedXor:
  void InterlockedXor(
     __in   R dest,
     __in   T value,
     __out  T original_value
  );
  dest에 있는 값과 value를 xor연산하여 그 결과를 dest에 저장한다.
1. ddx_coarse
            ddx()를 보충하기 위해 도입된 함수이다. ddx()에 대한 설명을 보면 해당 좌표(픽셀)에 대한 편미분값을
            구한다, 라고 돼 있다... 도대체 무슨 말인지... 화면 좌표계에서 어떻게 편미분 값을 구한다는 건지...
            이해도 안 가고 저런 식으로 달랑 한 문장 써 놓은 게 얄밉다.
            사실 ddx()는 특정 픽셀값의 Gradient 정도, 즉 변화 정도를 알려준다. 이 값은 지정한 픽셀 자신과 해당
            픽셀 바로 오른 쪽에 인접한 픽셀 값과의 차이를 통해서 얻을 수 있는데, 만약 그 차이가 크다면 이 픽셀은
            인접 픽셀과 비교해 변화 정도가 크다는 뜻이고, 작다면 서서히 변한다는 뜻이 되는 것이다.
            포토샵 같은 툴을 조금이라도 써 보신 분이라면 Gradient가 무언지 알 수 있을 것이다. Gradient를 작게 주면
            색이 자연스럽고 천천히 변하는데, 크게 주면 급격하게 색깔이 변하는 걸 알 수 있다. 바로 ddx() 값이 크다면
            이렇게 급격하게 변하는 걸 의미하는 것이다.
            ddx_coarse는 낮은 정밀도로 이 값을 구하는 함수이다.
2ddy_coarse: ddx_coarse와 똑 같은 의미. 방향이 아래쪽이라는 것만 틀리다.
3. ddxfine: ddx_coarse와는 다르게 고 정밀도로 해당 픽셀의 Gradient 정도를 구한다.
4. ddyfine: ddxfine와 똑 같은 의미. 방향이 y축 방향이다는 차이만 있다.

다음 Process로 시작하는 10개의 함수는 Direct3D 11에 추가된 Tessellation 용 함수들로서 Tessellation Factor값들을 구하는
함수 들입니다.
Tessellation은 Hull Shader, Domain Shader와 함께 오브젝트를 보다 정밀하게 표현할 수 있도록 마련된 기능입니다. 기존의
LOD가 미리 만들어 놓은 여러 단계의 오브젝트를 상황에 따라 선택적으로 보여주거나 감추는 것이었다면 Tessellation은
실시간으로 GPU연산을 통해 정밀도를 조정하여 오브젝트를 표현해준다는 차이가 있습니다. 또한 Parrallex map이 텍스쳐의
좌표를 보는 각도에 따라 달리하여 Normal/bump 맵보다 좀더 현실적인 그래픽을 보여주는 것과는 달리 실재 필요할 경우
오브젝트의 폴리곤의 갯수를 실시간으로 조절하여 정밀도를 조정한다,는 차이가 있습니다.
Tessellation의 기본 단위는 Patch와 Control Point입니다. 하나의 패치는 1~32개의 control Point를 가질 수 있습니다.
Tessellation을 적용하면 이런 Control Point를 중심으로 연산이 이뤄지게 됩니다. 또한 Tessellation을 어느정도 적용하지
결정하기 위한 Tessellation Factor가 있는데 다음 10개의 함수는 모두 이 Tessellation Factor값을 구하는 역할을 합니다.

5. Process2DQuadTessFactorsAvg  Edge Tessellation Factor(패치의 가장자리 Tessellation Factor값)들의 평균값을 이용
  Inside Tessellation Factor(패치 안쪽 Tessellation Factor값)를 계산하여
  4 각형 패치의 수정된 Tessellation Factor를 구한다. Tessellation Factor의 UV 값은
  각각 독립적으로 구하는데, 양쪽 가장자리 domain 값의 평균값을 취한 후 이 함수의
  두 번째 인자로 넘겨주는 Scale일 값만큼 스케일을 변경한다.

6. Process2DQuadTessFactorsMax  Process2DQuadTessFactorsAvg과의 차이는 Edge Tessellation Factor 평균값 대신 최대값을 이용한다는 점이다.
7. Process2DQuadTessFactorsMin  Process2DQuadTessFactorsAvg과의 차이는 Edge Tessellation Factor 평균값 대신 최소값을 이용한다는 점이다.
8. ProcessIsolineTessFactors  라인에 대한 Tessellation Factor 근사값을 구한다.

9. ProcessQuadTessFactorsAvg  Edge Tessellation Factor(패치의 가장자리 Tessellation Factor값)들의 평균값을 이용
  Inside Tessellation Factor(패치 안쪽 Tessellation Factor값)를 계산하여
  4 각형 패치의 수정된 Tessellation Factor를 구한다. 이렇게 구해진 Inside Tessellation Factor 값은
  함수의 2번째 인자로 넘겨주는 스케일값에 의해 조정된 가장자리 4개의 평균
  Tessellation Factor값과 동일하다.
10. ProcessQuadTessFactorsMax  위의 함수와 비교해 최대값을 이용한다는 차이점만 있다.
11. ProcessQuadTessFactorsMin
  위의 함수와 비교해 최소값을 이용한다는 차이점만 있다.

12. ProcessTriTessFactorsAvg  삼각형 형태의 패치(tri patch)에 대한 Tessellation Factor 값을 구한다. 구하는 방식의 Quad Patch와
  같다.
13. ProcessTriTessFactorsMax
14. ProcessTriTessFactorsMin

이제 두 번 정도만 더 정리하면 HLSL 기본 문법은 끝이 날 것 같습니다. 시리즈를 보고 계신다면 힘내세요.

abs: 절대값을 구한다.
acos: 코사인에 대한 역 삼각함수
all(x); x의 모든 원소가 0인가? 맞으면 true, 아니면 false를 리턴한다.
any(x): x의 원소중에 0이 아닌 원소가 하나라도 있는가? 있으면 true, 없으면 false를 리턴한다.
asfloat: 인자값을 float 타입으로 바꾼다.
asin: 싸인에 대한 역 삼각함수
asint: 인자값을 int 타입으로 바꾼다.
asuint: 인자값을 uint 타입으로 바꾼다.
atan: 탄젠트에 대한 역 삼각함수
atan2: atan2(y,x) 의 형태로 쓰이며 이는 atan(y/x)와 같다. 분모인 x는 당연히 0이어서는 안 된다.
ceil: 인자값으로 전달 받은 float형 값보다 크거나 같은 정수들 중에서 가장 작은 값
clamp: 인자값을 특정 범위로 한정한다. 즉, clamp(x, min, max)에서 x가 min보다 작으면 min을
       max보다 크면 max를 리턴한다.
clip:
     픽셀 쉐이더에서만 사용 가능하다. 만약 인자값이 0보다 작으면 현재의 픽셀을 버린다.
     clip( Input.Color.A < 0.1f ? -1:1 );
     위에서 만약 알파값이 0.1보다 작다면 인자값은 -1이 될 것이고 이는 0보다 작기 때문에
     해당 픽셀은 처리되지 않게 된다.
cos, sin, tan: 기본 삼각함수
cross: 인자로 받은 두 개의 float형 3D 벡터값들의 외적값을 구한다.
D3DCOLORtoUBYTE4:  D3DCOLOR값으로 채워진 4D 벡터의 float형 성분들을 UBYTE4 형으로 변경한다. UBYTE4형을 지원하지
                 않는 특정 하드웨어를 위해 마련된 함수이다.
ddx: ddx_coarse 참조
ddy: ddy_coarse 참조
degrees: 인자로 입력 받은 라디언 값에 해당하는 degree값을 리턴한다.
determinant: 인자로 입력받은 정방행렬의 행렬식을 구한다.
distance(x,y): 두 벡터의 거리를 구한다.
dot: 인자로 받은 두 개의 3D 벡터들의 내적값을 구한다.
log: 밑이 e인 로그값을 구한다.
log10: 밑이 10인 로그값을 구한다.
log2: 밑이 2인 로그값을 구한다.
floor:인자값으로 전달 받은 float형 값보다 작거나 같은 정수들 중에서 가장 큰 값
radians: 인자로 입력 받은 degree 값에 해당하는 radian값을 리턴한다.
sqrt(x) : x의 제곱근을 구한다.
rsqrt: 제곱근의 역수를 구한다.
max: 두 인자 중 큰 값을 구한다.
min: 두 인자 중 작은 값을 구한다.
fwidth:
isfinite(x): x가 유한한가? 맞으면 true, 아니면 false 리턴
isinf(x): x가 무한인가? 맞으면 true, 아니면 false 리턴
length(x): 벡터 x 의 길이를 리턴
normalize: 정규화한다.
pow(x,y): x^y, 즉 x의 y승 값을 리턴
exp(x): 밑을 e로 하는 지수 e^x를 리턴
exp2(x): 밑을 2로 하는 지수 2^x를 리턴
modf(x,i) : x의 정수부분은 i에 저장되고 소수점 이하부분이 리턴값으로 넘어온다.
sign(x) : x의 부호를 리턴한다. 부호가 음수이면 -1, 0이면 0, 양수이면 1을 리턴
saturate(x) : x를 [0, 1] 범위의 값으로 한전한다
lerp(x,y,s) : 선형보간 값인 x + s(y - x) 를 리턴한다.
step(x,y) : x가 y보다 작거나 같은지 판단한다. 맞으면 1, 그렇지 않으면 0을 리턴한다
smoothstep(min,max,x) : x가 [min, max] 사이의 값인 경우에 [0, 1] 사이의 Hermite 보간 값을
          리턴한다.
fmod(x,y) : x/y의 나머지 값을 리턴한다
frac(x) : x의 소수점 이하 부분을 리턴한다
frexp(x,e) : 주어진 실수 x의 소수점 이하값인 가수부분과 지수부분을 동시에 리턴한다.
    가수부분을 e로 리턴하고, 지수부분을 함수리턴값으로 리턴한다
round(x) : 반올림한 정수를 리턴
mul(x,y) : 두 행렬의 곱을 리턴한다.
faceforward(n, i, ng) : 관찰자를 향하는 표면 노말값을 리턴한다
reflect(i, n) : 반사벡터를 리턴한다.
refract(i, n, R) : 굴절벡터를 리턴한다.
lit(n·l, n·h, m) : 조명계수 벡터를 리턴한다.
noise(x) : Perlin 노이즈값을 리턴한다.

width(x): abs(ddx(x)) + abs(ddy(x)) 를 계산한다.
cosh(x): x의 cosine hyperbolic(쌍곡 함수) 값을 얻는다.
sinh(x): x의 sine쌍곡 함수 값을 얻는다.
tanh(x): x의 tangent쌍곡 함수 값을 얻는다.
sincos(x, out sineVal, out cosVal): x에 대한 sine값을 구해 sineVal에 저장하고, cosine값은 cosVal에 저장한다.
GetRenderTargetSampleCount: 렌더 타겟에 대한 샘플 갯수를 구한다.
GetRenderTargetSamplePosition(index) 인덱스에 해당하는 샘플에 대해서 샘플링 위치를 구한다.
isnan(x): x가 NAN(Not a number) 이거나 QNAN(Quiet Not a number)인지 판단한다.
ldexp(x, exp): x * (2의 exp 승)을 계산한다.
tex1D(s, t) : 샘플러 s를 이용 t 위치에서 텍스쳐의 색깔 정보를 뽑아낸다. 쉐이더가 1D를 지원하지 않기 때문에
              컴파일러는 2D 텍스쳐를 사용하게 되는데, 대신 컴파일러는 y좌표는 중요하지 않다고 판단한다.
tex1D(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 가지고 판단하고, 샘플러 s를 이용해
              t에서의 색깔 정보를 뽑아낸다.
tex1Dbias(s,t): bias는 Vertex Shader에서는 사용할 수 없고 Pixel Shader에서만 사용할 수 있다. t.w에 의해 mip map
              level을 정한 후 샘플러 s를 이용 해당 픽셀의 색깔 정보를 얻는다.
              이미지를 흐리게 보이게 하거나 선명하게 보이게 하게 위해 쓰일 수 있다.
tex1Dgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 x와 y의 gradient 정도값을 이용하고, 샘플러 s를 이용해
              t에서의 색깔 정보를 뽑아낸다.
tex1Dlod(s,t): t.w에 의해 miplevel을 정한 후 샘플러 s를 이용 해당 픽셀의 색깔 정보를 얻는다. t.w에 의해 LOD가
              어느단계에서 변할지를 결정한다.
tex1Dproj: proj 가 붙으면 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
tex2D(s, t): 샘플러 s를 이용해 2D 텍스쳐의 색깔 정보를 얻어낸다.
tex2D(s, t, ddx, ddy): 샘플러 s를 이용해 2D 텍스쳐 t에서의 색깔 정보를 얻어낸다. ddx와 ddy를 이용해 mipmap level을 정한다.
tex2Dbias(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 2D 텍스쳐의 픽셀 색깔 정보를 얻는다.
tex2Dgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 통해 결정하고, 샘플러 s를 이용해 2D 텍스쳐
              t에서의 색깔 정보를 뽑아낸다.
tex2Dlod(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 2D 텍스쳐의 픽셀 정보를 얻는다. t.w에 의해 LOD가
              어느단계에서 변할지를 결정한다.
tex2Dproj(s,t): 2D 텍스쳐에서 샘플러 s를 이용해 샘플링을 한다. 이때 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
tex3D(s, t): 샘플러 s를 이용해 3D 텍스쳐의 색깔 정보를 얻어낸다.
tex3D(s, t, ddx, ddy): 샘플러 s를 이용해 3D 텍스쳐 t에서의 색깔 정보를 얻어낸다. ddx와 ddy를 이용해 mipmap level을 정한다.
tex3Dbias(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 3D 텍스쳐의 픽셀 색깔 정보를 얻는다.
tex3Dgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 통해 결정하고, 샘플러 s를 이용해 3D 텍스쳐
              t에서의 색깔 정보를 뽑아낸다.
tex3Dlod(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 3D 텍스쳐의 픽셀 정보를 얻는다. t.w에 의해 LOD가
              어느단계에서 변할지를 결정한다.
tex3Dproj(s,t): 3D 텍스쳐에서 샘플러 s를 이용해 샘플링을 한다. 이때 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
texCUBE(s, t)샘플러 s를 이용해 큐브 텍스쳐의 색깔 정보를 얻어낸다.
texCUBE(s, t, ddx, ddy): 샘플러 s를 이용해 큐브 텍스쳐 t에서의 색깔 정보를 얻어낸다.
    ddx와 ddy를 이용해 mipmap level을 정한다.
texCUBEbias(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 큐브 텍스쳐의 픽셀 색깔 정보를 얻는다.
texCUBEgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 통해 결정하고, 샘플러 s를 이용해 큐브 텍스쳐
              t에서의 색깔 정보를 뽑아낸다.
texCUBElod(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 큐브 텍스쳐의 픽셀 정보를 얻는다. t.w에 의해 LOD가
              어느단계에서 변할지를 결정한다.
texCUBEproj(s,t): 큐브 텍스쳐에서 샘플러 s를 이용해 샘플링을 한다. 이때 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
transpose(x): x의 행과 열이 바뀐 전치행렬을 구한다.
trunc(x): x의 소숫점 아래 값을 버린 정수값을 얻는다.





댓글

이 블로그의 인기 게시물

WebRTC Janus Gateway Media Server 사용기

이번 프로젝트에 WebRTC Media Server가 필요해서 조사를 진행했다. 조사한 Media Server는 아래와 같다. 1. jitsi meet : https://jitsi.org/jitsi-meet/ 2. janus gateway : https://janus.conf.meetecho.com/ 3. kurento : https://www.kurento.org/ 4. mediasoup : https://mediasoup.org/ 5. medooze : http://www.medooze.com/ 이중에 여러 플랫폼 라이브러리가 필요해서 janus gateway 를 선택하게 되었다.