행복한 연어의 이야기

(Unity) 유니티 쉐이더 분석 본문

IT/Unity

(Unity) 유니티 쉐이더 분석

해피살몬 2020. 2. 4. 20:56

유니티 쉐이더

Fixed Funtion Shader

  • vertex당 lighting 연산
  • 하드웨어 관련 작업 x, 특수 커맨드 사용 x
  • Programmable Shader를 지원하지않는 낮은 하드웨어에 대응하기위해 주로 사용
  1. property

    • property 는 유니티 인스펙터 창에서 조절할 수 있는 값들 을 보여줍니다.
    • property의 정의는 다음의 형식을 따릅니다.

    _Name(“Displayed Name”, type) = default value[{options}]
    ex) _MainColor ("Main Color", Color) = (1,0,0,0.5)

    1) _Name은 참조될 property의 이름입니다.
    2) Displayed Name은 material editor(Inspector View)에 나타납니다.
    3) type은 property의 타입입니다. 여러분은 다음 중 하나를 선택할 수 있습니다.

    • Color - value는 전체 프로그램을 위한 하나의 색상이 될 것입니다.
    • 2D - value는 2의 제곱 크기의 텍스처입니다. 이 텍스처는 모델의 UV에 기반하여 특정 픽셀이 프로그램에 의해 샘플링됩니다.
    • Rect - value는 2의 제곱 크기가 아닌 텍스처입니다.
    • Cube - value는 반사에 사용되는 3D 큐브 맵 텍스처입니다. 특정한 픽셀을 프로그램으로 샘플링할 수 있습니다.
    • Range(min, max) - value는 min과 max 사이의 부동소수점입니다.
    • Float - value는 부동소수점 숫자 중 어떤 값입니다.
    • Vector - value는 4차원 벡터입니다.
      4) defalut value는 property의 기본 값입니다.
    • Color - 색상은 부동소수점으로 (r, g, b, a) 각 부분을 나타내는 방식으로 표현됩니다. 예를 들면 (1,1,1,1)입니다.
    • 2D / Rect / Cube - 텍스처 타입의 기본값으로 빈 string이거나 “white”, “black”, “gray”, “bump”로 표현됩니다.
    • Float / Range - 채택될 값입니다.
    • Vector - (x, y, z, w)로 표현되는 4차원 벡터입니다.
      5) { options }은 단지 2D, Rect, Cube와 같은 텍스처 타입과 관련있습니다. 하지만 반드시 {}는 명시되어야 합니다. 공백으로 분리하여 다양한 옵션을 조합할 수 있습니다.
    • TexGen texgenmode: 자동 텍스처 조정 생성 모드입니다. ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal 중 하나입니다.
      이것들은 OpenGL texgen 모드와 일치합니다. 만약 여러분이 정점 함수를 작성한다면 무시됩니다.
  2. SubShader

    • 여러개의 SubShader 를 가질 수 있지만 실행 되는 SubShader 는 하나 이다.
    • 보통 사양에 맞춰 여러 SubShader 를 작성한다.
    • 모든 SubShader를 사용할 수 없으면 Fallback 으로 지정된 Shader를 가져온다.
      1) Tag
      • surface shader는 하나 혹은 그 이상의 tag로 꾸며집니다. 이 tag들은 하드웨어가 shader를 언제 호출할지를 결정할 수 있도록 합니다.
        (1) Queue 태그 - "Queue" = "값"
        • Background (1000) : 가장 먼저 렌더링됨. 보통 배경에 배치해야할 때 사용
        • Geometry (2000) : 디폴트값. 대부분 오브젝트의 사용. 불투명인 경우에
        • AlphaTest (2450) : 알파테스트된 지오메트리가 사용
        • Transparent (3000) : 알파 값이 적용되어야 할 오브젝트들은 Geometry와 AlphaTest 이후에 렌더링
        • Overlay (4000) : 마지막에 렌더링되야할 항목에 적용
          *) Tags { "Queue" = "Geometry+1" }
          위처럼 +1을 통해 2001번으로 만들어 모든 Geometry가 렌더링 된 이후에 렌더링시킬 수도 있다.

    2) Pass

    • 렌더링 단위 (그리는 단위), 한 SubShader는 여러개의 Pass 를 가질 수 있고 이걸 멀티패스 라고 부른다.
      (1) Material

      • Ambient (주변광) : 물체를 덮은 일정한 색상(고정). 빛의 영향을 받지않고 항상 동일.
      • Diffuse (확산광) : 물체 표면에서 분산되어 들어오는 빛. 빛이 밝은곳에서는 강한 색상. 어두운쪽에선 약한 색상. 그림자가 진것처럼 표현됨
      • Specular (반사광) : 빛이 반사되어 하이라이트 되는 색상.
      • Emission (방출광) : 물체의 표면 자체에서 나오는 색상. (외부가 아닌 오브젝트 자체에서 발산)
      • Shininess (광택) : 하이라이트 선명도. 0~1 사이

      (2) 기타

      • Lighting On : 라이트 적용
      • ConstantColor [val,val,val,val] : 상수 칼라 등록
      • SetTexture[_Name] : Inspector 에서 넣어준 텍스쳐 적용
        = Combine texture * <옵션 or TEXTURE>
        = Combine <옵션 or TEXTURE> lerp(texture) <옵션 or TEXTURE> - texture(B) 의 알파값을 이용하여 A 와 C를 보간하여 결과값을 만듬
        <1> primary : 라이팅 계산 결과 적용 (primary DOUBLE = 2배, primary QUAD = 4배)
        <2> previous : 바로 직전까지의 결과를 적용
        <3> Constant : ConstantColor 명령어로 지정된 컬러 적용
        = Blend - 오브젝트의 알파값이 0.6이라고 한다면 DstFactor 0.4가 되어 오브젝트 60% 배경색상 40%비율로 섞여 반투명하게 보이는 효과가 나타남
        <1> One : 1값 입니다. 소스 또는 대상 컬러가 완전히 표시 되도록 하려면 이 값을 사용합니다.
        <2> Zero : 0값 입니다. 소스 또는 대상 값을 제거하려면 이 값을 사용합니다.
        <3> SrcColor : 스테이지 값을 소스 컬러 값으로 곱합니다.
        <4> SrcAlpha : 스테이지 값을 소스 알파 값으로 곱합니다.
        <5> DstColor : 스테이지 값을 프레임 버퍼 소스 컬러 값으로 곱합니다.
        <6> DstAlpha : 스테이지 값을 프레임 버퍼 소스 알파 값으로 곱합니다.
        <7> OneMinusSrcColor : 스테이지 값을 (1 - 소스컬러)로 곱합니다.
        <8> OneMinusSrcAlpha : 스테이지 값을 (1 - 소스알파)로 곱합니다.
        <9> OneMinusDstColor : 스테이지 값을 (1 - 대상컬러)로 곱합니다.
        <10> OneMinusDstAlpha : 스테이지 값을 (1 - 대상알파)로 곱합니다.

    3) Fallback

    • 모든 SubShader를 지원하지 않으면 Fallback에 지정해둔 Shader를 호출한다.

