ㅣ목차

1. ZDA 프로젝트의 시작.

2. 게임팀 팀 빌딩 

3. 게임팀의 한계 

 

ㅣ ZDA 프로젝트의 시작.

 

초등학교 6학년때 나에게 오타쿠 문화를 알려줬던 친구가 있다. 그 친구 덕분에 오타쿠의 길을 걷게 되었다. 
그 친구는 애니를 만들고 싶어서 영상쪽의 길을 걷게 되었고 나는 게임을 만들고 싶어서 게임쪽의 길을 걷게 되었다. 우리는 서로 자신이 원하는 일을 열정적으로 하며 살았다. 
그러던 중 2020년 초 겨울방학이 끝나갈때 쯤 그 친구와 함께 고기를 먹으며 이야기를 나눴다.
이야기를 하다보니 자연스레 자신이 하고 있는 작업에 대해 이야기를 하던 도중 그 친구가 제안을 했다.

하나의 세계관을 가지고 게임하고 애니를 만들어 보자는 제안이였다. 흥미로운 제안이였다.

그 이유 크게 4가지가 있었다. 

1. 새로운 형태의 협력관계를 경험 할 수 있다. 
2. 리소스를 제공 받을 수 있다.
3. 자연스레 게임을 홍보 할 수 있는 영상매체가 생긴다.
4. 오타쿠 개발자의 로망!!!!!


이중 리소스를 제공 받을 수 있다는 점이 매우 컸다.

우리 학교엔 아쉽지만 3D 모델링 개발자가 적다.
따라서 3D를 제작하기 매우 힘든 환경이다. 
하지만 3D 모델링을 지원 받는다면 정말 큰 도움이 될것이였다.

하지만 애니에서 쓰던 모델링을 그대로 쓰는건 문제가 있어보였다. 그래서 그 친구와 함께 1주일 프로젝트로
애니에서 쓰던 모델링들을 그대로 게임에 적용이 가능한가? 를 테스트 해보았다.

 

[ 테스트 해본 영상 ]

 


결과는 나쁘지 않았다. 돌아가긴 돌아갔다.
다만 

 

해당 빌드에서는

1. 라이팅 최적화 문제로 스펙큘러가 매우 강한 모습을 보였다

2. 씬의 크기가 상당히 크다. 텍스처가 굉장히 무거워 추후 최적화가 필요해 보였다.

 

추후 이 문제를 해결해 나가야 할것이다. 



그리고 이렇게 만든 프로젝트 빌드 동영상을 보여주면서 팀원들을 모았다. 


졸업작품을 하던 도중 애니메이션 에셋이 필요해 유니티 에셋스토어를 뒤져봤다. 

하지만 마음에 드는 애니메이션이 없었다. 언리얼 스토어에 있는 애니메이션을 찾아보니 맘에 드는 애니메이션이 있었다. 그래서 언리얼 스토어에 있는 애니메이션을 익스포트 해봤는데 테스트 결과 잘 되어 포스팅 해본다.

 

 

간단하게 미리 보기

1. 콘텐츠 브라우저에서 애니메이션을 선택 

 

2. 애니메이션 창 => 에셋익스포트 => 애니메이션 데이터 => FBX 파일 익스포트 완료 

 

이 다음부턴 유니티를 자주 다루셨다면 대충 감이 오실겁니다. 

 

3. Project창에 파일을 드래그 드롭 & 에셋 =>임포트 => Import new Asset

 

 

추가적으로 오류가 날 수 있는 부분

 

- 애니메이션을 임포트 하고 휴머노이드라면 꼭 타입을 휴머노이드로 바꿔주세요. 

 

결과 

 

언리얼

 

유니티 

 

 

 

1. 콘텐츠 브라우저에서 애니메이션을 선택 

 

 

2. 애니메이션 창 => 에셋익스포트 => 애니메이션 데이터 => FBX 파일 익스포트

애니메이션을 선택하게 되면 이런 창이 뜨게 됩니다. 

 

 

에셋익스포트 => 애니메이션 데이터

 

 

FBX 파일 익스포트 완료! 

 

 

 

