유니티셰이더의기초 1~6까지 따라하면서 정리한 것
기본 형식
Shader "BasicShader" { SubShader { // Shaderlab code } }
개념상 (그럴걸이라고 믿고 가는) 지원 되는 디바이스 대응
Shader "BasicShader" { SubShader { // 매우 좋은 스펙 디바이스 } SubShader { // 좋은 스펙 디바이스 } SubShader { // 낮은 스펙 디바이스 } }
Shader "BasicShader" { SubShader { // Shaderlab code } Fallback "Diffuse" }
Shader "BasicShader" { SubShader { // Shaderlab code Pass { } Pass { } } Fallback "Diffuse" }
키워드
셰이더의 목적은 재질과 라이팅에 반응되도록 하는 것이므로,
SubShader 의 Pass 내부에 Material 키워드로 조명 방식을 추가한다.
Material { Diffuse (0,0,1,1) Ambient (0,0,1,1) }
재질이 표시되려면 조명을 (재질은 조명을 받은 반응이므로) 추가하는데,
Lighting On
Material, Lighting 키워드가 Pass 블럭 내부에 있다.
클래식한 기능이지만, 셰이더 이전의 쓰던 기능은 다 되므로 은근히 막강.
변수다,생각.
Material { Diffuse (0,0,1,1) Ambient (0,0,1,1) }
위의 예제에서는 매트리얼에 값을 고정 값으로 설정 했는데,
Properties 키워드와 구문 블럭 내부에, 변수 역할의 프로퍼티를 추가할 수 있다.
(유니티 인스펙터에 노출되는 그것들)
Diffuse와 Ambient에 대한 프로퍼티를 추가. 다른 색상을 지정하도록 코드를 변경.
_DiffuseColor ("DiffuseColor", COLOR) = (0,0,1,1)
2D 프로퍼티로 텍스쳐를 설정해서 오브젝트에 입힐 수 있다.
위의 결과는, 텍스쳐를 오브젝트에 적용되었지만 라이팅 연산이 반영되지 않았다.
SetTexture 구문을 확장해서 ( {, }를 추가한다 ) 텍스쳐 연산 방법을 추가한다.
SetTexture [_MainTex] { Combine texture * primary }
텍스쳐 색상(texture)과 이전 라이팅 계산 결과(primary)를 곱해서 화면에 표시한다.
Combine의 조합 방식
combine <src1> * <src2> | 곱한다. 결과는 다소 어두워진다. 하지만 색상 결합의 기본은 곱이므로 이걸 사용한다. |
(0.2 * 0.2 = 0.04) 색상이 점점 0(검정)에 가까워지므로. | |
하지만 1(white)로 곱하면 원래 색상이 나오므로. | |
combine <src1> + <src2> | 더한다. 밝아진다. 점점 1에 가까워지니까. |
combine <src1> - <src2> | 빼는데.. 이건 좀 미묘. |
combine <src1> +- <src2> | src1을 src2에 더한 다음, 0.5를 뺀다. (signed add?) |
combine <src1> lerp(<src2>) <src3> | src2의 알파값으로 src1(=1)과 src3(=0)사이의 보간 값을 사용한다. |
숫자 범위가 (1~0)임의 주의 | |
combine <src1> * <src2> + <src3> | src1.rgba * src2.a + src3 . 이건 뭘까.. |
combine <src1> * <src2> +- <src3> | src1.rgba * src2.a + src3 - 0.5 |
combine <src1> * <src2> - <src3> | src1(전체) * src2(알파값) - src3(전체) |
src 프로퍼티는 아래 키워드로 변경 가능
combine <연산> <보정용 키워드>
SetTexture [_MainTex] { Combine texture * primary DOUBLE }
combine src1 src2, color(alpha)
“,” 로 색상과 알파 부분을 분리.
combine lerp 활용
텍스쳐만 표시되도록 재질 설정을 삭제하고 텍스쳐만 받는 셰이더 작성
두번째 텍스쳐는 알파값이 있는 투명한 이미지인데, 투명 처리를 하지 않아서 그림이 깨져보인다.
combine lerp()로 알파를 반영 해본다.
// texture의 알파값으로 src1, src2의 비율을 조정한다. 알파가 1(not 투명) _SubTex값을 사용, 0에 가까워질수록 previous를 사용 SetTexture [_SubTex] { Combine texture lerp(texture) previous }
셰이더 수정
반투명 효과 같은, “색상섞은 후 효과”를 얻으려면 Blend 로 조합 방법을 적는다.
기본 포맷
Blend <SrcFactor> <DstFactor>
(새로 찍을 색상 값) SrcFactor * (기존 배경의 색상) DstColor
색상을 섞겠다는 뜻인데, SrcFactor와 DstFactor에는 블렌딩에 사용될 색상 속성(Blend Factor)을 지정해야 한다.
Blend SrcAlpha OneMinusSrcAlpha
원래 문서의 설명(이 명료해서)
0~1 사이의 색상이나 알파 값을 어디에서 가져올 것이냐에 대한 선택 구문
잡…
Blend SrcAlpha DstAlpha | 이 경우, 둘다 0.6이면 어떻게 될려나. 최대값은 1이니까 |
SubShader, Pass의 안쪽에 위치.
텍스쳐 두장만 표시하는 셰이더에, Blend를 넣어 봅니다.
Blend만 넣어서는 결과가 나오지 않음.
어느 정도의 알파값을 SrcAlpha로 지정할 것인지 정할 수 있는 코드를 넣어야 하는데,
색상값을 입력 받아
이 색상의 알파값을 최종 알파값으로 사용하도록 코드를 추가.
렌더링 큐를 설정하지 않는데도 앞뒤 제대로 나오니.. 쩝인데. 혹시 모르니,
오브젝트의 앞 뒤로 반투명하게 나와야 할게 제대로 나오지 않는다면 렌더링 큐 설정이 필요하다는 뜻.
Shader “Study/TransObject” {
Properties { _Alpha ("AlphaColor", COLOR) = (0,0,0,1) _MainTex ("MainTex", 2D) = "white" {} _SubTex ("SubTex", 2D) = "white" {} } SubShader {
Tags { “Queue” = “Transparent” }
Pass { Blend SrcAlpha OneMinusSrcAlpha SetTexture [_MainTex] SetTexture [_SubTex] { ConstantColor[_Alpha] Combine texture lerp(texture) previous, constant } } }
} </code>
렌더링 큐를 Transparent로 설정해서, Transparent 에 해당되는 녀석들이 그려질때 같이 그려지도록 설정한다.
오브젝트가 렌더링 되는 순서를 정할 수 있는데, 5단계가 기본이다.
키워드 | 숫자인덱스 | 설명 |
---|---|---|
Background | 1000 | 가장 먼저 그린다. 다른 것들에 가린다는 뜻 |
Geometry 기본값 | 2000 | 대부분 여기에 해당됨. 반투명 오브젝트 위주 |
AlphaTest | 2450 | 반투명한 Geometry? 가 뭐지? 나무? 알파 테스트를 필요 있는 것. |
Transparent | 3000 | 투명한 (유리, 파티클) 오브젝트는 여기로 와야 함. 이게 거의 많이 쓰일 것 같은데.. |
Overlay | 4000 | 가장 나중에 그리는데, 언제든 보이는 가장 앞에 있는 (렌즈플레어 같은) 오브젝트 |
렌더링 큐는 Tag 키워드로 입력하는데,
Tags = { "Queue" = "Transparent" }
또한 기본 키워드에 숫자를 더하거나 빼서 렌더링 순서를 임의 설정할 수 있다.
Tags = { "Queue" = "Geometry+1" }
셰이더에서도 색상값은 (0~1) 사이의 값을 사용.
범위 값이, 0~1 사이 값인 것만 주의 하면 연산할때 도움이 된다.