감성을 위한 개발요소
퍼니파우 CTO 최 재영
현 프로젝트의 핵심 Keyword!
“감성충만” , “애니메이션 같은”
“감성”? “애니메이션 같은”?
감성?
〮 이성 또는 오성(悟性)과 함께 인간의 인식능력.
〮 자극이나 자극의 변화를 느끼는 성질.
〮 <철학> 이성(理性)에 대응되는 개념으로, 외계의 대상을
오관(五官)으로 감각하고 지각하여 표상을 형성하는
인간의 인식 능력.
그런데, … 게임개발에서
“감성” 혹은 “애니메이션 같은“ 의 표현은
사전적 의미 보다, 개발에서의 “디테일”
이라고 생각했습니다.
(디테일 = 다양한 시도 = 생산성)
“감성 및 애니메이션 같은” 의 기능적(?) 해석
〮 그래픽 생산성 향상
〮 미적 어색한 부분에 대한 시스템적 지원
〮 애니메이션의 특징적 부분 구현
〮 다양하고 많은 시도를 통한 디테일 향상
대표적인 몇가지 사례 소개 (목차)
〮 LookAt System
〮 Facial Animation
〮 EyeBrow Rendering
〮 PostEffect (Using UberShader)
〮 BTS
LookAt System
기존 :
- 기존 Bone Animation 에 머리의 회전이 포함 됨
- 따라서 특정 오브젝트를 바라보기 위해 새로운 모션 재작
(Idle 왼쪽보기/Idle 오른쪽보기 가 다른 모션)
- 유연성 및 생산성 불만족
 생산성 및 재사용성 부족
목표 :
- 애니메이션 시스템과 분리
- 시스템을 통한 동작제어
- 어떠한 모션에서도 자연스러운 동작 보장
- 재사용성 및 생산성 향상
 재사용성 및 생산성 만족
LookAt System
- 구현 자체는 간단.
- Bip01 Neck 에 특정 방향벡터를 Link 함
해당 Vector 를 Target Pos로 향하게 회전
- Animation 연산 후, 시행
(Animation 과 자연스러운 결합)
90도90도
LookAt System
- Unity : Empty GameObject 의 Transform 활용
UE4 : Socket 을 활용
- Animation 연산 후, 시행하기에 매 frame 재 계산필요
(Animation 연산 후, Bone 의 위치가 다시 Animation 의 Key 값으로 돌아감)
(따라서, 점진적 보간이 아니라, 이전 frame 의 회전값을 저장하여 적용 후 계산 필요)
Pseudo-Code
void execute_lookat_after_animation(){
Vector3 vhead_dir; // 현재 머리가 향하는 방향
Vector3 vlookat_dest; // 바라볼 목적지
Vector3 vhead_pos; // 머리의 현재 위치
Quat qhead_rot; // 현재 Bip 상의 머리 회전값
Vector3 _vlookat_dir; // LookAt 연산을 위한 임시변수
Quat _qlookat; // LookAt 연산을 위한 임시변수
float _fdegree; // LookAt 연산을 위한 임시변수
_vlookat_dir = normalize(vlookat_dest – vhead_pos);
_fdegree = degree_a_to_b(vhead_dir , _vlookat_dir);
_fdegree = clamp( _fdegree, MIN_HEAD_DEGREE * deltatime, MAX_HEAD_DEGREE * deltatime);
_vlookat_dir = rotate_vector3_from_degree( vhead_dir, _fdegree);
_qlookat = quat_from_vector3( _vlookat_dir );
qhead_rot = _qlookat * qhead_rot;
}
Final
〮 특정 회전각의 제한
〮 Pelvis 에 Link 된 기준 방향을 중심으로 회전
〮 머리 > 목 > 가슴 순으로 회전 (임계값까지)
〮 어깨선을 중심으로 특정각도 까지 회전
. 고개를 숙인 컨셉의 캐릭터 . 측면으로 서있는 모션 . 목만 돌아간다 ??? . 기준의 필요성 ???
Head > Neck > Spine
Problems
Pelvis ....
Facial Animation
기존 :
- Bone Animation 을 이용한 Facial Animation
(Body 모션에 Facial이 포함되어 있는 구조)
- 다양하지 못한 표정과 유연하지 못한 구조
- 유연성 부족으로 인한 중복작업 증가
 생산성 및 재 사용성, 메모리, 퀄리티 모두 불만족