언리얼에서 FBX 파일을 얻었습니다! 이제부터는 늘 해왔듯이 FBX를 유니티에 임포트 시키면 됩니다. 

 

 

3. 유니티에 임포트 

유니티에서 Project창에 파일을 드래그 드롭 또는

에셋 =>임포트 => Import new Asset 해서 추가 시킵시다! 

 

유니티에 추가된 애니메이션

 

 

 

추가적으로 오류가 날 수 있는 부분

- 애니메이션을 임포트 하고 애니메이션 타입이 휴머노이드라면 꼭 타입을 휴머노이드로 바꿔주세요. 

 

애니메이션을 임포트하면 Rig에 애니메이션 타입이 항상 제네릭으로 되어 있습니다.

만약 휴머노이드 애니메이션 타입이였다면 이것을 휴머노이드로 바꿔줘야 합니다.

 

 

 

프로젝트를 진행하면서 일기? 일지? 형식으로 프로젝트가 어떻게 진행되는지 적어볼 생각이다.

 

너무 무겁지 않게 가볍게 포스트 할 생각이다.

 

현재 프로토타입을 제작중이고 이전에 있었던 일들

 

1. ZDA 프로젝트의 시작.

2. 게임팀 팀 빌딩 

3. 게임팀의 한계 

 

이것들은 따로 정리해보려한다. 

 

ZDA Project 는 하나의 세계관을 두고 게임컨텐츠과, 애니메이션과 졸작팀이 서로 협력해

게임과 애니메이션을 제작하는 프로젝트이다. 

 

애니메이션팀은 트레일러를 제작 게임팀은 게임을 제작한다. 

 

나는 게임컨텐츠과 학생이고 게임제작을 하기 때문에 게임제작을 중심으로 다룰 생각이다. 

 

 

 




 

알고리즘과 자료구조의 기초를 확실히 다지기 위해 포스팅을 시작합니다.

해당 포스팅은 

누구나 자료구조와 알고리즘을 참고 하며 만들어갑니다.

 

더 쉽고 심플하게 포스팅을 하는것이 목표입니다! 

 

포스트프로세싱 적용방법을 간단하게 정리해둔 곳이 없어보여서 한번 만들어봤습니다.

 

- 포스트프로세싱 플러그인을 설치해주세요. 

 

윈도우->Package Manager

(만약 Package Manager가 보이지 않는다면 에셋스토어에서 무료로 임포트 할 수 있습니다 ) 

 

 

로딩을 기다리다보면 전체 목록이 뜨게 됩니다.

Post Processing를 다운 받아주세요.

 

 

 

 

 

 

- 포스트 프로세싱 적용 방법

 

1. 후처리를 할 카메라에 Post-Process Layer 컴포넌트를 달아줍니다.

 

 

 

2. Layer 설정을 PostProcess로 바꿔줍니다. 

 

 

3. 그리고 후처리로 쓸 카메라의 레이어 또한 PostProcess로 맞춰줍니다.

 

4. PostProcess Volume을 추가합니다.

이것은 빈 오브젝트에 추가해도 되고 카메라에 추가해도 됩니다.

굳이 빈 오브젝트에 추가할 필요성을 못느껴 저는 카메라에 추가하겠습니다.

 

 

4.1 PostProcess Volume의 Rrofile은 어떤 후처리 효과를 낼 것인지

효과를 세팅해 놓은 파일을 넣을 곳입니다.

따라서 그 파일을 만들어줘야겠죠?

 

이제 그 파일을 만들어보겠습니다.

 

 

5. Project -> Create -> PostProcess Profile 생성을 해줍니다.

 

 

5.1 PostProcess Profile을 보면 이렇게 다양한 후처리 효과들이 있는것을 볼 수 있습니다.

 

6. profile에 아까 우리가 만든 PostProcess Profile을 넣어줍니다. 

 

7. 그리고 씬 전체에 적용하기 위해서 PostProcess Volime -> Is Global 체크해줍니다. 

 

 

 

이러면 적용이 완료됩니다.

 

