Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
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
Archives
Today
Total
관리 메뉴

행복한 개구리

Unity Shader 21.05.03. 수업내용 본문

Unity/수업내용

Unity Shader 21.05.03. 수업내용

HappyFrog 2021. 5. 3. 10:39

Draw call : Cpu에서 Gpu로 그래픽을 처리하도록 전달하는 메시지(?)

픽셀 쉐이더 : 한 픽셀의 색을 결정하는 코드.

ex) 흰색 : RGB(100%, 100%, 100%) == RGB(255, 255, 255) == Float3(1.0, 1.0, 1.0) // Float3는 유니티코드

그래픽언어는 크게 3가지가 존재한다. HLSL GLSL CG

하지만 세가지가 모두 비슷해서 하나만 배워도 나머지를 사용가능하다.

 

여기에 투명도인 A(알파값)이 추가되면 Float3형식에서 Float4형식이 된다.

또한 픽셀쉐이더의 값은 0~1 표현되지만 데이터상으로는 1을 초과한 값이 그대로 남아있다.

ex) Float3(2,0,-1) =>표현은 Float3(1,0,0)와 같게 표현된다. // 하지만 데이터는 (2,0,-1) 그대로이다.

 

1.ShaderLab

매우 가볍고 하드웨어 호환성이 좋지만 기능이 상당히 제한적

 

2.SurfaceShader -> 우리가 쓸 방법

ShaderLab과 CG쉐이더 코드를 사용하는 방법

============================================================================

 

Shader와 Material을 결합시킨다.

Shader의 코드를 보면 이러한데, Properties는 Inspector에 출력되는 부분이고, 여기서 SubShder란의 코드를 보면 CGPROGRAM위론 유니티, 그 아래론 CG를 사용하는 것이다. 여기서 surf는 출력되는 값을 의미한다.

 

 

Albedo는 물체가 빛을 받았을 때 반사하는 정도를 나타내는 단위

Emission은 표면에 방출되는 색상과 강도를 제어

 

 

 

이렇게 surf에 입력한 값에 따라 색이 바뀐다.

 

 

Emission을 사용하면 이렇듯 좀 다른 느낌의 색이 나온다. 그리고 각 속성의 타입은 유니티 매뉴얼에서 찾자.

유니티 - 매뉴얼: 서피스 쉐이더 작성 (unity3d.com)

 

유니티 - 매뉴얼: 서피스 쉐이더 작성

서피스 쉐이더 작성 라이팅과 상호 작용하는 쉐이더 기술은 복잡합니다. 각종 라이트, 각종 그림자 옵션, 각종 렌더링 패스(포워드 및 지연 렌더링)가 있으며, 쉐이더는 그 복잡성을 처리해야 합

docs.unity3d.com

 

벡터처럼 연산도 가능하다.

당연히 곱연산도 가능.

 

위에서 설명했듯이 데이터값이 1을 넘더라도 표현은 1까지밖에 안된다.

 

*연산시 주의사항

예외적으로 한자리와는 언제나 가능하다.

ex)float3(0,1,0) + 1 = float(1,2,1)

 

이런 식의 연산도 가능하다.

 

요것도 가능.

============================================================================

프로퍼티에 코딩을 하면 이런식으로 인스펙터창에 생성되며 코딩을 할 땐 앞에 _를 붙여야한다. 또한 코드를 마칠 때 세미콜론을 코딩하지않는다.

프로퍼티 선언 형식 : _Name ("displayName", type) = default value

 

**주의

surf에서는 세미콜론으로 코드를 마무리해주어야한다. 또한 rgb는 grb등 순서를 바꾸어서 사용할 수 있다. 하지만 float4의 값의 순서도 따라서 바뀌어야 한다.

또한 o.Albedo = test.g로 사용하면 o.Albedo = 0이므로 검정색이 출력된다.

 

 

 

색을 이런식으로도 줄 수 있다.

** 구조체 아래에 변수를 선언할 때는 프로퍼티에 선언한 이름과 반드시 같아야한다.

 

알베도는 fixed3형식이므로 위 사진처럼 알파값을 따로 할당해주어야한다.

 

 

 

프로퍼티에서 인스펙터에 rgb값을 정할 bar를 만들고 구조체 아래에서 각 값을 변수로 선언했으며 surf 내에서 bar의 값에 따른 rgb값을 연동해주었다.

색상들은 각자의 형식을 지니고 있기 때문에 surf에서 색상을 지정해 줄 때는 반드시 값에 형식을 지정해주어야한다. float3를 안썼다가 아무런 변화도 없어서 당황했다..

정상작동.

Albedo = 빛까지 계산

Emission = 색상만 출력

 

둘을 함께 사용하면 밝아진다. 주로 둘 중 하나만 사용하며 색상만 확인할 때는 Emission을, 빛계산까지 할 때는 Albedo를 사용한다.

 

복습------------------------------------------------------------------------------------------------------------------------------

잘 작동한다. 이번엔 fixed형식으로 사용했다.

여기에 코드로 0.5f를 더해준다면 당연히 밝아진다.

굳이 f를 안붙여도 된다. 강사님은 안붙이신다.

이렇게 brightness도 코드로 bar를 뚫어서 조절할 수 있다. 하지만 rgb가 1,1,1일때와 brightness만 1일때의 밝기는 차이가 난다.

brighness 1 // rgb (1,1,1)

============================================================================

Texture