목표 :
- Blend Shape 방식을 사용해 생동감 있는 Facial 구현
- Body 모션과 Facial 분리
- 부위별 Shape Data(눈,코,입,눈썹) 를 각각 제작하여 Facial Animation 을 실시간 생산
- 캐릭터 별 Facial Shape Data 제작. Facial Animation 은 동일사용
 재사용성, 퀄리티, 메모리, 생산성 향상
캐릭터 별, 부위 별 Shape 제작. (약 15개)
각 Shape 별 Blend 를 통해 Facial Animation 생산
Shape 별 Blend 정보는 모든 캐릭터에 동일 적용
감정 강도 말하기 단순표정
喜 상 매우 기쁘면서 말하기 O
하 약간(?) 기쁘면서 말하기 O
怒 상 매우 화나면서 말하기 O
하 약간(?) 화나면서 말하기 O
愛 상 매우 슬프면서 말하기 O
하 약간(?) 슬프면서 말하기 O
樂 상 매우 즐거우면서 말하기 O
하 약간(?) 즐거우면서 말하기 O
6(희,노,애,락,기본표정,알파 ) X 2(감정단계) X 2(말하기 및 단순 표정)
총 24 개 Facial Animation 생산 (Default 갯수)
Blend
Shape
Vertex Color 를 통한 얼굴 음영 조정
코와 입 주변에 대한 조정 필요
(vertex normal vector 의 변화가 큰 부분)
Vertex Normal 의 수정없이 음영 계산
목표로 하는 Facial 의 음영계산
Vertex Normal 과 상이하게 음영계산됨
버텍스 컬러를 통해
Normal 정면 가중치 설정
Pseudo-Code ( Pixel Shader )
float3 vertex_normal; // 현재 픽셀의 normal
float4 vertex_color; // 현재 정점공간에서 전달 된, 픽셀의 color
vertex_normal = lerp( vertex_normal, float3(0 , 0, 1) , vertex_color.x );
// vertex_color.x 의 값이 1에 근접할 수록 정면을 향하는 normal 이 된다
Cartoon EyeBrow Rendering
눈썹 = 표정 = 감정표현!!
Depth Test Great Equal Render_bg();
Render_Characters();
render_1();
render_2();
....
Render_Characters();
render_1();
render_eyebrow();
render_2();
render_eyebrow();
render_3();
render_4();
....
Render_bg();
최적화를 위해, 특정 거리 이하 및 캐릭터의 시선과 카메라의 정면 Vector 의 각도에 따라 적용
Pseudo-Code
void Draw_Character()
{
Depth_Test = LessEqual; // default
Depth_Write = True; // default
Render_Character();
Depth_Test = GreatEqual;
Depth_Write = False;
Render_EyeBrow();
}
PostEffect
Bloom Filter Using DownScaled Buffers
게임의 전반적인 퀄리티 향상을 위한 Trade Off
Chromatic Aberration Filter
(빛이 물체점의 상이 상평면 상에 한 점에 모여야 하는데 그렇지 못하고 번지는 현상.)
실제 영화와 같은 연출을 위한 카메라효과
Pseudo-Code (Pixel Shader)
float2 texcoord = input.uv;
float k = _param.y;
float kcube = _param.z;
float r2 = (texcoord.x - 0.5) * (texcoord.x - 0.5) + (texcoord.y - 0.5) * (texcoord.y - 0.5);
float f = 0.0f;
if (kcube == 0.0f) {
f = 1.0f + r2 * k;
}
else {
f = 1.0f + r2 * (k + kcube * sqrt(r2));
}
float x = f*(texcoord.x - 0.5f) + 0.5f;
float y = f*(texcoord.y - 0.5f) + 0.5f;
float3 final_chromatic = tex2D(ScreenColor, float2(x, y)).rgb;
final_chromatic.z = tex2D(ScreenColor, input.uv).b;
Scratched Film Filter
과거회상 과 같은 연출을 위한 오래된 필름효과
Color Grading 과 함께 사용
Noise
Filter
Bloom
Filter
Chromatic
Aberration
Filter
Radial
Blur
Color
Inversion
Color
Grading
Vignette
Effect
Scratched
film Filter
Uber Shader
Noise
Filter
Chromatic
Aberration
Filter
Color
Grading
Vignette
Effect
scratched
film
Filter
Post Effect
Using UberShader
〮 수 개의 Shader 조합
〮 디자이너 선택에 따른 자동 생성
〮 Parameters 수정을 통한 커스텀
Uber Shader ?
코드 기반의 조합형 Shader.
간단한 인터페이스를 통해, 디자이너가 간단히 조합 할 수 있는 형태
float4 final_color = tex2D(Screen, input.xy);
#ifdef USE_BLOOM
final_color += bloom_function();
#endif
#ifdef USE_VIGNETTE
final_color *= vignette_function();
#endif
….
return final_color;
Pseudo-Code
Behavior Tree System
BTS 도입 배경
코드의 재사용성과 유연성 향상 (생산성)
빠른 대응과 피드백
커뮤니케이션 비용 감소
 개발 속도 향상을 통한 다양한 시도
