본문 바로가기
공허의 유산/표현의 자유

[Unity3D/Shader] 05. 텍스쳐를 이용하여 불꽃 효과 내기

by 바른생활머시마 2023. 2. 22.
728x90
반응형

앞에서 텍스쳐링에 대한 맛보기를 해보았습니다.

[Unity3D/Shader] 04. 텍스쳐 맛보기 (tistory.com)

 

[Unity3D/Shader] 04. 텍스쳐 맛보기

앞에서 출력 구조체에 대해서 조금 알아보았습니다. https://learn-and-give.tistory.com/74 [Unity3D/Shader] 03. SurfaceOutputStandard 맛보기 앞에서 Property에 대해서 알아보았습니다. [Unity3D/Shader] 02. Editor UI와 연동

learn-and-give.tistory.com

텍스쳐는 정말 활용도가 높은 데이터입니다. 단순히 표면에 그려질 이미지에 머물지 않고, 그 용도가 매우 다양합니다. 엄밀히 말하면, 2차원 형태의 데이터 구조이고 그 중 가장 보편적으로 많이 쓰이고 있는 형태가 이미지일 뿐, 그 데이터가 이미지가 아닌 다양한 형태의 활용이 가능합니다.

 

샘플 이미지가 좀 필요한데, 참고 서적의 예제 파일을 활용 해 보겠습니다. Plane 오브젝트를 추가해서 앞에서 만들어뒀던 재질도 적용 해 줍니다. 아래 Project에 추가 된 이미지들을 이용해서 진행 해 보겠습니다.

불꽃1

 

우선 텍스쳐를 이미지로 사용하는 사례로써, 두 개의 이미지를 이용하여 불꽃 효과를 표현하는 것을 살펴 보겠습니다.

두 개의 이미지에 다음 두 개의 텍스쳐를 할당합니다. 일단 이 상태에서 어떻게 되는지 한번 보겠습니다.

 불꽃 모양은 고정되어 있고, 화염이 그려진 텍스쳐는 대각선 방향으로 흐르고 있습니다. 이 화면은 한쪽 방향으로 연속 된 이미지로 되어 있습니다. 연결 된 방향으로 흘러가도록 해줘야 하겠네요. 불꽃도 방향을 돌려서 똑바로 세워주는게 보기 좋겠네요.

코드는 아래와 같이 수정해줍니다. 한쪽방향으로만 좌표를 더하기 위해, UV 성분을 각각 분리한 후, U는 그대로 쓰고, V에만 Time을 빼주도록 하였습니다. 

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D (_MainTex2, float2(IN.uv_MainTex2.x,IN.uv_MainTex2.y - _Time.y));
            o.Albedo = lerp(c.rgb, d.rgb, d.a);
            o.Alpha = c.a;
        }

결과는 아래 그림처럼 고정 된 불꽃 앞으로 화염이 위로 스크롤 되어 올라갑니다. 그런데, 두 개가 전혀 어울리지 못하고, 특히나 뒤 배경에 있는 불꽃은 멈춰 있으니 더욱 어색하게 보입니다. 두 색을 곱해보면 ???

 

 

두 색을 곱하는 식으로 변경하고,

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D (_MainTex2, float2(IN.uv_MainTex2.x,IN.uv_MainTex2.y - _Time.y));
            o.Albedo = c.rgb * d.rgb;
            o.Alpha = c.a;
        }

결과를 보니, 그냥 두 이미지를 반투명하게 섞어 놓은 것 같습니다. .

알고보니 반투명을 사용 할 수 있도록 설정을 하지 않았군요.

설정을 하면~

원래 불꽃의 모양도 변화가 거의 없어서 좀 심심하게 보이네요. 

lerp를 사용해서 두 불꽃을 좀 섞어봤는데, 0.8 정도로 섞으니까 가장 좋아보이네요. 하지만 뭔가 좀 아쉬운...특히 불꽃의 윤곽 모양이 고정되어 있어서 특히 어색하게 보이는 것 같습니다. 올라가는 불꽃의 알파 변화가 좀 더 있으면 좋을 것 같아요.

