ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 불 이펙트
    유니티/게임그래픽 2024. 2. 20. 17:36

    이번에는 여태까지 배운것들을 이용하여 실감나게 움직이는 불 이펙트를 만들어보겠다

    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축 기준으로 위로 올라가게 하도록 만들어주면 되는것

     

    15-1일차 UV - Time

    14-4일차 - UV 사실 이전글에서 UV에 대한 설명이 부족하여 간단하게나마 찾아본적이 있었다. 하지만 이번엔 UV에 대하여 좀 더 구체적으로 알아보겠다 처음 UV를 사용했던것은 Tex2D라는 함수를 사

    sangeun00.tistory.com

    이미 바로 전글에서 숫자판이 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
Designed by Tistory.