[클라우디아 도피오슬래시]유니티 물리 기반 셰이더 개발 02
생성 및 적용
- Asset - Create - Material
- Asset - Create - Shader - Unlit Shader
- Asset - 생성한 Material 선택 - Inspector - Shader - 생성한 Shader 선택
Unlit
Shader "Unlit/Shader이름"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
셰이더 경로와 이름
Shader "Unlit/Shader이름"
특성
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
인스펙터 창에 보여질 각각의 특성을 여기에서 선언한다.
하위 셰이더
SubShader
{
여기에는 한 개 이상의 셰이더 내의 하위 셰이더(Sub-Shaders)를 둘 수 있다.
태그
Tags { "RenderType"="Opaque" }
태그는 정보를 표현하는 키와 값의 쌍으로 구성돼 있다. 예로는 어떤 렌더링 큐를 사용할지에 대한 것을 들 수 있다. 투명 및 불투명 게임 오브젝트는 각기 다른 렌더링 큐에서 렌더링된다.
Pass
Pass
{
각각 패스는 렌더링을 위한 정보와 실제로 셰이더에서 계산하는 코드와 같은 정보들을 포함한다.
CGPROGRAM과 ENDCG
CGPROGRAM과 ENDCG는 명령어의 처음과 끝을 나타넨다.
pragma선언
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
정점 셰이더와 픽셀 셰이더에 사용할 함수들을 지정하는 것과 같은 옵션 설정방법을 제공한다. 이는 셰이더 컴파일러에게 정보를 전달하는 방법이다.
Includes
#include "UnityCG.cginc"
입력과 출력 구조체
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
정점 셰이더는 프레그먼트 셰이더로 구조체를 통해 정보를 전달한다. v2f가 그 구조체다.
정점 셰이더는 입력 구조체를 통해 특정 정보를 요청할 수 있다. appdata가 그 구조체다.
SV_POSITION과 같이 세미콜론 다음에 오는 단어들을 시맨틱(semantics)이라고 한다. 컴파일러에게 구조체 내 특정한 맴버 내에 어떤 종류의 정보를 저장하고자 하는지 알려준다. SV의 뜻은 System Value이다.
변수 선언
sampler2D _MainTex;
float4 _MainTex_ST;
정점 함수와 프레그먼트 함수
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
셰이더 수정
Shader "Unlit/RedShader"
{
SubShader
{
Tags { "RenderType" = "Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return fixed4(1, 0, 0, 1);
}
ENDCG
}
}
}
속성추가
하드코딩은 좋은 습관이 아니다. 원하는 색상으로 변경 가능 할 수 있는 셰이더로 변경하자.
Properties
{
_Color("Color", Color) = (1, 0, 0, 1)
}
속성 블록은 _이름(“설명”, 타입) = 기본값 으로 구성된다. 속성의 종류에는 텍스처, 색상, 범위, 숫자를 포함하며 매우 다양하다.
fixed4 _Color;
CGPROGRAM 뒤쪽 어딘가에 선언을 추가한다.
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
이제 재질 인스팩터 패널에서 색상을 선택할 수 있다.
이 셰이더에는 다른 유니티 셰이더들과 마찬가지로 두 가지 언어가 섞여 있다. 하나는 Cg 라는 NVIDIA에서 개발한 셰이더 언어이다. CGPROGRAM과 ENDCG문 사이에 있는 것들이 이 언어로 작성됐다.
다른 하나는 셰이더랩(ShaderLab)언어이고, 유니티에서만 사용하는 Cg를 확장한 언어이다. CGPROGRAM 바깥쪽에 있는 모든 코드가 이 언어로 작성됐다.