Input In은 UV좌표를 할당받지 않은 sampler이기때문에 tex2D의 작업을 통해 uv좌표를 텍스처에 할당해주고 그에 따른 uv좌표값에 각 색상정보를 할당한다.

 

프로퍼티의 기본값 뒤의 {}는 옵션을 나타낸다.

 

전 // 후

Material을 여러개를 쓰려면 이런식으로 변수도 추가로 선언하고 Input안에도 uv를 선언해주어야한다.

여기서 _Tex2("Sand Texture", 2d) = "white"{}의 white은 default값이라고 보면된다.

 

lerp(a, b, c)는 a,b텍스쳐를 c만큼 섞겠다는 함수이다.

하지만 c칸에 알파값을 넣게된다면

이런식으로 풀 부분만 빼고 나머지의 섞이는 값이 바뀌게 된다.

이게 풀 텍스쳐의 알파인데, 아마도 알파가 1인부분은 그대로이고 0인부분만 섞이는 듯 하다.

그 이유는 모래 텍스쳐의 알파값이 없기 때문(=0이라고 생각)이지 않을까...싶다. (layer개념처럼 0끼리 섞이고 1은 그 위에 항상 덮이는 형태라고 추측중)

 

    

이런식의 함수를 추가해서 아래의 bar형태로 모래의 밝기조절을 할 수 있다.

그리고 모래를 회색으로 변경해보았다

이 때는 Brightness의 값이 0만 되어도 하얗게 빛났기 때문에 -2~0사이의 값을 지정하도록 변경했다. 또한 흑백값은 세 값이 모두 같을 때이기때문에 세값을 더한 것에 평균을 구했다.

 

++평균값을 더하기만하고 나누질 않았기때문에 원래보다 밝은 값이 나왔던 것이다.

(c2.r + c2.g + c2.b)/3을 해주니 밝기를 -1~1값으로 지정해주어도 정상적으로 출력됐다.

 

============================================================================

텍스쳐 UV

텍스쳐의 x값(u값)만 출력했을 때 // y값(v값)만 출력했을때

아래는 UV값을 출력했을때

UV값은 XY값, RG값과 같기때문에 이런식으로 XY좌표에 할당하고 z는 비워둬야한다.

텍스처의 위치를 움직이기 위해 프로퍼티에 U와V 그리고 UV값 모두를 움직일 bar를 생성하고 할당받은 U,V값에 의해 텍스처가 움직이는듯 하게 보이기 위해서 tex2D로 UV좌표에 색상정보를 할당할 때 변화를 주었다.

UV값에 변화를 주면 텍스처가 바뀐 좌표에 색상정보를 할당하기 때문에 그림이 이동한 것 처럼 보이는 것이다.(단, 텍스쳐가 Repeat모드여야한다.)

============================================================================

쉐이더에 내장된 _Time함수이다. 각 값은 다음과 같다.

이를 이용하여 텍스쳐를 움직이게 할 수 있다.

 

코드는 이렇게 작성했으며 위의 bar로 변화를 주는 형식과 동일하다. 물론 쓰는 Time의 값과 +-값이 같을때는 좌표각각이 아닌 전체에 한번에 더해주거나 빼주는 식으로 해도 좋다.

이렇게.

 

이것도 마찬가지로 bar형태의 속도조절 창을 생성하여 속도를 조절할 수 있다.

다만 이렇게 바꿀때마다 휘리릭 감기는 효과가 나오는건 원래 이런건지 내가 잘못한 건지 잘 모르겠다.

 

============================================================================

렌더타입을 불투명하게 만들고, 큐도 불투명하게 만든다.(큐가 뭔진 잘 모르겠다.)

그리고 CG에서 alpha:fade를 선언하여 알파0인부분을 안보이게한다.

 

============================================================================

쉐이더로 불 만들기

1.바탕 텍스쳐를 넣는다.

2.렌더타입과 큐를 지정해준다.

3.알파를 안보이도록 CGPROGRAM바로 아랫줄에 선언해준다.

4.효과로 넣을 텍스쳐를 넣는다.

5.효과텍스쳐를 위로 올리는 함수와 스피드계수를 인스펙터에 띄워서 조절할 수 있도록 한다.

6.바탕텍스쳐와 효과텍스쳐의 교집합을 보여주기 위해 *를 사용하여 Alpha와 Albedo를 표현한다. (Albedo는 다른것으로 대체가능)

위 사진과 같이 텍스쳐가 겹치지 않는 부분은 투명하게 나온다.

============================================================================

 

이번엔 2번째 텍스쳐를 데이터로서 활용하는 방법이다. 검정색은 0,0,0이기때문에 현재 타일에는 아무런 변화가 없다.

 

하지만 데이터가 있는 텍스쳐를 준다면 타일은 물살 건너에 보이듯이 일렁이게 된다.

첫번째 텍스쳐를 불로 바꾸면 오른쪽과 같이 일렁이게 된다.

============================================================================

여기에 일렁임의 정도와 효과가 흘러가는 속도를 조절할 수 있는 기능을 인스펙터에 띄워서 조절해봤다.

이렇듯 잘 실행이 되며

 

일렁거림이 1.5이상 넘어가면 불이 아닌 화마의 형태를 띈다...

그리고 위에서 찔끔찔끔 삐져나오는 불이 보기 싫어서 y축으로 0.075만큼 올려줬더니 깔끔히 해결됐다.