-
이번에는 여태까지 배운것들을 이용하여 실감나게 움직이는 불 이펙트를 만들어보겠다
Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _MainTex2 ("Texture2", 2D) = "white" {} } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } // 1 CGPROGRAM #pragma surface surf Standard alpha:fade // 2 sampler2D _MainTex; sampler2D _MainTex2; struct Input { float2 uv_MainTex; float2 uv_MainTex2; }; void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 d = tex2D(_MainTex, IN.uv_MainTex); fixed4 c = tex2D(_MainTex2, IN.uv_MainTex2); o.Emission = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
우선 두 텍스쳐를 입력받고 첫번째 _MainTex를 출력하는 스크립트를 짜보자
주석을 걸어둔 2줄은 이미지를 투명하게 만들기 위한 알파채널 활성화 코드이다
그리고 두 이미지를 집어넣는다
아직 변수 c의 rgb를 출력하도록 코드를 작성했기에 Scene뷰에는 첫번째 이미지만 보인다
이제 _Time 변수를 활용하여 UV 애니메이션을 만들어보겠다
애니메이션이 만들어지는 과정은 매우 간단하다
fireTest라는 틀위에 4_2라는 이미지가 y축 기준으로 위로 올라가게 하도록 만들어주면 되는것
이미 바로 전글에서 숫자판이 x,y축으로 움직이게 하는 법을 배웠기에 바로 응용하면 된다
Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _MainTex2 ("Texture2", 2D) = "white" {} } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } CGPROGRAM #pragma surface surf Standard alpha:fade sampler2D _MainTex; sampler2D _MainTex2; struct Input { float2 uv_MainTex; float2 uv_MainTex2; }; void surf (Input IN, inout SurfaceOutputStandard o) { float2 uv = IN.uv_MainTex2; fixed4 c = tex2D(_MainTex, IN.uv_MainTex); fixed4 d = tex2D(_MainTex2, float2(uv.x, uv.y - _Time.y)); // 2번째 이미지를 y축 위로 올리는 애니메이션 o.Emission = c.rgb * d.rgb; o.Alpha = c.a * d.a; // 이미지의 합성을 위해 c와 d의 rgb, 알파를 곱해준다 } ENDCG } FallBack "Diffuse"
실행결과를 보면 1번째 이미지틀에 2번째 이미지가 위로 올라오는 모습을 볼 수 있다
이번에는 조금 더 퀄리티가 있는 불을 만들어보겠다
Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _MainTex2 ("Texture2", 2D) = "white" {} } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } CGPROGRAM #pragma surface surf Standard alpha:fade sampler2D _MainTex; sampler2D _MainTex2; struct Input { float2 uv_MainTex; float2 uv_MainTex2; }; void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex); fixed4 d = tex2D(_MainTex2, IN.uv_MainTex2); o.Emission = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
다시 한번 스크립트를 짜주고 두개의 텍스쳐를 입력받게하자. 이번엔 서로의 이미지를 곱해주지 않는다
확실한 효과를 보기 위해 첫번째 이미지는 숫자표, 두번째 이미지는 단순 검정색으로 넣는다
Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _MainTex2 ("Texture2", 2D) = "white" {} } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } CGPROGRAM #pragma surface surf Standard alpha:fade sampler2D _MainTex; sampler2D _MainTex2; struct Input { float2 uv_MainTex; float2 uv_MainTex2; }; void surf (Input IN, inout SurfaceOutputStandard o) { //데이터 (단순 검은색) fixed4 d = tex2D(_MainTex2, IN.uv_MainTex2); //데이터를 적용할 텍스쳐 (숫자판 이미지) fixed4 c = tex2D(_MainTex, IN.uv_MainTex + d.r); // 변경된 부분 o.Emission = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
지금 변경된것은 c에 들어갈 uv값에 d.r을 더해준것뿐
tex2D (_Maintex, IN.uv_MainTex + d.r);
d에는 검은색 이미지가 들어갔으니 (0,0,0,1)이다. 즉 d.r은 0
그렇기에 uv전체에 d.r을 더한다면 u와 v에 둘다 0을 더해준다는 의미도 된다
하지만 0을 더해준것은 아무런 변화도 일어나지 않는다
하지만 d.r(0) 대신 0.5를 더해준다면
이렇게 숫자판이 이동한것을 볼 수 있다
그러니 d가 검은색이 아니라 회색이었다면 이렇게 이동했을것이고, 흰색이라면 1.0만큼 이동해 원래 이미지대로,
(1,0,0)인 빨간색이라도 마찬가지였을 것이다. 즉 컬러는 숫자다
데이터로 쓰일 이미지에 각각 dot과 noise를 가져와보자.
모든 원리를 정확히 이해하지는 못하더라도 r값에 맞춰 적절히 잘 구겨진다는거 정도는 알겠다
이제 이미지를 흐르면서 구겨지게 만들어보자
void surf (Input IN, inout SurfaceOutputStandard o) { //데이터 float2 uv = IN.uv_MainTex2; fixed4 d = tex2D(_MainTex2, float2(uv.x,uv.y - _Time.y)); //데이터를 적용할 텍스쳐 fixed4 c = tex2D(_MainTex, IN.uv_MainTex + d.r); // 변경된 부분 o.Emission = c.rgb; o.Alpha = c.a; }
아주 간단하다. _Time 변수를 이용해 데이터를 y축으로 올려주기만 하면 된다
오ㅋㅋ 이건 좀 신기하다. 항상 보기만했던 이런 이펙트들이 구현되는 원리는 기초적으로나마 알게되니 참 재밌다
이제 텍스쳐를 불 이미지로 바꿔주자
'유니티 > 게임그래픽' 카테고리의 다른 글
Vertex Color (1) 2024.02.21 _Time 변수 스크립트 기본형 (0) 2024.02.20 UV - Time (2) 2024.02.20 UV (0) 2024.02.19 이미지 흑백으로 만들기, Lerp 함수 (0) 2024.02.19