이전 단계에서는 화면에 파랑색을 표시 했습니다.
다시 복습하면
작성한 Shader를 보기 위해서는 다음 과정을 거칩니다.
Shader 작성 -> 매터리얼에 작성한 Shader 선택 -> Quad 오브젝트에 매터리얼 등록
-> Quad 오브젝트를 Scene 배치 -> 카메라를 Orthographic 으로 수정.
------------------------------------------------------------------------------------------
이번에는 쿼드의 색상을 계속 변하도록 만들어 봅시다.
------------------------------------------------------------------------------------------
fixed3 structure x,y,z에 대응하는 값들을 다음과 같이 세팅해봅시다.
x: (sin(_Time.y) + 1) / 2
y : 0
z : (cos(_Time.y) + 1) / 2
sin, cos 함수는 -1 ~ 1의 Range를 가지고 있으므로 + 1을 하고 2로 나누어 주면
0 ~ 1 Range를 가지게 됩니다.
fragment shader의 리턴값은 fixed4 type 입니다.
(x,y,z,w) 해당되는 값은 RGBA 값 입니다.
x : 빨강, z : 파랑 값이 0 ~ 1로 변하게 되므로, 색의 변화는 빨강 계열 <--> 파랑 계열로 변화가 일어날 것 입니다.
Shader "SimonLee/Shader2Unlit"
{
Properties
{
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 frag(v2f_img i) : SV_Target
{
fixed3 color = fixed3((sin(_Time.y) + 1) / 2, 0, (cos(_Time.y) + 1) / 2);
return fixed4(color, 1).gbra;
}
ENDCG
}
}
}
fixed(color, 1) 뒤에 붙은 gbra는 뭘까요 ?
rgba순서를 gbra로 바꾼 다는 의미 입니다.
fixed4 원소의 (x, y, z, w) 순서가 (y, z, x, w)로 변화가 됩니다.
RenderType 경우는 투명이 아니면 Opaque를 사용을 합니다.
그 밖에 여러 type이 존재하는데 아래 공식문서를 참조 합시다.
https://docs.unity3d.com/kr/530/Manual/SL-ShaderReplacement.html
------------------------------------------------------------------------------------------
이번에는 색상을 인자로 받아서 블렌딩 해봅시다.
------------------------------------------------------------------------------------------
Properties 항목에는 인자로 받을 놈들을 넣어 줍시다.
우리는 블렌딩할 색상 A, B를 입력으로 넣습니다.
자세한 건 아래 문서를 참고하시고요
https://docs.unity3d.com/kr/530/Manual/SL-Properties.html
Unity에서는 밑줄 표시로 셰이더 프로퍼티 이름을 시작하는 것이 일반적이라네요.
프로퍼티에 등록을 했으면 CG Shader 에서 선언을 해야 사용할수 있습니다.
fixed4 _ColorA, fixed4 _ColorB로 선언을 했습니다.
블렌딩을 할때 lerp 함수를 사용했네요
lerp 함수는 (Source, Destination, delta)로 구성되어 있습니다.
delta 값은 0 ~ 1의 범위를 가지며 (Source * delta) + (Destination * ( 1- delta)) 계산됩니다.
쉽게 말해서
0이면 Source에 가깝고, 1이면 Destination에 가깝습니다.
delta 값은 i.uv.x를 사용했고, 이는 v2f_img라는 type을 사용하는데
struct v2f_img
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f_img sturct에 두번째 원소에 uv 가 있습니다.
uv는 Texture Cordinates 입니다.
Texture Coordinates는 0 ~ 1의 범위를 가지고 Texture에서 색상을 샘플링 할때 사용됩니다.
현재 Unity Quad 오브젝트를 사용하고 있습니다.
Quad 오브젝트의 4개의 꼭지점에 해당하는 UV 값이 지정이 되어 있습니다.
위 값들은 래스터 라이제이션에서 보간되어 각 프래그먼트마다 보간된 UV값을 가지고 있습니다.
이 보간된 UV중 첫번째 원소 x값도 역시 0 ~ 1 범위를 가지고 있습니다.
Quad 오브젝트 각 픽셀의 x값이 커짐에 따라 uv.x도 같이 커지기 때문에,
오른쪽으로 갈수록 ColorB의 색상과 가까워 집니다.
Shader "SimonLee/Shader4Unlit"
{
Properties
{
_ColorA("Color A", Color) = (1,0,0,1)
_ColorB("Color B", Color) = (0,0,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _ColorA;
fixed4 _ColorB;
fixed4 frag(v2f_img i) : SV_Target
{
float delta = i.uv.x;
fixed3 color = lerp(_ColorA, _ColorB, delta);
return fixed4(color, 1.0);
}
ENDCG
}
}
}
------------------------------------------------------------------------------------------
마지막 예제 입니다.
또다른 블렌딩 예제입니다.
------------------------------------------------------------------------------------------
이번에는 Vertex Shader도 정의해 봅시다.
vert라는 함수가 Vertex Shader 입니다.
아래 보면 Vertex Shader에서 Framgment Shader로 보간을 할 정보를 넘겨주는데,
v2f 구조체에서 vertex, position, uv 입니다.
VertexShader에서 해야하는 일중 하나가 로컬스페이스 좌표를 클립스페이스로 옮겨주어야 합니다.
이를 위해 내부 함수인 UnityObjectToClipPos() 함수를 사용합니다.
좌표계 -0.5 ~ 0.5 범위를 가지게 됩니다.
여기서 좌표값에 2를 곱하게 되면 ,
좌표계 -1 ~ 1의 범위를 가지게 됩니다.
Saturate 함수는 0 ~ 1 범위로 만들어 줍니다.
0 보다 작으면 0, 1보다 크면 1, 중간 값이면 그대로 값을 취합니다.
그림을 그려보면 다음과 같습니다.
클립 스페이스에서 사용한 position에 해당하는 좌표는 검은색이고, saturate 통해 변경된 값은 파랑색으로 표시했습니다.
검은색 영역은 R, G에 해당하는 영역이 (0, 0) 이고
빨강색 영역은 R, G ( 1, 0 ), 초록색 영역은 R, G ( 0, 1 ) , 노랑색은 (1, 1) 입니다.
여기서 0에 해당하는 영역은 saturate에 의해 확실하게 0 인 반면에,
1이라고 쓴 영역은 0 ~ 1에 해당하는 값을 가졌기에 경계가 스무스하게 블렌딩 된것을 확인할 수 있습니다. ^^
Shader "SimonLee/Shader5Unlit"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 vertex: SV_POSITION;
float4 position: TEXCOORD1;
float2 uv: TEXCOORD0;
};
v2f vert(appdata_base v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.position = v.vertex;
o.uv = v.texcoord;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed3 color = saturate(i.position * 2);
return fixed4(color, 1.0);
}
ENDCG
}
}
}
참고 사이트
CG API
https://developer.download.nvidia.com/cg/index_stdlib.html
예제 가져온 곳
'Shader CG' 카테고리의 다른 글
1.2 도형 - Draw Rectangle - 1 (0) | 2023.07.09 |
---|---|
1.1 도형 - draw Circle (0) | 2023.07.09 |
기초 3. 블렌딩 해보자 (step, smoothstep) (0) | 2023.07.06 |
기초 1. Shader 배워보자. (0) | 2023.07.05 |
기초 2. 기본 색상 출력 해보기 (0) | 2023.06.28 |