Vertex and Fragment Program

  • 표준 3D변환, 라이팅 및 텍스쳐 좌표생성 Off됨. setTexture 명령어가 필요없다.

  • 주로 CG라는 nVidia에서 만든 언어로 작성된다.

  • 일반적인 셰이더 텍스트에 CG 스니펫(짧은코드)가 Pass 블록에 삽입된다.

    1) Pass

    • CG 스니펫 전체는 CGPROGRAM과 ENDCG 키워드 사이에 적혀있다.

    • 컴파일 지시문은 #pragma 문으로 주어진다.
      pragma vertex NAME : NAME 함수 코드가 정점 프로그램을 포함.
      pragma fragment NAME : NAME 함수가 프래그먼트 프로그램을 포함.
      pragma surface NAME : NAME 함수가 <Lambert(디퓨즈)> 라이트 모델을 사용함

      • void NAME (Input IN, inout SurfaceOutput o) - light를 사용할 때 빛을 계산하는 함수를 따로 빼줘서 간단히 원하는 값을 조정할 수 있다.
        (1) SurfaceOutput

        • Albedo : 기본색상
        • Normal : 반사각을 결정하는 면의 방향
        • Emission : 오브젝트가 스스로 생성하는 빛의 양
        • Specular : 머테리얼이 빛을 반사하는 정도 (0~1)
        • Gloss : 스펙큘러 반사가 퍼지는 정도(세기)
        • Alpha : 머테리얼의 투명한 정도

        (2) SurfaceInput - 일반적으로 쉐이더에 의해 요구되는 텍스쳐 좌표가 있다. 이름 형식은 uv_TEXTURENAME

        • float3 viewDir - 뷰 방향을 포함합니다. 시차 효과, 림 라이팅 등의 계산에 사용
        • float4 screenPos - 반사 효과의 스크린스페이스 위치 또는 스크린스페이스 효과를 포함합니다.
        • float3 worldPos - 월드 공간상의 위치를 포함합니다.
        • float3 worldRefl - Surface Shaders이 o.Normal에 기입하지 않는 경우 월드 반사 벡터를 포함
        • float3 worldNormal - Surface Shaders이 o.Normal에 기입하지 않는 경우 월드 법선 벡터를 포함
        • float3 worldRefl; INTERNAL_DATA - Surface Shaders이 o.Normal에 쓸 경우 월드 반사 벡터를 포함.
          픽셀 당 법선 맵에 기초하여, 반사 벡터를 얻으려면 WorldReflectionVector(IN, o.Normal)를 사용.
        • float3 worldNormal; INTERNAL_DATA - _Surface Shaders가 o.Normal에 쓰는 경우 _ 월드 반사 벡터를 포함.
          픽셀 당 법선맵에 기초하며, 법선 벡터를 얻으려면 WorldNormalVector (IN, o.Normal)를 사용.
          ex)
        • o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
          Input에서 tex2D() 함수를 통해 _MainTex에서 uv_MainTex 좌표의 색상 정보를 가져와서 적용한다.
        • o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
          노멀맵을 받아와서 o.Normal에 UnpackNormal로 텍스쳐를 적용
Comments