유니티 쉐이더 기초 - 깊이 착시효과

그래픽스꿀잼·2026년 4월 10일

그래픽스

목록 보기
7/20
post-thumbnail

bump mapping

흑백 displacement텍스쳐를 이용함

이런거임 그냥ㅇㅇ

normal blending

먼저 normal map을 받았으면

인스펙터에서 타입을 노말맵으로 바꾸셈ㅇㅇ


2개의 normal map을 스까주는 노드임

default와 reoriented가 있음

  • default

    void Unity_NormalBlend_float(float3 A, float3 B, out float3 Out)
    {
       Out = normalize(float3(A.rg + B.rg, A.b * B.b));
    }
    • 정규화(A라는 노말의 rg + B라는 노말의 rg * B라는 노말의 b)
  • reoriented

    void Unity_NormalBlend_Reoriented_float(float3 A,  float3 B, out float3 Out)
    {
        float3 t = A.xyz + float3(0.0, 0.0, 1.0);
        float3 u = B.xyz * float3(-1.0, -1.0, 1.0);
        Out = (t / t.z) * dot(t, u) - u;
    }
    • A라는 노말의 rgb + (0,0,1) = t
    • B라는 노말의 rgb * (-1,-1,1) = u
    • (t / t.b) * dot(t, u) - u;
      • dot(t,u) : t벡터와 u벡터의 방향이 얼마나 같은지

항목DefaultReorientate (RNM)
계산 방식단순 더하기 + normalize방향 재정렬 후 결합
정확도낮음높음
디테일 유지약함강함
성능빠름조금 느림
사용 추천간단한 경우대부분의 경우

만약 blend하는 normal이든 원본의 normal이든
blue값이 중요함

normal의 intensity변경 에러 (b채널값 0)

근데 만약 intensity설정한다고 변수를 곱하는데 0을 곱해서 0으로 만들어버리면?
검은세상ㅇㅇ

대충 이런노드가 있음
위의 텍스쳐가 base텍스쳐(쭈글쭈글한거), 아래의 텍스쳐가 blend텍스쳐(가로세로선)임

지금은 crackIntensity라는 값이 1이어서 blending과 strength조절이 잘 되었는데,,,
만약 0이면?


이렇게 됨

blue채널이 사라져버리는거임

blue채널은 Z축이고, x,y(r,g)에 대한 수직벡터(외적벡터)임
게다가 크기도 가지고 잇음

외적이 0이면 평행이고, 0이 아니면 수직인 벡터임(오른손 혹은 왼손 좌표계)

따라서 0이되면 빛 반사가 이뤄지지 않으니 검은세상이 되어버리는거임
참고용

해결하는 법은 간단함

normal blend는 일단 버리고 ㅇㅇ

직접 구현을 해주면 됨
대신 blue채널에 해당되는 값은 필요할때 만들어버리면 되는거임

뭔소리인지 모르겠지?

먼저 공식은

void Unity_NormalBlend_float(float3 A, float3 B, out float3 Out)
{
    Out = normalize(float3(A.rg + B.rg, A.b * B.b));
}

swizzle노드를 이용해서 필요한 채널값(rg)을 가져와 add해줌

그리고 normal reconstruct Z노드를 이용해서 blue채널을 동적으로 계산해서 적용하면 되는거임

그럼 intensity가 0이어도 blue채널은 살아있으니
normal mapping이 잘되는거 ㅇㅇ

  • 0일때
  • 3일때

normal 왜곡

이런식으로 일반 왜곡 쉐이더를 만든다음 uv 연결만 해주면 됨

profile
그래픽스 공부중

0개의 댓글