반응형

 

 

불꽃2

 

첫번째 불꽃에서 가장 아쉬웠던 부분은 딱 정형화 된 움직임(위로 이동)과 정해진 윤곽 모양이었습니다. 실제로 불은 윤곽 모양도 바뀌도 움직임도 구불구불하게 움직이죠. 이런 효과는 어떻게 만들어 낼 수 있을까요???

 

책에서 소개한 방법은, 두번째 텍스쳐를 이미지로써가 아니라 텍스쳐 좌표로써 사용하게 하는 방법입니다.

이를 위에서 랜덤 패턴이 그려진 이미지를 두 번째 이미지에 할당합니다.

 

위 그림에서 보듯 불꽃 이미지는 아무 정형화 된 모습으로 그려져 있는데, 저것을 일렁거리게 하려면 UV좌표를 일렁거리게 해야합니다. 이를 위해 UV좌표에 두번째 텍스쳐의 픽셀값을 좌표값으로써 사용하는 것입니다. 즉, 두번째 이미지의 UV 좌표에 있는 rgb값 중 어떤 채널 값을 U나 V에 더하거나 빼주면 첫번째 텍스쳐 좌표아 일렁거리게 되는 것입니다.

 코드는 아래와 같습니다.

 그리고, 지금 보니 불꽃이기 때문에 Albedo 보다는 Emission에 할당하는 것이 더 적절했었군요.

 

코드는 아래와 같습니다. 불꽃의 이미즈는 그대로 사용하고, 그 UV좌표를  두번째 이미지를 참조하여 계산하기 때문에 순서가 바뀌었습니다. Albedo 대신 Emission으로 적용하고~

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 d = tex2D (_MainTex2, float2(IN.uv_MainTex2.x,IN.uv_MainTex2.y-_Time.y));
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex + d.r);
            //o.Albedo = lerp(c.rgb, d.rgb, 0.8);
            o.Emission = c.rgb;
            o.Alpha = c.a;
        }

 

결과는... 이전보다 훨씬 좋아졌지만 원래 텍스쳐 이미지에 그려졌던 불꽃의 크기보다 일렁이는 크기가 작아서 조금 아쉽네요. 제곱을 하면 값이 더 작아질 것이니, 제곱으로 나눠주면??? (연산량이 불필요하게 많아지는데 그냥 곱하기를 해줘도 될 것 같고...)

 

Play 모드에서 쉐이더 코드를 수정하고 저장하니 Play 상태에서도 적용이 되는군요~

곱하기 5를 했더니 많이 일렁거리네요. 중간 중간에 가로로 긴 줄 같은 것이 가는 것은 어쩌면 UV repeat/ wrap 뭐 그런 것과 관련이 있지 않을까 싶네요.

 

이렇게 변경 해 가면서 살펴보니 공부는 많이 되는데 진행이 더디긴 하네요.

이번 시간에 특히 중요했던 사항 중 하나는, 텍스쳐를 이미지가 아니라 데이터로써 사용하는 부분인데, 다음 시간에 이런 사례와 재질 특성에 대한 내용을 리뷰 해 보겠습니다.

https://learn-and-give.tistory.com/77

 

[Unity3D/Shader] 06. 텍스쳐를 이용한 멀티 텍스쳐링 영역 설정

앞에서 불규칙적인 무늬가 있는 텍스쳐의 어떤 픽셀값을 다른 텍스쳐의 좌표로 활용하는 방법으로 일렁이는 불꽃을 만드는 방법을 보았습니다. https://learn-and-give.tistory.com/76 [Unity3D/Shader] 05. 텍

learn-and-give.tistory.com

 

작성 된 프로젝트 코드는 매회의 제목으로 github에 커밋하고 있습니다.

https://github.com/red112/unity_shader

 

GitHub - red112/unity_shader: unity3d shader review

unity3d shader review. Contribute to red112/unity_shader development by creating an account on GitHub.

github.com

 

728x90
반응형

댓글