다음 포스팅에서는 포스트프로세싱 기본 효과를 통해 구현할 수 있는 효과들을 소개해보려고 합니다

 

 

 

 

 

 

 

 

 

본 포스팅에서는

1. RimLight가 무엇인지

2. RimLight를 통해 어떤 효과를 기대 할 수 있는지

3. RimLight를 구현하기 위한 프레넬 공식

4. RimLight구현하는 방법

에 대해 알아보려 합니다. 

 


1. RimLight가 무엇인가? 

 

RimLight는 "모든 물체는 기울어질수록 반사가 심해진다" 라는 현상에서 부터 시작됩니다. 

 

이때 역광이 있을때 털이나 반투명 재질을 가진 물체들은 이 현상이 매우 강렬하게 나타납니다. 

 

사진 분야에서 이 현상을 RimLight 라고 합니다. 

 

림 라이트 예제 이미지1

 

림 라이트 예제 이미지 2

두 예제 이미지를 보면 머리카락이나 옷 부분을 보면 역광에 반사가 심해져 윤곽선 같은 느낌이 나는걸 볼 수 있습니다.

 

이것이 RimLight 입니다. 

 


 

2. RimLight를 통해 어떤 효과를 기대 할 수 있는지

기본적으로 게임에서는

1. 배경과 캐릭터의 분리나 강조 효과

2. 캐릭터가 선택 되었을 때나 특정 상태를 표현하기 위한 이펙트

3. 셀 세이딩 효과 같은 특수한 효과를 위해

과장되도록 사용합니다. 

 

 

RimLight 효과가 적용 되기 전 

 

RimLight가 적용된 이후

RimLight 예제 이미지 처럼 외곽선 부분이 강조된걸 볼 수 있습니다.

이 때문에 배경과 캐릭터가 구분 되는 효과를 볼 수 있습니다.

 

 


 

3. RimLight를 구현하기 위한 프레넬 공식

 

프레넬?

 