BTS 도입 을 위한 준비
기획 및 개발 팀의 BTS 교육
올바른 설계 방향성의 지속적 점검
 AI 및 잦은 변경 이 요구되는 contents 들에 도입
BTS ?
4가지 노드의 계층적 연결을 통해 if / else 및 switch / case 를 시각적으로 구현하는 모델링 방식
(Composite / Condition / Action / Decorator)
- Composite : Selector, Sequencer
- Condition : 조건
- Action : 행위
- Decorator : Invertor ...
Root
Selector
IdleSequencer
attackDistance < 50
Root
Selector
IdleSequencer
attackDistance < 50
Root
Selector
IdleSequencer
Distance < 50 Selector
attackSequencer
Run AwayHP < 50%
Sample
기존 코드의 수정 없이 기능 개선 및 추가, 복구 가 가능
Tutorial System
Using B.T.S
〮 튜토리얼의 경우, 출시 전까지 잦은
변경이 요구됨
〮 기존 하드코딩(?) 된 튜토리얼을
BT 를 활용하여 시스템화 하였음.
〮 BT 를 통해 빠르고 유연한 대응 가능
Unity Unreal
최근 대부분의 Engine 들이 BTS 를 포함 하고 있음
( Unity 의 경우 Asset Store 의 Behavior Designer 존재 )
감사합니다.
Q&A
(mail : nmcjy@nm-funnypaw.com)

