이전까지 사용했던 것들은 Fixed Funtion Shader가장 기본적인 셰이더였다.

- vertex당 lighting 연산

- 하드웨어 관련 작업 x, 특수 커맨드 사용 x

- Programmable Shader를 지원하지않는 낮은 하드웨어에 대응하기위해 주로 사용




Vertex and Fragment Program에서는 (vertex & pixel shader라고 생각하면 됨) 

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

주로 CG라는 nVidia에서 만든 언어로 작성됨.

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


1
2
3
4
5
6
7
8
9
10
11
12
13
Pass {
    // ... the usual pass state setup ...
 
    CGPROGRAM
    // compilation directives for this snippet, e.g.:
    #pragma vertex vert
    #pragma fragment frag
 
    // the Cg/HLSL code itself
 
    ENDCG
    // ... the rest of pass setup ...
}
cs

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

먼저 컴파일 지시문이 #pragma 문으로 주어짐.


1
2
#pragma vertex vert
#pragma fragment frag
cs

#pragma vertex name에 의해 주어진 함수 코드가 정점 프로그램을 포함.

#pragma fragment name에 의해 주어진 함수가 프래그먼트 프로그램을 포함.



그래서 아래와 같은 형태로 구성된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Shader "Tutorial/Textured Colored" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,0.5)
        _MainTex ("Texture", 2D) = "white" { }
    }
    SubShader {
        Pass {
 
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
 
        #include "UnityCG.cginc"
 
        fixed4 _Color;
        sampler2D _MainTex;
 
        struct v2f {
            float4 pos : SV_POSITION;
            float2 uv : TEXCOORD0;
        };
 
        float4 _MainTex_ST;
 
        v2f vert (appdata_base v)
        {
            v2f o;
            o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
            o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
            return o;
        }
 
        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 texcol = tex2D (_MainTex, i.uv);
            return texcol * _Color;
        }
        ENDCG
 
        }
    }
}
cs




Surface Shader

라이팅 및 섀도우 계산을 위한 셰이더 코드를 자동으로 추가함으로써 CG 셰이더를 프로그래밍하는 단순화된 방법

빛을 계산하는 함수를 따로 빼줘서 간단히 원하는 값을 조정할 수 있기에 light를 사용할 시에 

Vertex and Fragment Shader로 만드는것보다 난이도가 쉬워짐.

빛에 대한 계산은 내부에 숨기며 surf라는 함수 안에 알베도, 노멀, 반사율 등 직관적인 속성만 지정하면됨.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Shader "Example/Diffuse Simple" {
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float4 color : COLOR;
      };
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = 1;
      }
      ENDCG
    }
    Fallback "Diffuse"
}
cs

Surface Shader는 여러 패스로 컴파일 되므로 Pass 대신 SubShader 블록에 배치됨.

#pragma surface .. 명령을 사용함

Posted by misty_
,