프레넬 방정식(Fresnel equations) 또는 프레넬 공식(Fresnel's formulas)은 반사계수와 투과계수에 관한것으로 한 매질과 광학적 특성 즉, 굴절률이 다른 매질의 계면에서 반사 또는 투과 진폭을 입사진폭으로 나눈 값을 말한다. 프랑스의 물리학자 오귀스탱 장 프레넬이 유도하였다.

( 위키백과 )

 

라고 하는데

 

프레넬은 아주 쉽게 말해서 각 재질에 따른 반사 정도를 나타냈다고 이해합시다...

실제로 프레넬은 프로그램에서 대체로 빛을 반사하는 값의 정도를 조절하는 값인 경우가 많다.

 

 

근데 RimLight를 구현하는데 왜 갑자기 프레넬이 튀어 나오냐구요?

 

 

왜냐면 RimLight는 결국 역광에서 나온 빛이 반사가 되어 생긴 현상이기 때문입니다. ( 글쓴이의 얕은 추론의 결론... )

따라서 반사와 투과에 대한 공식인 프레넬은 림라이트를 포함하는 개념입니다. ( 이것은 아래 레퍼런스 참고..!)

 

 

 

 


3. RimLight 구현

RimLight를 구현하는 과정을 간략하게 정리해보려합니다.

 

 

 

a. RimLight은 Lembert 공식(  N Dot L ) 에서 L을 V로 바꾼것

b. 그 결과값을 1 - 결과값 으로 뒤집어 버린다.

c. 그리고 POW를 통해 값을 급격하게 높혀버린다. 이를 통해 외곽선이 뚜렷하게 보이는 것

 

 


 

테스트 모델은 이 에셋을 이용합니다.

https://assetstore.unity.com/packages/essentials/asset-packs/the-blacksmith-characters-39941

 

 

The Blacksmith: Characters - Asset Store

This package includes the characters from “The Blacksmith” short film: - The Blacksmith character - The Challenger character - Hair Shader - Wrinkle maps - Unique character shadows - Plane reflections Please visit this blog post for more information: "The

assetstore.unity.com

 

이름 : 빡빡이 아조씨

캐릭터에 메테리얼이 많이 붙어있기 때문에 머리만 남겨두고 진행합니다. 

1. 프레넬 공식 기본 코드

 

유니티에서 Standard Shader로 생성을 한 후 

라이팅을 Lambert로 하고 환경광을 제거해줍시다.

그리고 쓸데 없는 부분들은 싹 정리 해줍시다. ( 코드 1 )

 

코드 1 : 라이팅을 Lambert로 만들어줬다.

 

아 참고로 더이상 스탠다드 라이팅이 아니기 때문에 Inout에서

SurfaceOutputStandard 쪽에 문제가 생길겁니다. 이것을 SurfaceOutput로 바꿔줘야 합니다.

 

 


그 다음

 

 알베도를 0으로 만들어서 검정색으로 만들어 봅시다. 

왜 검정색으로 만드냐면 라이팅 효과를 제대로 보면서 하고 싶기 때문입니다.

나중에 다시 rgb를 넣어줘서 피부를 되찾아줄겁니다. 

 

위 코드의 결과값입니다.

 

 

마치 코난의 범인 실루엣 같습니다.

이 대머리 아조씨는 어떤 사연을 가지고 살인을 저질렀을까요.

코난의 추리로 사건의 전말이 모두 까발려지고 울먹이면서 어떤 구구절절한 사연을 이야기할지 기대가 됩니다. 

 

 


 

 

RimLight는 Lambert 공식 ( N Dot L ) 에서  L을 V로 바꿔 카메라 벡터를 빛 처럼 받게 합니다. 

 

Lambert 라이트 기본 개념

여기서 L (라이트벡터) 대신 V (뷰 벡터)( 카메라 벡터 ) 로 바꾸면 어떻게 될까요?

원래 빛을 무시하고 카메라를 빛처럼 인식하게 됩니다. 

 

따라서 광원에 따라서 빛이 생기는 것이 아닌 카메라에 따라 빛이 생기는 것입니다.

 

그렇다면 카메라 벡터를 가지고 와야겠죠? 

 

Input에 viewdir (뷰벡터)를 추가합니다. ( 코드 2 ) 

 

코드 2 : viewDir 추가 

 

그리고 ( N dot V ) 값을 Emission에 넣어줍니다. ( 코드 3 )

 

 

 

 코드 3 

 

 

결과값을 봅시다. 

코드3의 결과값

코난에게 구구절절하게 사연을 말하고 자신의 죄를 씻어내기 위해 하얀 죄수복을 입게 되었군요. ( 개소리 ) 

 

( N dot V )라서 카메라가 마치 조명인것 처럼 인식을 하고 있습니다. 

 

 


 

 

( N dot V ) 의 결과값을 뒤집어 줍니다. ( 코드 4 )

 

 

 

코드4

 

 

코드4의 결과값 

결과값을 뒤집어 ( 반전 ) 시켜줘 제일 밝은 부분이 어두운 부분이 되어버렸습니다. 

 

이 상태에서 제일 흰 부분의 영역을 좁히면 RimLight 현상을 구현해볼수 있지 않을까요??? 

 


흰 부분의 영역을 좁히려면 어떻게 해야할까요? 

 

바로 제곱을 통해 영역을 좁힐 수 있습니다. 

 

제곱을 하게 되면

 

 

이런 일정한 값을 가지고 있는 그래프를 

 

 

이렇게 휘게 만들 수 있습니다. 

 

 

 

더 자세하게 보자면 

 

 0.5 부분에서는 값의 변화율이 굉장히 적습니다.

하지만 그 이후부터는 엄청난 변화율을 보여주게 됩니다. 

따라서 값이 극단적으로 변하게 된다고 보면 됩니다. 

 

자! 이 지식을 가지고 다음으로 넘어가 봅시다!

 

rim 값을 제곱해봅시다. ( 코드 5 ) 

pow함수를 통해 제곱이 가능합니다.

코드5: 제곱을 해줬다. 

 

값이 균등하게 바뀌는 것이 아니라 극단적으로 확 변하게 되었습니다. 

 

따라서 

 

코드4의 결과값 

 

제곱을 해준 코드 5의 결과값

 

검은색 부분의 영역은 많아 지고 흰색 부분의 영역이 좁아지는 것입니다.

 

 

 

 

 

완성 코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Shader "Custom/RimLight_Re1"
{
    Properties
    {
        _Color ("Color"Color= (1,1,1,1)
        _MainTex ("Albedo (RGB)"2D= "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
 
        CGPROGRAM
        #pragma surface surf Lambert noambient
        #pragma target 3.0
 
        sampler2D _MainTex;
 
        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };
 
   
        fixed4 _Color;
 
    
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;// //  
            o.Albedo = 0;
 
            float rim  = dot(o.Normal , IN.viewDir);
            rim = pow ( 1-rim , 3);
            o.Emission = rim;
            
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs

 

 

 

 

 


 

- RimLight를 더 완성해보자 ! 

 

프레넬 기본형에 컬러랑 파워 추가해봅시다. ( 코드 6 )

 

코드 6
코드 6의 메테리얼 설정값

이렇게 해서 인스펙터창에서 값을 설정 할 수 있게 되었습니다. 

컬러도 조절 할 수 있어서 

코드 6 결과값

이렇게 깜직한 핫핑크 빡빡이 아조씨가 되었습니다.

 

핫핑크 아조씨의 피부를 다시 입혀줍시다.

 

피부 텍스처와 노말맵 텍스처를 받아와야 합니다. ( 코드 7 )

 

코드 7 : 

알베도에 값을 0에서 c.rgb로 바꿔주고

노말맵을 받아왔습니다.

 

코드 7 결과값

 

 


 

내적의 값이 -1 ~ 1 까지 되어 나중에 빛 연산을 해도 비정상적으로 어두운 상황을 막기 위해 

saturate 함수로 0~1까지 값을 짤라줍니다. ( 코드 8 )

 

 

코드 8 

 

 

 

- 최종 코드 -

 

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Shader "Custom/RimLight_Re1"
{
    Properties
    {
        _Color ("Color"Color= (1,1,1,1)
        _MainTex ("Albedo (RGB)"2D= "white" {}
        _RimPower("RimPower" , Range(0,10)) = 0 
        _NormalMap ("NormalMap",2D ) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
 
        CGPROGRAM
        #pragma surface surf Lambert noambient
        #pragma target 3.0
 
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_NormalMap;
 
            float3 viewDir;
        };
   
        fixed4 _Color;
        float _RimPower;
        sampler2D _MainTex;
        sampler2D _NormalMap;
 
    
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
 
            o.Normal = UnpackNormal(tex2D (_NormalMap, IN.uv_NormalMap));// //
 
            float rim  = saturate(dot(o.Normal , IN.viewDir));
            rim = pow ( 1-rim , _RimPower);
            o.Emission = rim * _Color.rgb;
 
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs

 

 

 


다음 포스팅은 RImLight를 활용한 홀로그렘을 제작해보려합니다.

 

 

 

레퍼런스 :

1. 유니티쉐이더 스타트업

2. https://meshmason.tistory.com/9

 

 

[Blender] 프레넬(Fresnel)이란 무엇인가

3D 툴을 다루다 보면 언젠가 한 번쯤은 들어보았거나, 반드시 이해해야만 하는 문제에 봉착할 수 있는 개념이 Fresnel이다. 아무래도 3D 물체에 재질을 입힐 때 여러가지 값을 설정해야만 되는데, 재질이란 것이..

meshmason.tistory.com

3. https://lifeisforu.tistory.com/384

 

[ PBR 이란 무엇인가 ] 17. Fresnel 이란?

주의 : 잘못된 내용이 포함되어 있을 수 있으므로 이상하면 참고자료를 확인하세요. [ PBR 이란 무엇인가 ] Fresnel 이란? 프레넬 공식이란? 앞서 [ [ 번역 ] 모든 것은 프레넬을 가집니다 ] 와 [ Reflection 에..

lifeisforu.tistory.com

 

 

 

 

+ Recent posts