3.7K Views
September 25, 19
スライド概要
2019/9/25-6に開催されたUnite Tokyo 2019の講演スライドです。
Jaeseong Ryu(FUNNYPAW)
Jaeyoung Choi(FUNNYPAW)
こんな人におすすめ
・グラフィックデザイナー
・プログラマー
・テクニカルアーティスト
受講者が得られる知見
・ アニメ風キャラクターのレンダリング方法
・ 様々なモバイル3Dグラフィックスの表現事例
・ 最適化による効果的な開発方法
Unityのイベント資料はこちらから:
https://www.slideshare.net/UnityTechnologiesJapan/clipboards
リアルタイム3Dコンテンツを制作・運用するための世界的にリードするプラットフォームである「Unity」の日本国内における販売、サポート、コミュニティ活動、研究開発、教育支援を行っています。ゲーム開発者からアーティスト、建築家、自動車デザイナー、映画製作者など、さまざまなクリエイターがUnityを使い想像力を発揮しています。
〈七つの大罪〉をゲームで! 高品質グラフィックを具現するための 技法と開発最適化のご紹介 FUNNYPAW FUNNYPAW チェ・ジェヨン リュ・ジェソン CTO TA
シネマチック・アドベンチャーRPG アニメーションスタイル 華麗な演出効果 600枚以上のローディング画面
二つの挑戦 競争力 + 生産性
競争力! ゲーム内でアニメーション感性 を具現 アニメ感性 = キャラクターの表情や動き、カメラ構図など多数のディテールを表現
生産性! 非効率的要素削除 = 生産性 より多くの試し・検証 = 面白さ
挑戦の始まり — Design R&D (Character Rendering) — Normal Shift (Face) — EyeBrow Rendering — Character FX — Changing BG Colour (Color Grading , LUT) — 2D Polygonal Imposters for 3D Crowds
Design R&D Characters Rendering 良質のグラフィッククオリティとは何か ユーザーに伝えたい感性は何か
Character Rendering (before) Head Diffuse Head Normal Body Diffuse Body Normal ディテール強調することが良質のモデリングに繋がる?
Character Rendering (reference) — 原作そのままのキャラクターモデリング — 漫画/アニメのような"線(Line)"を強調 — 意図的な比率を使用
Character Rendering (after) Normal Map Cartoon Map 非効率的な空間使用 効率的な空間使用
Lighting (before) — 既存のCell Shadingを使用 — 照明の方向によって変わる陰影 — シーン別の照明方向は修正不可 キャラクターの方向により不自然な影ができる
Lighting (reference) — アニメーション参考 — 演出により非現実的な陰影設定 — 物理的な事実より感情重視の伝達方法 キャラクターの方向に関係なく一定の明暗を表現
Previous Shader Matcap Shader 3DS MAX DirectX Shader
Lighting (after) — Matcap Shaderを使用し、照明方向に関係なく同一の明暗 — Global LightingのColor Toneは適用 既存Shader Matcap Shader
Face shading (before) Character face Animation — Normalの変化が大きい部分は不自然な陰影発生 — 鼻と口の周りに陰影無し — 陰影を自由にコントロールする必要有り — 鼻は簡単な線で表現
Face shading (edit) — Vertex Color Alphaを使用 — 値が0に近いほど正面に向かうNormalになる — Normalの修正をせず迅速な作業が可能 — アウトラインの厚さにも値を適用 1 2 3 4 5 6 float3 worldNorm = normalize(unity_WorldToObject[0].xyz * v.normal.x + unity_WorldToObject[1].xyz * v.normal.y + unity_WorldToObject[2].xyz * v.normal.z); worldNorm = mul((float3x3)UNITY_MATRIX_V, worldNorm); uv = (worldNorm.xy * 0.5) * v.color.a + 0.5;
Face shading (after) Vertex Color Vertex Color適用無し Vertex Color適用
Eyebrow (before) Eyebrow Back Eyebrow Front 眉毛の表現でキャラクターの特性を表す比率が高い
Eyebrow (edit) — Depth Test Greater Equal使用 — 髪の上に重なる眉毛は透明度を持つ ZTest LEqual ZTest GEqual Alpha Eyebrow
Eyebrow (after) — 描く手順 Render Queue 900 Render Queue 800 Render Queue 800 Ztest LEqual Ztest LEqual Ztest LEqual Hair Face Eyebrow (inside) Render Queue 900 Ztest GEqual Eyebrow (outside)
Character directing effect 24
状態異常効果 — Matcap Textureを変更し、簡単な質感表現 — Additive & Multiplyモードサポート — アウトライン色相変更 凍結 ヘビメタ 石化
キャラクターの光源効果 — Matcap Textureを使用し、光源効果追加 — Additive & Multiplyモードサポート
FX SHADER ADDITIVE BLEND DISTORT MASK BLEND UBERSHAER MESH (DIFFUSE) DISCARD SCREEN PROJECTION MESH 2SIDE HUE SHIFT MATCAP
FX SCRIPT CAMERA BILLBOARD MATCAP MAPPER MOVEMENT TARGET SUB EMITTER SPAWNER RANDOM CREATE MESH TEXTURE SHEET FADEOUT GENERATOR HIT CREATE SCROLLING UV SHAKE MOVEMENT RENDER THAN NGUI
Background effect 29
Cloud shadow — 背景マップ全域に効果適用 — 色相・大きさ・速度調整
Lookup texture — 背景にLUTを適用後、プロップを追加してデータの再活用性を上昇 Default Map LUT + Add props LUT + Add props
Default LUT Default LUT
Fake Interior — 室内をモデリングせず偽で作れる技術 — 多数の室内を簡単に製作
Fake Interior Shader — 室外Window Texture支援 — 室内Room Texture支援 (cube map使用) — 室内深さを調節できる機能を追加 Cube Map (6 direction) Right Left Up Down Back Front
Final result
Imposter — 多数のモデルが必要な際は2Dビルボードに交代 — MeshのPolygon数を節約 — Draw Callの数を節約
Imposter — Camera個数 ・ 角度調節 — Camera位置 ・ 距離調節 — Texture自動出力
Atlas Texture for Imposter
Imposter Shader — Animation 2 Texture支援 — Animation Speed, Tempo, Start Time
Model & Imposter
Imposter Animation
さらなる挑戦の始まり — PostEffect (Using UberShader) — LookAt System — Facial Animation — Story Telling Tools — BTS — Machine/Deep Learning — Bug Detection System
Facial Animation
Facial Animation — Bone Animationと結合した状況 — 状況別の新規モーション制作 (Idle口の動き、Idle目瞬き) — 再使用性・生産性・多様性の不足 — アニメーションのシステムと分離 — システムによる動作制御 — 自然な動作を保障 — すべてのキャラクターのFacial Animを同一使用 — 再活用性・生産性・多様性を確保
Facial Animation — Morphの使用から見たアニメとの分離 — 部位別にBlend Shapeを分けて再使用性を確保 — 基本13つ+αの表情製作 — すべてのキャラクターの表情には同一のBlend値を使用 — 表情同士のBlendを通じて新しい表情制作
Facial Tool — 自動会話型アニメの再生 — 多数のキャラクターを迅速に確認 — 容易に多彩なアニメを再生
Story Telling
Strory Telling
会話カットシーン — アニメーションのような演出 — デザイナーの多様な要望への対応 — 'カット'単位の編集 — 繊細なカメラ演出で感性を伝達 — 演出のための様々な技能支援 — 単一のツールを使用することで生産性増加
LookAt System
LookAt System — Bone Animationと結合した状況 — 状況別新規モーション製作(Idle左向き・Idle右向き) — 生産性および再使用性の不足 — アニメーションシステムと分離 — システムによる動作制御 — 自然な動作を保障 — 再使用性・生産性・多様性を確保
LookAt System — 簡単な具現 — 指定方向に向かせるVectorリンク(Bip01 Neck) — 指定方向に向かせるVectorがターゲットに向かうまでNeckを回転 — Animation演算後、施行(Animationと自然な結合) 90° 90°
Pseudo-Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void execute_lookat_after_animation(){ Vector3 vhead_dir; Vector3 vlookat_dest; Vector3 vhead_pos; Quat qhead_rot; Vector3 _vlookat_dir; Quat _qlookat; float _fdegree; _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; }
LookAt System — 特定の回転角の制限 — PelvisにLinkされた基準方向を中心に回転 — 頭 > 首 > 胸の順で回転(臨界値まで) — 肩のラインを中心に特定角度まで回転
Problems on LookAt System キャラクターが見下ろしたり、 見上げるコンセプトのキャラクター 既存のシステムでは正面だけを見る キャラクターのモーションが斜めに 立っている場合 既存のシステムでは正面のみを基 準として動作する 首だけ不自然に回る場合 胸、首、頭すべてを自然に回転さ せる必要有り
Problems on LookAt System — 黄色ラインに沿って回転 — 赤ラインに沿っての回転要求 — 青の肩ラインを中心とした回転制限
Problems on LookAt System — 特定の回転角制限 — Pelvisと肩のラインを中心に最大回転角制限 — 頭>首>胸の順で回転
PostEffect
Post Effect — Bloom (Using DownScaled Buffer)
Post Effect — Chromatic Aberration Filter (色収差現象:レンズを通過した色が明瞭せず、重なったり滲んで見える現象。色によって光の波長が違うために発生する)
Pseudo-Code (Pixel Shader) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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;
PostEffect — Scratched Film Filter 回想演出のための古いフィルム効果、Color Gradingと一緒に使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // scratch float scratch_intensity = _scratch_intensity_smooth_vspd_hspd.x; float scratch_smooth = _scratch_intensity_smooth_vspd_hspd.y; float vert_scrach_spd = _scratch_intensity_smooth_vspd_hspd.z; float hori_scrach_spd = _scratch_intensity_smooth_vspd_hspd.w; float _scratch_lerp = 1.0f; // outer value float _vert_line = _Time.x * vert_scrach_spd; float _hori_line = _Time.x * hori_scrach_spd; float2 _noise_texcoord = float2(i.uv.x + _hori_line, _vert_line); float _scratch = tex2D(noise_texture, _noise_texcoord).x; _scratch = 2.0 * (_scratch - scratch_intensity) / clamp(scratch_smooth, 0.01f, 0.1f); _scratch = clamp(1.0 - abs(1.0f - _scratch), 0.0f, 1.0f); _scratch = lerp(_scratch * _scratch_lerp, 0.0f, 1.0f - lookup_texture_desc.w); _scratch *= 0.6; _scratch = 1.0 - _scratch;
PostEffect Using UberShader — Chromatic Aberration Filter — Noise Filter — Vignette Effect — Scratched Film Filter — Color Grading
Behavior Tree System
Behavior Tree System — コードの再使用性の弱化(生産性減少) — 迅速な対応とフィードバックが必要 — コミュニケーションコストの増加 — コードの再使用性強化 — 迅速な対応とフィードバック — コミュニケーションコストの削減 — 生産性増加
Behavior Tree System 4つのノードを階層的連結をすることで if/else 及び switch/caseを視覚的に具現するモデリング方式 — Composite : Selector, Sequencer — Condition : 条件 — Action : 行為 — Decorator : Invertor ... Root Selector Sequencer Distance < 50 Idle attack
Behavior Tree System 既存コードを修正することなく機能改善、追加、復旧が可能 Root Root Selector Selector Root Sequencer Sequencer Selector Sequencer Distance < 50 Idle Distance <<50 Distance 50 Selector Selector Sequencer attack HP < 50% Idle Run Away attack
Behavior Tree System — チュートリアルの場合、発売直前まで 頻繁な変更要求発生 — 従来のハードコーディングされた チュートリアルをBTを活用しシステム化 — BTを通じて迅速で柔軟な対応可能
Behavior Tree System BlackBoard — ノード間の独立性が核心 — コード再使用のための構造設計 — BBについて考慮が不必要な開発環境 — 持続的な管理と教育が必要 例)キャラクターマネジャーを通じたHP獲得 モンスターマネジャーによるキャラクター間の距離比較
Using BlackBoard 1 2 3 4 5 6 7 Obj = ObjectMgr.get_object( object_id ); Vector3 Diff = Obj.get_pos() – MainChr.get_pos(); Float fDist = Diff.length(); 1 2 3 4 5 6 7 8 9 If( fDist > 10.0f) return true; Return false; Vector3 obj_pos = BlackBoard.get_pos( object_id); Vector3 main_chr_pos = BlackBoard.get_pos( main_chr_id); Vector3 Diff = obj_pos– main_chr_pos; Float fDist = Diff.length(); If( fDist > 10.0f) return true; Return false; コード再使用性減少 コード再使用性上昇 ObjectMgr / MainChrのclass従属 class従属無し(Vector3程度…) 70
Thank you ご静聴ありがとうございました! Q&A 71