[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소

  • 1.
  • 2.
    현 프로젝트의 핵심Keyword! “감성충만” , “애니메이션 같은” “감성”? “애니메이션 같은”?
  • 3.
    감성? 〮 이성 또는오성(悟性)과 함께 인간의 인식능력. 〮 자극이나 자극의 변화를 느끼는 성질. 〮 <철학> 이성(理性)에 대응되는 개념으로, 외계의 대상을 오관(五官)으로 감각하고 지각하여 표상을 형성하는 인간의 인식 능력.
  • 4.
    그런데, … 게임개발에서 “감성”혹은 “애니메이션 같은“ 의 표현은 사전적 의미 보다, 개발에서의 “디테일” 이라고 생각했습니다. (디테일 = 다양한 시도 = 생산성)
  • 5.
    “감성 및 애니메이션같은” 의 기능적(?) 해석 〮 그래픽 생산성 향상 〮 미적 어색한 부분에 대한 시스템적 지원 〮 애니메이션의 특징적 부분 구현 〮 다양하고 많은 시도를 통한 디테일 향상
  • 6.
    대표적인 몇가지 사례소개 (목차) 〮 LookAt System 〮 Facial Animation 〮 EyeBrow Rendering 〮 PostEffect (Using UberShader) 〮 BTS
  • 7.
  • 8.
    기존 : - 기존Bone Animation 에 머리의 회전이 포함 됨 - 따라서 특정 오브젝트를 바라보기 위해 새로운 모션 재작 (Idle 왼쪽보기/Idle 오른쪽보기 가 다른 모션) - 유연성 및 생산성 불만족  생산성 및 재사용성 부족 목표 : - 애니메이션 시스템과 분리 - 시스템을 통한 동작제어 - 어떠한 모션에서도 자연스러운 동작 보장 - 재사용성 및 생산성 향상  재사용성 및 생산성 만족
  • 9.
    LookAt System - 구현자체는 간단. - Bip01 Neck 에 특정 방향벡터를 Link 함 해당 Vector 를 Target Pos로 향하게 회전 - Animation 연산 후, 시행 (Animation 과 자연스러운 결합) 90도90도
  • 10.
    LookAt System - Unity: Empty GameObject 의 Transform 활용 UE4 : Socket 을 활용 - Animation 연산 후, 시행하기에 매 frame 재 계산필요 (Animation 연산 후, Bone 의 위치가 다시 Animation 의 Key 값으로 돌아감) (따라서, 점진적 보간이 아니라, 이전 frame 의 회전값을 저장하여 적용 후 계산 필요)
  • 11.
    Pseudo-Code void execute_lookat_after_animation(){ Vector3 vhead_dir;// 현재 머리가 향하는 방향 Vector3 vlookat_dest; // 바라볼 목적지 Vector3 vhead_pos; // 머리의 현재 위치 Quat qhead_rot; // 현재 Bip 상의 머리 회전값 Vector3 _vlookat_dir; // LookAt 연산을 위한 임시변수 Quat _qlookat; // LookAt 연산을 위한 임시변수 float _fdegree; // LookAt 연산을 위한 임시변수 _vlookat_dir = normalize(vlookat_dest – vhead_pos); _fdegree = degree_a_to_b(vhead_dir , _vlookat_dir); _fdegree = clamp( _fdegree, MIN_HEAD_DEGREE * deltatime, MAX_HEAD_DEGREE * deltatime); _vlookat_dir = rotate_vector3_from_degree( vhead_dir, _fdegree); _qlookat = quat_from_vector3( _vlookat_dir ); qhead_rot = _qlookat * qhead_rot; }
  • 12.
    Final 〮 특정 회전각의제한 〮 Pelvis 에 Link 된 기준 방향을 중심으로 회전 〮 머리 > 목 > 가슴 순으로 회전 (임계값까지) 〮 어깨선을 중심으로 특정각도 까지 회전
  • 13.
    . 고개를 숙인컨셉의 캐릭터 . 측면으로 서있는 모션 . 목만 돌아간다 ??? . 기준의 필요성 ??? Head > Neck > Spine Problems Pelvis ....
  • 14.
  • 15.
    기존 : - BoneAnimation 을 이용한 Facial Animation (Body 모션에 Facial이 포함되어 있는 구조) - 다양하지 못한 표정과 유연하지 못한 구조 - 유연성 부족으로 인한 중복작업 증가  생산성 및 재 사용성, 메모리, 퀄리티 모두 불만족 목표 : - Blend Shape 방식을 사용해 생동감 있는 Facial 구현 - Body 모션과 Facial 분리 - 부위별 Shape Data(눈,코,입,눈썹) 를 각각 제작하여 Facial Animation 을 실시간 생산 - 캐릭터 별 Facial Shape Data 제작. Facial Animation 은 동일사용  재사용성, 퀄리티, 메모리, 생산성 향상
  • 16.
    캐릭터 별, 부위별 Shape 제작. (약 15개) 각 Shape 별 Blend 를 통해 Facial Animation 생산 Shape 별 Blend 정보는 모든 캐릭터에 동일 적용
  • 17.
    감정 강도 말하기단순표정 喜 상 매우 기쁘면서 말하기 O 하 약간(?) 기쁘면서 말하기 O 怒 상 매우 화나면서 말하기 O 하 약간(?) 화나면서 말하기 O 愛 상 매우 슬프면서 말하기 O 하 약간(?) 슬프면서 말하기 O 樂 상 매우 즐거우면서 말하기 O 하 약간(?) 즐거우면서 말하기 O 6(희,노,애,락,기본표정,알파 ) X 2(감정단계) X 2(말하기 및 단순 표정) 총 24 개 Facial Animation 생산 (Default 갯수) Blend Shape
  • 18.
    Vertex Color 를통한 얼굴 음영 조정 코와 입 주변에 대한 조정 필요 (vertex normal vector 의 변화가 큰 부분) Vertex Normal 의 수정없이 음영 계산 목표로 하는 Facial 의 음영계산 Vertex Normal 과 상이하게 음영계산됨 버텍스 컬러를 통해 Normal 정면 가중치 설정
  • 19.
    Pseudo-Code ( PixelShader ) float3 vertex_normal; // 현재 픽셀의 normal float4 vertex_color; // 현재 정점공간에서 전달 된, 픽셀의 color vertex_normal = lerp( vertex_normal, float3(0 , 0, 1) , vertex_color.x ); // vertex_color.x 의 값이 1에 근접할 수록 정면을 향하는 normal 이 된다
  • 20.
  • 21.
    눈썹 = 표정= 감정표현!!
  • 22.
    Depth Test GreatEqual Render_bg(); Render_Characters(); render_1(); render_2(); .... Render_Characters(); render_1(); render_eyebrow(); render_2(); render_eyebrow(); render_3(); render_4(); .... Render_bg(); 최적화를 위해, 특정 거리 이하 및 캐릭터의 시선과 카메라의 정면 Vector 의 각도에 따라 적용
  • 23.
    Pseudo-Code void Draw_Character() { Depth_Test =LessEqual; // default Depth_Write = True; // default Render_Character(); Depth_Test = GreatEqual; Depth_Write = False; Render_EyeBrow(); }
  • 24.
  • 25.
    Bloom Filter UsingDownScaled Buffers 게임의 전반적인 퀄리티 향상을 위한 Trade Off
  • 26.
    Chromatic Aberration Filter (빛이물체점의 상이 상평면 상에 한 점에 모여야 하는데 그렇지 못하고 번지는 현상.) 실제 영화와 같은 연출을 위한 카메라효과
  • 27.
    Pseudo-Code (Pixel Shader) float2texcoord = input.uv; float k = _param.y; float kcube = _param.z; float r2 = (texcoord.x - 0.5) * (texcoord.x - 0.5) + (texcoord.y - 0.5) * (texcoord.y - 0.5); float f = 0.0f; if (kcube == 0.0f) { f = 1.0f + r2 * k; } else { f = 1.0f + r2 * (k + kcube * sqrt(r2)); } float x = f*(texcoord.x - 0.5f) + 0.5f; float y = f*(texcoord.y - 0.5f) + 0.5f; float3 final_chromatic = tex2D(ScreenColor, float2(x, y)).rgb; final_chromatic.z = tex2D(ScreenColor, input.uv).b;
  • 28.
    Scratched Film Filter 과거회상과 같은 연출을 위한 오래된 필름효과 Color Grading 과 함께 사용
  • 29.
  • 30.
    Noise Filter Chromatic Aberration Filter Color Grading Vignette Effect scratched film Filter Post Effect Using UberShader 〮수 개의 Shader 조합 〮 디자이너 선택에 따른 자동 생성 〮 Parameters 수정을 통한 커스텀
  • 31.
    Uber Shader ? 코드기반의 조합형 Shader. 간단한 인터페이스를 통해, 디자이너가 간단히 조합 할 수 있는 형태 float4 final_color = tex2D(Screen, input.xy); #ifdef USE_BLOOM final_color += bloom_function(); #endif #ifdef USE_VIGNETTE final_color *= vignette_function(); #endif …. return final_color; Pseudo-Code
  • 32.
  • 33.
    BTS 도입 배경 코드의재사용성과 유연성 향상 (생산성) 빠른 대응과 피드백 커뮤니케이션 비용 감소  개발 속도 향상을 통한 다양한 시도 BTS 도입 을 위한 준비 기획 및 개발 팀의 BTS 교육 올바른 설계 방향성의 지속적 점검  AI 및 잦은 변경 이 요구되는 contents 들에 도입
  • 34.
    BTS ? 4가지 노드의계층적 연결을 통해 if / else 및 switch / case 를 시각적으로 구현하는 모델링 방식 (Composite / Condition / Action / Decorator) - Composite : Selector, Sequencer - Condition : 조건 - Action : 행위 - Decorator : Invertor ... Root Selector IdleSequencer attackDistance < 50
  • 35.
    Root Selector IdleSequencer attackDistance < 50 Root Selector IdleSequencer Distance< 50 Selector attackSequencer Run AwayHP < 50% Sample 기존 코드의 수정 없이 기능 개선 및 추가, 복구 가 가능
  • 36.
    Tutorial System Using B.T.S 〮튜토리얼의 경우, 출시 전까지 잦은 변경이 요구됨 〮 기존 하드코딩(?) 된 튜토리얼을 BT 를 활용하여 시스템화 하였음. 〮 BT 를 통해 빠르고 유연한 대응 가능
  • 37.
    Unity Unreal 최근 대부분의Engine 들이 BTS 를 포함 하고 있음 ( Unity 의 경우 Asset Store 의 Behavior Designer 존재 )
  • 38.