그래픽(기타)

(SRP)쉐이더 서브그래프 제작 - SimpleRaderMask

에페아 2020. 1. 6. 12:03

모든 것의 시작은 이 벽이었다...

저거 한번 만들어보고 싶은데 마스크 텍스쳐를 따로 만드니까 크기 면이나, 루핑 면에서 개인적으로 좀 불편하더라고요

그래서 한번 텍스쳐 없이 저런거 만들 때 쓸만한 마스크를 만들 수 있지 않을까? 하는 생각에서 만들어보게 되었습니다

 

결과물은 이렇습니다!

_speed : 마스크가 흘러가는 속도를 조절할 수 있습니다

_offset : 이걸 조절해서 다른 마스크와 더했을 때 면이 겹치는 걸 막을 수 있습니다

(혹은 이걸 이용해서 2줄 나왔다가 한줄 비는 형태의 패턴을 만들 수도 있습니다)

_blank : 레이더 선의 간격을 조절할 수 있습니다

_bold : 레이더 선의 굵기를 조절할 수 있습니다

_direction : 레이더의 방향을 정할 수 있습니다(1 : 왼쪽, 2 : 오른쪽, 3 : 위쪽, 4 : 아래쪽)

 

SGSimpleRaderMask.shadersubgraph
0.13MB

안이 어떻게 구현되어있는지 궁금하거나, 사용하고싶으신 분들은 이 파일을 받아서 뜯어보시면 되겠습니다

 

아래는 구현 내용 설명입니다

원래는 방향을 Enum으로 받아오려 했는데 enum이 먹통인지 에디터에서 구동이 안되길래 Vector1을 받아오도록 만들었습니다

근데 방향값으로 쓰려면 계산에 필요한 각 방향마다의 벡터가 있어요

왼쪽 : 1, 0, 1, 0

오른쪽 : 1, 0, 0, 1

위쪽 : 0, 1, 1, 0

아래쪽 : 0, 1, 0, 1

근데 서브그래프 사용자한테 이런걸 배우게 할 순 없으니까 그나마 최대한 간편하게 인풋을 1~4로 받게 하고

서브그래프 내부에서 이 1~4를 방향에 맞는 벡터값으로 변환해주는 작업을 먼저 했습니다

 

그래서 그룹 오른쪽 끝에 보면 Vector4가 밖으로 빠지는 걸 볼 수 있죠

 

그다음 위에 direction check에서 받아온 값을 토대로 기초 마스크를 만들기 시작합니다

 

먼저 이 마스크를 가로방향으로 만들건지, 세로방향으로 만들건지에 따라 마스크를 만듭니다

가로이면 앞에서 받아온 벡터값의 xy가 1,0이 되게 했고, 세로이면 xy가 0,1이 되게 만들어놨습니다.

 

그걸 토대로 uv를 이용해 uv의 가로값*x, uv의 세로값*y 이 두개를 더합니다

1, 1이나, 0, 0인 경우는 없으니 무조건 uv의 가로값이나 세로값을 추출해오겠죠

그 추출된 값이 저 사진 오른쪽에 있는 add의 결과물이죠

 

그 다음은 0->1 방향인지, 1->0방향인지에 따라 마스크를 수정합니다

0->1방향은 오른쪽, 위쪽이고, 1->0 방향은 왼쪽, 아래쪽입니다

앞의 add로 넘어온 마스크는 0->1방향으로 넘어오게 되죠

 

위에 가로세로 구분하는 방법과 비슷하게

이번엔 zw값을 이용해서 방향을 구합니다

그럼 원하는 방향에 맞는 기본 마스크가 만들어지게 되죠

 

 

 

 

그리고 저렇게 나온 결과물을 굵기 / 간격 / 속도 에 따라 다시 연산을 해줍니다

 

먼서 속도에 따라 스크롤이 되는 기능부터 봅시다

time값과 블랙보드에 걸어놓은 속도값을 곱하고

이 값에 오프셋을 더합니다(오프셋의 용도는 맨위에서 설명했으니 넘어갑니다)

그리고 더한 값에 modulo를 먹이는거죠 간격값만큼.

그럼 이런 식으로 확 꺼졌다가 점점 밝아지는데

이걸 그대로 더하면 마스크의 앞쪽부분이 가장 어둡게 나와요 방향도 달라지고요

 

그래서 이 값을 한번 반전시켜줍니다

간격값(더하는 최대값)에서 저 modulo로 출력된 값을 뺍니다

그럼 확 밝아졌다가 점점 어두워지죠

 

이걸 이제 기초 마스크에 더해주면

이런식으로 나오는것이죠

 

 

그 다음 간격/굵기 구현

간격은 기본 마스크의 결과물에 간격 길이만큼 modulo를 걸어버립니다

만약 간격이 0.7이라면

0 / 0.1 / 0.2 / 0.3 / 0.4 / 0.5 / 0.6 / 0 / 0.1 / 0.2 / 0.3

이런식으로 결과가 나올것이고, 딱 0.7간격으로 점점 밝아지고 확 어두워지고 하겠죠

(그래프에서는 마스크가 겹치는 경우 생기는 연산오류를 방지하기 위해서 굵기+간격을 실제 간격값으로 사용했습니다)

 

저상태로 그대로 두면

이런식으로 간격값과 마스크 굵기가 똑같은 결과만 나올겁니다

이상태에서 굵기를 제어하고 싶으면 어떻게 해야 할까요

 

저기에다가 0.3을 빼볼까요?

우리가 아까 간격을 0.7로 해놨으니 원본은 0~0.7 사이가 계속 반복되겠죠?

근데 0.3을 뺐으니까 -0.3~0.4 사이로 반복이되고,

0 아래는 다 검정색이니까 0.3만큼의 공백을 남기고, 마스크의 굵기는 나머지인 0.4가 됩니다!

 

이렇게만 두면 또 마스크가 전체적으로 어두워지니까 최대값이 1이 되도록 만들어줘야겠죠

0.3을 뺀 후 저 벡터의 최대값은 0.4입니다.

0.4와 곱했을 때 1이 되는 수를 곱해주면 마스크의 두께는 유지되면서 최대값이 1이 되겠죠?

그래서 Divide로 1과 굵기값을 나눕니다

나눈 값을 위에서 계산했던 벡터와 곱해주면

오른쪽 위의 노드 결과처럼 최대값이 하얀 1이 되는걸 볼 수 있습니다!

왼쪽 노드와 비교해보면 밝기차이가 확 나죠?

 

+만드는 도중 알게된 사실

칼라값을 음수로 만들어서 출력하면 additive에서도 검은색이 나오긴 합니다

 

암튼 굵기조절할 때 벡터에서 값을 빼서 음수가 되가지고 생기는 현상인데

그냥 다 연산한 후에 maximum을 걸면 됩니다

둘중 더 큰값을 출력하는건데, 한쪽엔 연산해놓은 벡터 연결시키고 다른쪽에는 0을 입력해놓으면

0 아래값들은 다 0으로 만들어버리죠

 

그래서 이런식으로 결과물이 나옵니다!

 

 

이제 이 그래프로

이런 거라던가

요런것도 만들 수 있습니다

 

요건 십자선 텍스쳐 가져와서 마스크랑 곱해가지고 만든 결과물입니다

반응형